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 | |
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 '')
266 files changed, 24965 insertions, 0 deletions
diff --git a/src/boost/libs/contract/test/Jamfile.v2 b/src/boost/libs/contract/test/Jamfile.v2 new file mode 100644 index 00000000..2026b8de --- /dev/null +++ b/src/boost/libs/contract/test/Jamfile.v2 @@ -0,0 +1,449 @@ + +# 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 + +import ../build/boost_contract_build ; +import ../../config/checks/config : requires ; + +test-suite constructor : + [ boost_contract_build.subdir-run-cxx11 constructor : smoke ] + + [ boost_contract_build.subdir-run-cxx11 constructor : decl_pre_all ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_pre_ends ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_pre_mid ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_pre_none ] + + [ boost_contract_build.subdir-run-cxx11 constructor : decl_post_all ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_post_ends ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_post_mid ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_post_none ] + + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_entry_static_inv_all ] + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_entry_static_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_entry_static_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_entry_static_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_exit_static_inv_all ] + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_exit_static_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_exit_static_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 constructor : + decl_exit_static_inv_none ] + + # No decl_entry_static_inv_... (as no obj before ctor). + + [ boost_contract_build.subdir-run-cxx11 constructor : decl_exit_inv_all ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_exit_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_exit_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 constructor : decl_exit_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 constructor : access ] + + [ boost_contract_build.subdir-run-cxx11 constructor : ifdef ] + [ boost_contract_build.subdir-run-cxx11 constructor : ifdef_macro ] + + [ boost_contract_build.subdir-run-cxx11 constructor : throwing_pre ] + [ boost_contract_build.subdir-run-cxx11 constructor : throwing_old ] + [ boost_contract_build.subdir-run-cxx11 constructor : throwing_body ] + [ boost_contract_build.subdir-run-cxx11 constructor : throwing_post ] + # No throwing_except test (as throwing twice calls terminate). + + [ boost_contract_build.subdir-compile-fail-cxx11 constructor : pre_error ] +; + +test-suite destructor : + [ boost_contract_build.subdir-run-cxx11 destructor : smoke ] + + # No decl_pre_... (as dtors have no pre). + + [ boost_contract_build.subdir-run-cxx11 destructor : decl_post_all ] + [ boost_contract_build.subdir-run-cxx11 destructor : decl_post_ends ] + [ boost_contract_build.subdir-run-cxx11 destructor : decl_post_mid ] + [ boost_contract_build.subdir-run-cxx11 destructor : decl_post_none ] + + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_entry_static_inv_all ] + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_entry_static_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_entry_static_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_entry_static_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_exit_static_inv_all ] + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_exit_static_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_exit_static_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 destructor : + decl_exit_static_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 destructor : decl_entry_inv_all ] + [ boost_contract_build.subdir-run-cxx11 destructor : decl_entry_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 destructor : decl_entry_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 destructor : decl_entry_inv_none ] + + # No decl_exit_inv_... (as no obj after dtor). + + [ boost_contract_build.subdir-run-cxx11 destructor : access ] + + [ boost_contract_build.subdir-run-cxx11 destructor : ifdef ] + [ boost_contract_build.subdir-run-cxx11 destructor : ifdef_macro ] + + # No throwing_pre test (as dtors have no pre). + [ boost_contract_build.subdir-run-cxx11 destructor : throwing_old ] + [ boost_contract_build.subdir-run-cxx11 destructor : throwing_body ] + [ boost_contract_build.subdir-run-cxx11 destructor : throwing_post ] + # No throwing_except test (as throwing twice calls terminate). + + [ boost_contract_build.subdir-compile-fail-cxx11 destructor : pre_error ] +; + +test-suite public_function : + [ boost_contract_build.subdir-run-cxx11 public_function : smoke ] + + [ boost_contract_build.subdir-run-cxx11 public_function : decl_pre_all ] + [ boost_contract_build.subdir-run-cxx11 public_function : decl_pre_ends ] + [ boost_contract_build.subdir-run-cxx11 public_function : decl_pre_mid ] + [ boost_contract_build.subdir-run-cxx11 public_function : decl_pre_none ] + + [ boost_contract_build.subdir-run-cxx11 public_function : decl_post_all ] + [ boost_contract_build.subdir-run-cxx11 public_function : decl_post_ends ] + [ boost_contract_build.subdir-run-cxx11 public_function : decl_post_mid ] + [ boost_contract_build.subdir-run-cxx11 public_function : decl_post_none ] + + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_static_inv_all ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_static_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_static_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_static_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_static_inv_all ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_static_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_static_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_static_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_inv_all ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_entry_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_inv_all ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_inv_ends ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_inv_mid ] + [ boost_contract_build.subdir-run-cxx11 public_function : + decl_exit_inv_none ] + + [ boost_contract_build.subdir-run-cxx11 public_function : access ] + + [ boost_contract_build.subdir-run-cxx11 public_function : ifdef ] + [ boost_contract_build.subdir-run-cxx11 public_function : ifdef_macro ] + + [ boost_contract_build.subdir-run-cxx11 public_function : virtual ] + [ boost_contract_build.subdir-run-cxx11 public_function : virtual_branch ] + [ boost_contract_build.subdir-run-cxx11 public_function : virtual_sparse ] + [ boost_contract_build.subdir-run-cxx11 public_function : virtual_access ] + [ boost_contract_build.subdir-run-cxx11 public_function : + virtual_access_multi ] + [ boost_contract_build.subdir-run-cxx11 public_function : old_virtual ] + + [ boost_contract_build.subdir-run-cxx11 public_function : protected ] + [ boost_contract_build.subdir-compile-fail public_function : + protected_error ] + [ boost_contract_build.subdir-run-cxx11 public_function : friend ] + + [ boost_contract_build.subdir-run-cxx11 public_function : throwing_pre ] + [ boost_contract_build.subdir-run-cxx11 public_function : throwing_old ] + [ boost_contract_build.subdir-run-cxx11 public_function : throwing_body ] + [ boost_contract_build.subdir-run-cxx11 public_function : + throwing_body_virtual ] + [ boost_contract_build.subdir-run-cxx11 public_function : + throwing_body_virtual_branch ] + [ boost_contract_build.subdir-run-cxx11 public_function : throwing_post ] + # No throwing_except test (as throwing twice calls terminate). + + [ boost_contract_build.subdir-run-cxx11 public_function : max_args0 : + <define>BOOST_CONTRACT_MAX_ARGS=0 ] + [ boost_contract_build.subdir-run-cxx11 public_function : max_args0_no_tva : + <define>BOOST_CONTRACT_MAX_ARGS=0 + <define>BOOST_NO_CXX11_VARIADIC_TEMPLATES + ] + [ boost_contract_build.subdir-run-cxx11 public_function : max_args1 : + <define>BOOST_CONTRACT_MAX_ARGS=1 ] + [ boost_contract_build.subdir-run-cxx11 public_function : max_args1_no_tva : + <define>BOOST_CONTRACT_MAX_ARGS=1 + <define>BOOST_NO_CXX11_VARIADIC_TEMPLATES + ] + [ boost_contract_build.subdir-run-cxx11 public_function : max_args2 : + <define>BOOST_CONTRACT_MAX_ARGS=2 ] + [ boost_contract_build.subdir-run-cxx11 public_function : max_args2_no_tva : + <define>BOOST_CONTRACT_MAX_ARGS=2 + <define>BOOST_NO_CXX11_VARIADIC_TEMPLATES + ] + [ boost_contract_build.subdir-run-cxx11 public_function : max_args ] + [ boost_contract_build.subdir-run-cxx11 public_function : max_args_no_tva : + <define>BOOST_NO_CXX11_VARIADIC_TEMPLATES ] + + [ boost_contract_build.subdir-run-cxx11 public_function : + max_bases ] # C++11 for BASES(...) variadic macros. + + [ boost_contract_build.subdir-run-cxx11 public_function : overload ] + [ boost_contract_build.subdir-run-cxx11 public_function : overload_no_tva : + <define>BOOST_NO_CXX11_VARIADIC_TEMPLATES ] + + [ boost_contract_build.subdir-compile-fail-cxx11 public_function : + override_error ] # C++11 for BASES(...) variadic macros. + [ boost_contract_build.subdir-run-cxx11 public_function : # C++11 for BASES. + override_permissive : <define>BOOST_CONTRACT_PERMISSIVE ] + + [ boost_contract_build.subdir-run-cxx11 public_function : static ] + [ boost_contract_build.subdir-run-cxx11 public_function : static_ifdef ] + [ boost_contract_build.subdir-run-cxx11 public_function : + static_ifdef_macro ] + [ boost_contract_build.subdir-run-cxx11 public_function : + static_throwing_pre ] + [ boost_contract_build.subdir-run-cxx11 public_function : + static_throwing_old ] + [ boost_contract_build.subdir-run-cxx11 public_function : + static_throwing_body ] + [ boost_contract_build.subdir-run-cxx11 public_function : + static_throwing_post ] + # No throwing_except test (as throwing twice calls terminate). +; + +test-suite invariant : + [ boost_contract_build.subdir-run-cxx11 invariant : decl_static_cv_const ] + [ boost_contract_build.subdir-run-cxx11 invariant : decl_static_cv ] + [ boost_contract_build.subdir-run-cxx11 invariant : decl_cv_const ] + [ boost_contract_build.subdir-run-cxx11 invariant : decl_static_const ] + [ boost_contract_build.subdir-run-cxx11 invariant : decl_static ] + [ boost_contract_build.subdir-run-cxx11 invariant : decl_cv ] + [ boost_contract_build.subdir-run-cxx11 invariant : decl_const ] + [ boost_contract_build.subdir-run-cxx11 invariant : decl_nothing ] + + [ boost_contract_build.subdir-run invariant : ifdef ] + [ boost_contract_build.subdir-run-cxx11 invariant : ifdef_macro ] + + [ boost_contract_build.subdir-compile-fail invariant : + static_mutable_error ] + [ boost_contract_build.subdir-run invariant : static_mutable_permissive : + <define>BOOST_CONTRACT_PERMISSIVE ] + [ boost_contract_build.subdir-compile-fail invariant : static_const_error ] + [ boost_contract_build.subdir-run invariant : static_const_permissive : + <define>BOOST_CONTRACT_PERMISSIVE ] + [ boost_contract_build.subdir-compile-fail invariant : + static_volatile_error ] + [ boost_contract_build.subdir-run invariant : static_volatile_permissive : + <define>BOOST_CONTRACT_PERMISSIVE ] + [ boost_contract_build.subdir-compile-fail invariant : static_cv_error ] + [ boost_contract_build.subdir-run invariant : static_cv_permissive : + <define>BOOST_CONTRACT_PERMISSIVE ] + + [ boost_contract_build.subdir-compile-fail invariant : static_error ] + [ boost_contract_build.subdir-run invariant : static_permissive : + <define>BOOST_CONTRACT_PERMISSIVE ] + [ boost_contract_build.subdir-compile-fail invariant : mutable_error ] + [ boost_contract_build.subdir-run invariant : mutable_permissive : + <define>BOOST_CONTRACT_PERMISSIVE ] + [ boost_contract_build.subdir-compile-fail invariant : volatile_error ] + [ boost_contract_build.subdir-run invariant : volatile_permissive : + <define>BOOST_CONTRACT_PERMISSIVE ] +; + +test-suite function : + [ boost_contract_build.subdir-run-cxx11 function : smoke ] + + [ boost_contract_build.subdir-run-cxx11 function : decl_pre_all ] + [ boost_contract_build.subdir-run-cxx11 function : decl_pre_none ] + + [ boost_contract_build.subdir-run-cxx11 function : decl_post_all ] + [ boost_contract_build.subdir-run-cxx11 function : decl_post_none ] + + [ boost_contract_build.subdir-run-cxx11 function : ifdef ] + [ boost_contract_build.subdir-run-cxx11 function : ifdef_macro ] + + [ boost_contract_build.subdir-run-cxx11 function : throwing_pre ] + [ boost_contract_build.subdir-run-cxx11 function : throwing_old ] + [ boost_contract_build.subdir-run-cxx11 function : throwing_body ] + [ boost_contract_build.subdir-run-cxx11 function : throwing_post ] + # No throwing_except test (as throwing twice calls terminate). +; + +test-suite check : + [ boost_contract_build.subdir-run-cxx11 check : decl_class ] + [ boost_contract_build.subdir-run-cxx11 check : decl_macro ] + + [ boost_contract_build.subdir-run-cxx11 check : ifdef ] + [ boost_contract_build.subdir-run-cxx11 check : ifdef_macro ] + + [ boost_contract_build.subdir-run-cxx11 check : audit : + <define>BOOST_CONTRACT_AUDITS ] + [ boost_contract_build.subdir-compile-fail-cxx11 check : audit_error ] + [ boost_contract_build.subdir-run-cxx11 check : audit_disabled ] + [ boost_contract_build.subdir-compile-fail-cxx11 check : + audit_disabled_error ] + [ boost_contract_build.subdir-run check : axiom ] + [ boost_contract_build.subdir-compile-fail check : axiom_error ] +; + +test-suite result : + [ boost_contract_build.subdir-run-cxx11 result : mixed_optional ] + [ boost_contract_build.subdir-run-cxx11 result : mixed_optional_ref ] + + [ boost_contract_build.subdir-compile-fail-cxx11 result : + type_mismatch_error ] # C++11 for BASES(...) variadic macros. +; + +test-suite old : + [ boost_contract_build.subdir-run old : auto : + [ requires cxx11_auto_declarations ] ] + + [ boost_contract_build.subdir-run-cxx11 old : no_macro ] + [ boost_contract_build.subdir-run-cxx11 old : no_macro_if_copyable ] + + [ boost_contract_build.subdir-compile-fail old : no_make_old_error ] + [ boost_contract_build.subdir-compile-fail old : + no_make_old_if_copyable_error ] + + [ boost_contract_build.subdir-run-cxx11 old : if_copyable ] + [ boost_contract_build.subdir-compile-fail-cxx11 old : if_copyable_error ] + [ boost_contract_build.subdir-run-cxx11 old : if_copyable_macro ] + + [ boost_contract_build.subdir-run old : copyable_traits ] +; + +test-suite disable : + [ boost_contract_build.subdir-run-cxx11 disable : nothing_for_pre_prog : + <define>BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION ] + [ boost_contract_build.subdir-run-cxx11 disable : other_assertions_prog ] + + [ boost_contract_build.subdir-lib-cxx11 disable : lib_a : + <link>shared:<define>BOOST_CONTRACT_TEST_LIB_A_DYN_LINK ] + [ boost_contract_build.subdir-lib-cxx11 disable : lib_b : + <library>disable-lib_a + <link>shared:<define>BOOST_CONTRACT_TEST_LIB_B_DYN_LINK + ] + [ boost_contract_build.subdir-run-cxx11 disable : other_assertions_lib : + <library>disable-lib_a <library>disable-lib_b ] + + [ boost_contract_build.subdir-run-cxx11 disable : other_assertions_unit + disable/lib_a.cpp disable/lib_b.cpp ] + + [ boost_contract_build.subdir-lib-cxx11 disable : lib_x : + <define>BOOST_CONTRACT_NO_POSTCONDITIONS + <define>BOOST_CONTRACT_NO_EXCEPTS + <link>shared:<define>BOOST_CONTRACT_TEST_LIB_X_DYN_LINK + ] + [ boost_contract_build.subdir-lib-cxx11 disable : lib_y : + <library>disable-lib_x + <define>BOOST_CONTRACT_NO_POSTCONDITIONS + <define>BOOST_CONTRACT_NO_EXCEPTS + <link>shared:<define>BOOST_CONTRACT_TEST_LIB_Y_DYN_LINK + ] + [ boost_contract_build.subdir-run-cxx11 disable : no_post_except_lib : + <library>disable-lib_x <library>disable-lib_y ] + + [ boost_contract_build.subdir-run-cxx11 disable : no_post_except_unit + disable/lib_x.cpp disable/lib_y.cpp : + <define>BOOST_CONTRACT_NO_POSTCONDITIONS + <define>BOOST_CONTRACT_NO_EXCEPTS + ] + + [ boost_contract_build.subdir-run disable : audit : + <define>BOOST_CONTRACT_AUDITS ] + [ boost_contract_build.subdir-compile-fail disable : audit_error ] + [ boost_contract_build.subdir-run disable : audit_disabled ] + [ boost_contract_build.subdir-compile-fail disable : audit_disabled_error ] + [ boost_contract_build.subdir-run disable : axiom ] + [ boost_contract_build.subdir-compile-fail disable : axiom_error ] +; + +test-suite specify : + [ boost_contract_build.subdir-run-cxx11 specify : pre_old_post_except ] + + [ boost_contract_build.subdir-run-cxx11 specify : pre_old_post ] + [ boost_contract_build.subdir-run-cxx11 specify : pre_old_except ] + [ boost_contract_build.subdir-run-cxx11 specify : pre_post_except ] + [ boost_contract_build.subdir-run-cxx11 specify : old_post_except ] + + [ boost_contract_build.subdir-run-cxx11 specify : pre_old ] + [ boost_contract_build.subdir-run-cxx11 specify : pre_post ] + [ boost_contract_build.subdir-run-cxx11 specify : pre_except ] + [ boost_contract_build.subdir-run-cxx11 specify : old_post ] + [ boost_contract_build.subdir-run-cxx11 specify : old_except ] + [ boost_contract_build.subdir-run-cxx11 specify : post_except ] + + [ boost_contract_build.subdir-run-cxx11 specify : pre ] + [ boost_contract_build.subdir-run-cxx11 specify : old ] + [ boost_contract_build.subdir-run-cxx11 specify : post ] + [ boost_contract_build.subdir-run-cxx11 specify : except ] + + [ boost_contract_build.subdir-run specify : nothing ] + + [ boost_contract_build.subdir-compile-fail-cxx11 specify : + except_post_error ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : + except_old_error ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : + except_pre_error ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : post_old_error ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : post_pre_error ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : old_pre_error ] + + [ boost_contract_build.subdir-run-cxx11 specify : missing_check : + <define>BOOST_CONTRACT_ON_MISSING_CHECK_DECL=\"\{\ throw\ err()\;\ \}\" + ] + + [ boost_contract_build.subdir-compile-fail specify : auto_error : + [ requires cxx11_auto_declarations ] ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : auto_pre_error : + [ requires cxx11_auto_declarations ] ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : + auto_pre_old_error : [ requires cxx11_auto_declarations ] ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify : + auto_pre_old_post_error : [ requires cxx11_auto_declarations ] ] + [ boost_contract_build.subdir-compile-fail-cxx11 specify + : auto_pre_old_post_except_error + : [ requires cxx11_auto_declarations ] + ] +; + +test-suite call_if : + [ boost_contract_build.subdir-run-cxx11 call_if : true_ ] + [ boost_contract_build.subdir-run-cxx11 call_if : false_ ] + + [ boost_contract_build.subdir-run-cxx11 call_if : true_void ] + [ boost_contract_build.subdir-run-cxx11 call_if : false_void ] + + [ boost_contract_build.subdir-run-cxx11 call_if : equal_to ] + [ boost_contract_build.subdir-run-cxx11 call_if : equal_to_cxx14 : + [ requires cxx14_generic_lambdas ] ] + + [ boost_contract_build.subdir-run-cxx11 call_if : no_equal_condition_if ] + [ boost_contract_build.subdir-run-cxx11 call_if : no_equal_call_if ] + [ boost_contract_build.subdir-compile-fail-cxx11 call_if : no_equal_error ] +; + diff --git a/src/boost/libs/contract/test/call_if/equal_to.cpp b/src/boost/libs/contract/test/call_if/equal_to.cpp new file mode 100644 index 00000000..a71c12bf --- /dev/null +++ b/src/boost/libs/contract/test/call_if/equal_to.cpp @@ -0,0 +1,86 @@ + +// 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 STL equal_to with call_if. + +// C++17 warning from Boost.Bind. +#define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING + +#include "../detail/oteststream.hpp" +#include <boost/contract/call_if.hpp> +#include <boost/bind.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <functional> +#include <sstream> +#include <ios> + +boost::contract::test::detail::oteststream out; + +template<typename T> +struct void_equal_to { + typedef void result_type; // Test void result type. + + void operator()(T const& left, T const& right) const { + out << (left == right) << std::endl; + } +}; + +struct x {}; // Doest not have operator==. + +int main() { + std::ostringstream ok; + ok << std::boolalpha; + out << std::boolalpha; + x x1, x2;; + + out.str(""); + out << // Test on true condition with non-void result type. + boost::contract::call_if<boost::has_equal_to<int> >( + boost::bind(std::equal_to<int>(), 123, 123) // True. + ).else_( + // Compiler-error... but not called. + boost::bind(std::equal_to<x>(), x1, x2) + ) + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + out << // Test on false condition with non-void result type. + boost::contract::call_if<boost::has_equal_to<x> >( + // Compiler-error... but not called. + boost::bind(std::equal_to<x>(), x1, x2) + ).else_([] { return true; }) + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + // Test on true condition void result type. + boost::contract::call_if<boost::has_equal_to<int> >( + boost::bind(void_equal_to<int>(), 123, 456) // False. + ).else_( + // Compiler-error... but not called. + boost::bind(void_equal_to<x>(), x1, x1) + ); + ok.str(""); ok << false << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + // Test on false condition with void result type. + boost::contract::call_if<boost::has_equal_to<x> >( + // Compiler-error... but not called. + boost::bind(void_equal_to<x>(), x1, x1) + ).else_( + boost::bind(void_equal_to<int>(), 123, 456) // False. + ); + ok.str(""); ok << false << std::endl; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/call_if/equal_to_cxx14.cpp b/src/boost/libs/contract/test/call_if/equal_to_cxx14.cpp new file mode 100644 index 00000000..4ab59863 --- /dev/null +++ b/src/boost/libs/contract/test/call_if/equal_to_cxx14.cpp @@ -0,0 +1,56 @@ + +// 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 call_if equality check with C++14 generic lambdas. + +#include "../detail/oteststream.hpp" +#include <boost/contract/call_if.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <functional> // std::bind for generic lambdas. +#include <sstream> +#include <ios> + +boost::contract::test::detail::oteststream out; + +struct x {}; // Does not have operator==. + +int main() { + std::ostringstream ok; + ok << std::boolalpha; + out << std::boolalpha; + x x1, x2; + + out.str(""); + out << + boost::contract::call_if<boost::has_equal_to<int> >( + std::bind([] (auto a, auto b) { return a == b; }, 123, 456) + ).else_([] { return true; }) + << std::endl; + ok.str(""); ok << false << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + out << + boost::contract::call_if<boost::has_equal_to<x> >( + std::bind([] (auto a, auto b) { return a == b; }, x1, x2) + ).else_([] { return true; }) + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + out << // Test explicit result, cannot deduce from lambda missing `-> bool`. + boost::contract::call_if<boost::has_equal_to<x> >( + std::bind([] (auto a, auto b) { return a == b; }, x1, x2) + ).else_([] { return true; }) + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/call_if/false_.cpp b/src/boost/libs/contract/test/call_if/false_.cpp new file mode 100644 index 00000000..c604f6d8 --- /dev/null +++ b/src/boost/libs/contract/test/call_if/false_.cpp @@ -0,0 +1,65 @@ + +// 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 call_if with false condition and non-void result type. + +#include "../detail/oteststream.hpp" +#include <boost/contract/call_if.hpp> +#include <boost/bind.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <ios> + +boost::contract::test::detail::oteststream out; + +struct eq { + typedef bool result_type; // Test non-void result type. + + template<typename L, typename R> + result_type operator()(L left, R right) const { + return left == right; // Requires operator==. + } +}; + +struct x {}; // Doest not have operator==. + +int main() { + std::ostringstream ok; + ok << std::boolalpha; + out << std::boolalpha; + x x1, x2;; + + out.str(""); + out << + boost::contract::call_if<boost::has_equal_to<x> >( + boost::bind(eq(), x1, x1) // Compiler-error... but not called. + ).else_([] { return false; }) // Test else. + << std::endl; + ok.str(""); ok << false << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + out << + boost::contract::call_if<boost::has_equal_to<x> >( + boost::bind(eq(), x1, x2) // Compiler-error... but not called. + ).else_([] { return true; }) + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + out << // Test "..._c". + boost::contract::call_if_c<boost::has_equal_to<x>::value>( + boost::bind(eq(), x1, x2) // Compiler-error...but not called. + ).else_([] { return true; }) + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/call_if/false_void.cpp b/src/boost/libs/contract/test/call_if/false_void.cpp new file mode 100644 index 00000000..ca6465cd --- /dev/null +++ b/src/boost/libs/contract/test/call_if/false_void.cpp @@ -0,0 +1,55 @@ + +// 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 call_if with false condition and void result type. + +#include "../detail/oteststream.hpp" +#include <boost/contract/call_if.hpp> +#include <boost/bind.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <ios> + +boost::contract::test::detail::oteststream out; + +struct eq { + typedef void result_type; // Test void result type. + + template<typename L, typename R> + result_type operator()(L left, R right) const { + out << (left == right) << std::endl; // Requires operator==. + } +}; + +struct x {}; // Doest not have operator==. + +int main() { + std::ostringstream ok; + ok << std::boolalpha; + out << std::boolalpha; + x x1, x2;; + + out.str(""); + boost::contract::call_if<boost::has_equal_to<x> >( + boost::bind(eq(), x1, x2) // Compiler-error... but not called. + ); // Test no else. + ok.str(""); + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + // Test "..._c". + boost::contract::call_if_c<boost::has_equal_to<x>::value>( + boost::bind(eq(), x1, x2) // Compiler-error...but not called. + ).else_( + [] { out << true << std::endl; } // Test else. + ); + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/call_if/no_equal_call_if.cpp b/src/boost/libs/contract/test/call_if/no_equal_call_if.cpp new file mode 100644 index 00000000..854cffc5 --- /dev/null +++ b/src/boost/libs/contract/test/call_if/no_equal_call_if.cpp @@ -0,0 +1,66 @@ + +// 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 assertions skipped when operations to check them missing (e.g., `==`). + +// C++17 warning from Boost.Bind. +#define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/call_if.hpp> +#include <boost/bind.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <functional> +#include <vector> + +unsigned equal_skips; + +template<typename T> +void push_back(std::vector<T>& vect, T const& value) { + boost::contract::check c = boost::contract::function() + .postcondition([&] { + BOOST_CONTRACT_ASSERT( + boost::contract::call_if<boost::has_equal_to<T> >( + boost::bind(std::equal_to<T>(), boost::cref(vect.back()), + boost::cref(value)) + // Explicit bool return and [&] needed for MSVC10 lambdas. + ).else_([&] () -> bool { ++equal_skips; return true; }) + ); + }) + ; + vect.push_back(value); +} + +struct j { // Type without operator==. + explicit j(int /* i */) {} +}; + +int main() { + std::vector<int> vi; + equal_skips = 0; + push_back(vi, 123); + BOOST_TEST_EQ(equal_skips, 0); + + unsigned const cnt = + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + 1 + #else + 0 + #endif + ; + + j jj(456); + std::vector<j> vj; + equal_skips = 0; + push_back(vj, jj); + BOOST_TEST_EQ(equal_skips, cnt); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/call_if/no_equal_condition_if.cpp b/src/boost/libs/contract/test/call_if/no_equal_condition_if.cpp new file mode 100644 index 00000000..e4929d16 --- /dev/null +++ b/src/boost/libs/contract/test/call_if/no_equal_condition_if.cpp @@ -0,0 +1,66 @@ + +// 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 assertions skipped when operations to check them missing (e.g., `==`). + +// C++17 warning from Boost.Bind. +#define _SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/call_if.hpp> +#include <boost/bind.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <functional> +#include <vector> + +unsigned equal_skips; + +template<typename T> +void push_back(std::vector<T>& vect, T const& value) { + boost::contract::check c = boost::contract::function() + .postcondition([&] { + BOOST_CONTRACT_ASSERT( + boost::contract::condition_if<boost::has_equal_to<T> >( + boost::bind(std::equal_to<T>(), boost::cref(vect.back()), + boost::cref(value)) + ) + ); + if(!boost::has_equal_to<T>::value) ++equal_skips; + }) + ; + vect.push_back(value); +} + +struct j { // Type without operator==. + explicit j(int /* i */) {} +}; + +int main() { + std::vector<int> vi; + equal_skips = 0; + push_back(vi, 123); + BOOST_TEST_EQ(equal_skips, 0u); + + unsigned const cnt = + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + 1 + #else + 0 + #endif + ; + + j jj(456); + std::vector<j> vj; + equal_skips = 0; + push_back(vj, jj); + BOOST_TEST_EQ(equal_skips, cnt); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/call_if/no_equal_error.cpp b/src/boost/libs/contract/test/call_if/no_equal_error.cpp new file mode 100644 index 00000000..025e9c76 --- /dev/null +++ b/src/boost/libs/contract/test/call_if/no_equal_error.cpp @@ -0,0 +1,41 @@ + +// 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 assertion error when operations to check them missing (e.g., `==`). + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <vector> + +template<typename T> +void push_back(std::vector<T>& vect, T const& value) { + boost::contract::check c = boost::contract::function() + .postcondition([&] { + BOOST_CONTRACT_ASSERT(vect.back() == value); // Error (j has no ==). + #ifdef BOOST_CONTRACT_NO_ALL + #error "force error if no contracts (ASSERT expands to nothing)" + #endif + }) + ; + vect.push_back(value); +} + +struct j { // Type without operator==. + explicit j(int /* i */) {} +}; + +int main() { + std::vector<int> vi; + push_back(vi, 123); + + j jj(456); + std::vector<j> vj; + push_back(vj, jj); + + return 0; +} + diff --git a/src/boost/libs/contract/test/call_if/true_.cpp b/src/boost/libs/contract/test/call_if/true_.cpp new file mode 100644 index 00000000..d8c47f49 --- /dev/null +++ b/src/boost/libs/contract/test/call_if/true_.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 call_if with true condition and non-void result type. + +#include "../detail/oteststream.hpp" +#include <boost/contract/call_if.hpp> +#include <boost/bind.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <ios> + +boost::contract::test::detail::oteststream out; + +struct eq { + typedef bool result_type; // Test non-void result type. + + template<typename L, typename R> + result_type operator()(L left, R right) const { + return left == right; // Requires operator==. + } +}; + +struct x {}; // Doest not have operator==. + +int main() { + std::ostringstream ok; + ok << std::boolalpha; + out << std::boolalpha; + x x1, x2;; + + out.str(""); + out << + boost::contract::call_if<boost::has_equal_to<int> >( + boost::bind(eq(), 123, 456) // False. + ) // Test no else (not called). + << std::endl; + ok.str(""); ok << false << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + out << + boost::contract::call_if<boost::has_equal_to<int> >( + boost::bind(eq(), 123, 123) // True. + ).else_([] { return false; }) // Test else not called. + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + out << // Test "..._c". + boost::contract::call_if_c<boost::has_equal_to<int>::value>( + boost::bind(eq(), 123, 123) // True. + ).else_( // Test else not called. + boost::bind(eq(), x1, x2) // Compiler-error... but not called. + ) + << std::endl; + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/call_if/true_void.cpp b/src/boost/libs/contract/test/call_if/true_void.cpp new file mode 100644 index 00000000..d3279c80 --- /dev/null +++ b/src/boost/libs/contract/test/call_if/true_void.cpp @@ -0,0 +1,64 @@ + +// 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 call_if with true condition and void result type. + +#include "../detail/oteststream.hpp" +#include <boost/contract/call_if.hpp> +#include <boost/bind.hpp> +#include <boost/type_traits/has_equal_to.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <ios> + +boost::contract::test::detail::oteststream out; + +struct eq { + typedef void result_type; // Test void result type. + + template<typename L, typename R> + result_type operator()(L left, R right) const { + out << (left == right) << std::endl; // Requires operator==. + } +}; + +struct x {}; // Doest not have operator==. + +int main() { + std::ostringstream ok; + ok << std::boolalpha; + out << std::boolalpha; + x x1, x2;; + + out.str(""); + boost::contract::call_if<boost::has_equal_to<int> >( + boost::bind(eq(), 123, 456) // False. + ); // Test no else (not called). + ok.str(""); ok << false << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + boost::contract::call_if<boost::has_equal_to<int> >( + boost::bind(eq(), 123, 123) // True. + ).else_( + [] { return false; } + ); // Test else (not called). + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + // Test "..._c". + boost::contract::call_if_c<boost::has_equal_to<int>::value>( + boost::bind(eq(), 123, 123) // True. + ).else_( // Test else (not called). + boost::bind(eq(), x1, x2) // Compiler-error... but not called. + ); + ok.str(""); ok << true << std::endl; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/check/audit.cpp b/src/boost/libs/contract/test/check/audit.cpp new file mode 100644 index 00000000..cb0765ea --- /dev/null +++ b/src/boost/libs/contract/test/check/audit.cpp @@ -0,0 +1,11 @@ + +// 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 + +#ifndef BOOST_CONTRACT_AUDITS + #error "build must define AUDITS" +#endif +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/check/audit.hpp b/src/boost/libs/contract/test/check/audit.hpp new file mode 100644 index 00000000..0b649ed9 --- /dev/null +++ b/src/boost/libs/contract/test/check/audit.hpp @@ -0,0 +1,36 @@ + +// 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 + +#include <boost/contract/check.hpp> +#include <boost/contract/core/exception.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + boost::contract::set_check_failure([] { throw err(); }); + + bool threw = false; + try { + #ifdef BOOST_CONTRACT_TEST_ERROR + BOOST_CONTRACT_CHECK_AUDIT( + BOOST_CONTRACT_TEST_ERROR_expected_undeclared_identifier); + #else + BOOST_CONTRACT_CHECK_AUDIT(false); + #endif + } catch(err const&) { threw = true; } + + #if defined(BOOST_CONTRACT_AUDITS) && !defined(BOOST_CONTRACT_NO_CHECKS) + BOOST_TEST(threw); + #else + BOOST_TEST(!threw); + #endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/check/audit_disabled.cpp b/src/boost/libs/contract/test/check/audit_disabled.cpp new file mode 100644 index 00000000..18c6ad03 --- /dev/null +++ b/src/boost/libs/contract/test/check/audit_disabled.cpp @@ -0,0 +1,8 @@ + +// 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 + +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/check/audit_disabled_error.cpp b/src/boost/libs/contract/test/check/audit_disabled_error.cpp new file mode 100644 index 00000000..c58714dc --- /dev/null +++ b/src/boost/libs/contract/test/check/audit_disabled_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_ERROR +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/check/audit_error.cpp b/src/boost/libs/contract/test/check/audit_error.cpp new file mode 100644 index 00000000..c58714dc --- /dev/null +++ b/src/boost/libs/contract/test/check/audit_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_ERROR +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/check/axiom.cpp b/src/boost/libs/contract/test/check/axiom.cpp new file mode 100644 index 00000000..b24af7a4 --- /dev/null +++ b/src/boost/libs/contract/test/check/axiom.cpp @@ -0,0 +1,8 @@ + +// 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 + +#include "axiom.hpp" + diff --git a/src/boost/libs/contract/test/check/axiom.hpp b/src/boost/libs/contract/test/check/axiom.hpp new file mode 100644 index 00000000..ddf87f8c --- /dev/null +++ b/src/boost/libs/contract/test/check/axiom.hpp @@ -0,0 +1,23 @@ + +// 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 + +#include <boost/contract/check.hpp> + +bool no_impl(); // Test func that cannot be impl in C++ sill OK in axioms. + +int main() { + #ifdef BOOST_CONTRACT_TEST_ERROR + BOOST_CONTRACT_CHECK_AXIOM( + BOOST_CONTRACT_TEST_ERROR_expected_undeclared_identifier); + #else + BOOST_CONTRACT_CHECK_AXIOM(false); // Test always false, OK. + BOOST_CONTRACT_CHECK_AXIOM(no_impl()); // Test no implementation, OK. + #endif + return 0; +} + diff --git a/src/boost/libs/contract/test/check/axiom_error.cpp b/src/boost/libs/contract/test/check/axiom_error.cpp new file mode 100644 index 00000000..a7c4c406 --- /dev/null +++ b/src/boost/libs/contract/test/check/axiom_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_ERROR +#include "axiom.hpp" + diff --git a/src/boost/libs/contract/test/check/decl.hpp b/src/boost/libs/contract/test/check/decl.hpp new file mode 100644 index 00000000..1b592fb3 --- /dev/null +++ b/src/boost/libs/contract/test/check/decl.hpp @@ -0,0 +1,66 @@ + +// 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 check (class and macro). + +#include "../detail/oteststream.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; + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +void f(bool check) { + #ifdef BOOST_CONTRACT_TEST_CHECK_MACRO + BOOST_CONTRACT_CHECK([&] () -> bool { + out << "f::check" << std::endl; + return check; + }()); + #else + boost::contract::check c = [&] { + out << "f::check" << std::endl; + BOOST_CONTRACT_ASSERT(check); + }; + #endif + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(true); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_CHECKS + << "f::check" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_check_failure([] { throw err(); }); + + out.str(""); + try { + f(false); + #ifndef BOOST_CONTRACT_NO_CHECKS + BOOST_TEST(false); + } catch(err const&) { + ok.str(""); + ok << "f::check" << std::endl; + #else + ok.str(""); + ok << "f::body" << 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/check/decl_class.cpp b/src/boost/libs/contract/test/check/decl_class.cpp new file mode 100644 index 00000000..eb586341 --- /dev/null +++ b/src/boost/libs/contract/test/check/decl_class.cpp @@ -0,0 +1,11 @@ + +// 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 check class. + +#undef BOOST_CONTRACT_TEST_CHECK_MACRO +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/check/decl_macro.cpp b/src/boost/libs/contract/test/check/decl_macro.cpp new file mode 100644 index 00000000..f36ce189 --- /dev/null +++ b/src/boost/libs/contract/test/check/decl_macro.cpp @@ -0,0 +1,11 @@ + +// 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 check macro. + +#define BOOST_CONTRACT_TEST_CHECK_MACRO +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/check/ifdef.cpp b/src/boost/libs/contract/test/check/ifdef.cpp new file mode 100644 index 00000000..561eb76e --- /dev/null +++ b/src/boost/libs/contract/test/check/ifdef.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 contract compilation on/off. + +#include "../detail/oteststream.hpp" +#include <boost/contract/core/config.hpp> +#ifndef BOOST_CONTRACT_NO_CHECKS + #include <boost/contract/check.hpp> + #include <boost/contract/assert.hpp> +#else + #include <boost/contract/core/check_macro.hpp> + #include <boost/contract/core/exception.hpp> +#endif +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f(bool check1, bool check2) { + BOOST_CONTRACT_CHECK([&] () -> bool { // Macro already so #ifdef needed. + out << "f::check1" << std::endl; + return check1; + }()); + #ifndef BOOST_CONTRACT_NO_CHECKS + boost::contract::check c = [&] { + out << "f::check2" << std::endl; + BOOST_CONTRACT_ASSERT(check2); + }; + #endif + out << "f::body" << std::endl; +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + out.str(""); + f(true, true); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_CHECKS + << "f::check1" << std::endl + << "f::check2" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_check_failure([] { throw err(); }); + + out.str(""); + try { + f(false, true); + #ifndef BOOST_CONTRACT_NO_CHECKS + BOOST_TEST(false); + } catch(err const&) { + ok.str(""); + ok << "f::check1" << std::endl; + #else + ok.str(""); + ok << "f::body" << std::endl; + #endif + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + out.str(""); + try { + f(true, false); + #ifndef BOOST_CONTRACT_NO_CHECKS + BOOST_TEST(false); + } catch(err const&) { + ok.str(""); + ok << "f::check1" << std::endl; + ok << "f::check2" << std::endl; + #else + ok.str(""); + ok << "f::body" << std::endl; + #endif + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + // No need to test `f(false, false)` because same as `f(false, true)`. + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/check/ifdef_macro.cpp b/src/boost/libs/contract/test/check/ifdef_macro.cpp new file mode 100644 index 00000000..67616a89 --- /dev/null +++ b/src/boost/libs/contract/test/check/ifdef_macro.cpp @@ -0,0 +1,63 @@ + +// 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 only). + +#include "../detail/oteststream.hpp" +#include "../detail/unprotected_commas.hpp" +#include <boost/contract_macro.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f(bool check) { + BOOST_CONTRACT_CHECK(( + [&] () -> bool { + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + out << "f::check" << std::endl; + return check; + }() + )); + out << "f::body" << std::endl; +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + out.str(""); + f(true); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_CHECKS + << "f::check" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_check_failure([] { throw err(); }); + + out.str(""); + try { + f(false); + #ifndef BOOST_CONTRACT_NO_CHECKS + BOOST_TEST(false); + } catch(err const&) { + ok.str(""); + ok << "f::check" << std::endl; + #else + ok.str(""); + ok << "f::body" << 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/constructor/access.cpp b/src/boost/libs/contract/test/constructor/access.cpp new file mode 100644 index 00000000..19eae17d --- /dev/null +++ b/src/boost/libs/contract/test/constructor/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/constructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +class b + #define BASES private boost::contract::constructor_precondition<b> + : BASES +{ + friend class boost::contract::access; + + 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; } + +public: + b() : boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + }) { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "b::ctor::old" << std::endl; }) + .postcondition([] { out << "b::ctor::post" << std::endl; }) + ; + out << "b::ctor::body" << std::endl; + } +}; + +class a + #define BASES private boost::contract::constructor_precondition<a>, public b + : BASES +{ + friend class boost::contract::access; + + // Private base types (always OK because never used by ctors). + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + // Private invariants. + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + +public: + a() : boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + }) { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "a::ctor::old" << std::endl; }) + .postcondition([] { out << "a::ctor::post" << std::endl; }) + ; + out << "a::ctor::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + out.str(""); + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + b bb; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl.hpp b/src/boost/libs/contract/test/constructor/decl.hpp new file mode 100644 index 00000000..59e42128 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl.hpp @@ -0,0 +1,170 @@ + +#ifndef BOOST_CONTRACT_TEST_CONSTRUCTOR_DECL_HPP_ +#define BOOST_CONTRACT_TEST_CONSTRUCTOR_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/constructor.hpp> +#include <boost/contract/base_types.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_exit_inv = true; // Only exit non-static inv for ctors. +struct c + #ifndef BOOST_CONTRACT_TEST_NO_C_PRE + : private boost::contract::constructor_precondition<c> + #endif +{ + #ifndef BOOST_CONTRACT_TEST_NO_C_STATIC_INV + static void static_invariant() { + out << "c::static_inv" << std::endl; + if(c_entering_static_inv) BOOST_CONTRACT_ASSERT(c_entry_static_inv); + else BOOST_CONTRACT_ASSERT(c_exit_static_inv); + c_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_C_INV + void invariant() const { + out << "c::inv" << std::endl; + BOOST_CONTRACT_ASSERT(c_exit_inv); + } + #endif + + c() + #ifndef BOOST_CONTRACT_TEST_NO_C_PRE + : boost::contract::constructor_precondition<c>([] { + out << "c::ctor::pre" << std::endl; + BOOST_CONTRACT_ASSERT(c_pre); + }) + #endif + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "c::ctor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_C_POST + .postcondition([] { + out << "c::ctor::post" << std::endl; + BOOST_CONTRACT_ASSERT(c_post); + }) + #endif + ; + out << "c::ctor::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_exit_inv = true; // Only exit non-static inv for ctors. +struct b + #ifndef BOOST_CONTRACT_TEST_NO_B_PRE + #define BASES \ + private boost::contract::constructor_precondition<b>, public c + #else + #define BASES public c + #endif + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + #ifndef BOOST_CONTRACT_TEST_NO_B_STATIC_INV + static void static_invariant() { + out << "b::static_inv" << std::endl; + if(b_entering_static_inv) BOOST_CONTRACT_ASSERT(b_entry_static_inv); + else BOOST_CONTRACT_ASSERT(b_exit_static_inv); + b_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_B_INV + void invariant() const { + out << "b::inv" << std::endl; + BOOST_CONTRACT_ASSERT(b_exit_inv); + } + #endif + + b() + #ifndef BOOST_CONTRACT_TEST_NO_B_PRE + : boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + BOOST_CONTRACT_ASSERT(b_pre); + }) + #endif + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "b::ctor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_B_POST + .postcondition([] { + out << "b::ctor::post" << std::endl; + BOOST_CONTRACT_ASSERT(b_post); + }) + #endif + ; + out << "b::ctor::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_exit_inv = true; // Only exit non-static inv for ctors. +struct a + #ifndef BOOST_CONTRACT_TEST_NO_A_PRE + #define BASES \ + private boost::contract::constructor_precondition<a>, public b + #else + #define BASES public b + #endif + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + #ifndef BOOST_CONTRACT_TEST_NO_A_STATIC_INV + static void static_invariant() { + out << "a::static_inv" << std::endl; + if(a_entering_static_inv) BOOST_CONTRACT_ASSERT(a_entry_static_inv); + else BOOST_CONTRACT_ASSERT(a_exit_static_inv); + a_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_A_INV + void invariant() const { + out << "a::inv" << std::endl; + BOOST_CONTRACT_ASSERT(a_exit_inv); + } + #endif + + a() + #ifndef BOOST_CONTRACT_TEST_NO_A_PRE + : boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + BOOST_CONTRACT_ASSERT(a_pre); + }) + #endif + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "a::ctor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_A_POST + .postcondition([] { + out << "a::ctor::post" << std::endl; + BOOST_CONTRACT_ASSERT(a_post); + }) + #endif + ; + out << "a::ctor::body" << std::endl; + } +}; + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/constructor/decl_entry_static_inv_all.cpp b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_all.cpp new file mode 100644 index 00000000..b5f4ad6f --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_all.cpp @@ -0,0 +1,219 @@ + +// 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_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // Might fail. + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl // Might fail. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Might fail. + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::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_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(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test a::static_inv failed. + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::static_inv failed. + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::static_inv failed. + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::static_inv failed (as all did). + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_b() + << ok_a() + << 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/constructor/decl_entry_static_inv_ends.cpp b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_ends.cpp new file mode 100644 index 00000000..32168cb9 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_ends.cpp @@ -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 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_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // This might fail. + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + // No b::static_inv to fail. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // This might fail. + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::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_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(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test a::static_inv failed. + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << 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(""); + a aa; + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::static_inv failed. + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::static_inv failed (as all did). + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_b() + << ok_a() + << 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/constructor/decl_entry_static_inv_mid.cpp b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_mid.cpp new file mode 100644 index 00000000..104388be --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_mid.cpp @@ -0,0 +1,204 @@ + +// 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_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + // No c::static_inv here. + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl // This might fail. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + // No a::static_inv here. + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::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_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(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_b() + << ok_a() + << 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(""); + a aa; + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test no a::static_inv so no failure. + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } + + std::cout << "---" << std::endl; + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::static_inv failed. + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_a() + << ok_end() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + std::cout << "===" << std::endl; + + 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(""); + a aa; + ok.str(""); ok + << ok_c() // Test no c::static_inv so no failure. + << ok_b() + << ok_a() + << ok_end() + ; + 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::static_inv failed (as all did). + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_a() + << 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/constructor/decl_entry_static_inv_none.cpp b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_none.cpp new file mode 100644 index 00000000..58b711d7 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_entry_static_inv_none.cpp @@ -0,0 +1,124 @@ + +// 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 +#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_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + + #ifdef BOOST_CONTRACT_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + out.str(""); + a aa; + 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(""); + a aa; + 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(""); + a aa; + 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(""); + a aa; + 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(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_exit_inv_all.cpp b/src/boost/libs/contract/test/constructor/decl_exit_inv_all.cpp new file mode 100644 index 00000000..3aee1cc4 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_inv_all.cpp @@ -0,0 +1,201 @@ + +// 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/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test nothing fails. + << ok_c() + << ok_b() + << ok_a() + << 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; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test a::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << 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; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test bb::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_a() + << 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; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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/constructor/decl_exit_inv_ends.cpp b/src/boost/libs/contract/test/constructor/decl_exit_inv_ends.cpp new file mode 100644 index 00000000..ac45eac2 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_inv_ends.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 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/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + // No failure here. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test no failure. + << ok_c() + << ok_b() + << ok_a() + << 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; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test a::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << 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; + try { + out.str(""); + a aa; + ok.str(""); ok + << ok_c() + << ok_b() // Test no b::inv so no failure. + << ok_a() + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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/constructor/decl_exit_inv_mid.cpp b/src/boost/libs/contract/test/constructor/decl_exit_inv_mid.cpp new file mode 100644 index 00000000..d9c8bcd4 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_inv_mid.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 middle 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/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + // No failure here. + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + // No failure here. + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_b() + << ok_a() + << 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; + try { + out.str(""); + a aa; + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test no failure here. + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = true; + b_exit_inv = false; + c_exit_inv = true; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_a() + << 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; + try { + out.str(""); + a aa; + ok.str(""); ok + << ok_c() // Test no failure here. + << ok_b() + << ok_a() + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_inv = false; + b_exit_inv = false; + c_exit_inv = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_a() + << 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/constructor/decl_exit_inv_none.cpp b/src/boost/libs/contract/test/constructor/decl_exit_inv_none.cpp new file mode 100644 index 00000000..baf89813 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_inv_none.cpp @@ -0,0 +1,115 @@ + +// 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 grandparent classes (ends) with 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/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_exit_inv = false; + b_exit_inv = true; + c_exit_inv = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_exit_inv = true; + b_exit_inv = false; + c_exit_inv = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_exit_inv = true; + b_exit_inv = true; + c_exit_inv = false; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_exit_inv = false; + b_exit_inv = false; + c_exit_inv = false; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_exit_static_inv_all.cpp b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_all.cpp new file mode 100644 index 00000000..e33e4cd1 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_all.cpp @@ -0,0 +1,224 @@ + +// 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_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::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_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(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test exit a::static_inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test exit b::static_inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test exit c::static_inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test exit c::static_inv failed (as all did). + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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/constructor/decl_exit_static_inv_ends.cpp b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_ends.cpp new file mode 100644 index 00000000..a8b2f5e6 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_ends.cpp @@ -0,0 +1,213 @@ + +// 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 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_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::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_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(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test a::static_inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << 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); + try { + out.str(""); + a aa; + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::static_inv failed (as all did). + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::static_inv failed (as all did). + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_b() + << ok_a() + << 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/constructor/decl_exit_static_inv_mid.cpp b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_mid.cpp new file mode 100644 index 00000000..c8a24bde --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_mid.cpp @@ -0,0 +1,202 @@ + +// 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_c() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + // No failure here. + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + // No failure here. + ; + return ok.str(); +} + +std::string ok_end() { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::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_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(""); + a aa; + ok.str(""); ok // Test nothing fails. + << ok_c() + << ok_b() + << ok_a() + << 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); + try { + out.str(""); + a aa; + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() // Test no a::static_inv so no failure. + << ok_end() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::static_inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_a() + << 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); + try { + out.str(""); + a aa; + ok.str(""); ok + << ok_c() // Test no c::static_inv so no failure. + << ok_b() + << ok_a() + << ok_end() + ; + 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); + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::static_inv failed. + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << ok_a() + << 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/constructor/decl_exit_static_inv_none.cpp b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_none.cpp new file mode 100644 index 00000000..79ceaf79 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_exit_static_inv_none.cpp @@ -0,0 +1,123 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without exit static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + out.str(""); + a aa; + 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(""); + a aa; + 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(""); + a aa; + 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(""); + a aa; + 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(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_post_all.cpp b/src/boost/libs/contract/test/constructor/decl_post_all.cpp new file mode 100644 index 00000000..b4e38a1c --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_post_all.cpp @@ -0,0 +1,186 @@ + +// 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_c() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + out.str(""); + { + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_b() + << ok_a() + ; + 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 { + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() + << ok_a() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + out.str(""); + try { + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_b() // Test b::ctor::post failed. + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_a() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + out.str(""); + try { + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::ctor::post failed. + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_b() + << ok_a() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + out.str(""); + try { + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::ctor::post failed (as all did) + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_b() + << ok_a() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_post_ends.cpp b/src/boost/libs/contract/test/constructor/decl_post_ends.cpp new file mode 100644 index 00000000..b98af74f --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_post_ends.cpp @@ -0,0 +1,168 @@ + +// 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_c() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_ba() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + // No b::ctor::post here. + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_c() + << ok_ba() + ; + 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; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() + << ok_ba() // Test a::ctor::post failed. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + { + out.str(""); + a aa; + ok.str(""); ok + << ok_c() + << ok_ba() // Test no b::ctor::post so no failure. + ; + BOOST_TEST(out.eq(ok.str())); + } + + a_post = true; + b_post = true; + c_post = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::ctor::post failed. + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_ba() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_c() // Test c::ctor::post failed (as all did). + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_ba() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_post_mid.cpp b/src/boost/libs/contract/test/constructor/decl_post_mid.cpp new file mode 100644 index 00000000..a6afce6b --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_post_mid.cpp @@ -0,0 +1,160 @@ + +// 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_cb() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "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_post = true; + b_post = true; + c_post = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test nothing failed. + << ok_cb() + << ok_a() + ; + 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(""); + a aa; + ok.str(""); ok + << ok_cb() + << ok_a() // Test no a::ctor::post so no failure. + ; + BOOST_TEST(out.eq(ok.str())); + } + + a_post = true; + b_post = false; + c_post = true; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_cb() // Test b::ctor::post failed. + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_a() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + { + out.str(""); + a aa; + ok.str(""); ok + << ok_cb() // Test no c::ctor::post so no failure. + << ok_a() + ; + BOOST_TEST(out.eq(ok.str())); + } + + a_post = false; + b_post = false; + c_post = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_cb() // Test b::ctor::post failed (as all did). + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + << ok_a() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_post_none.cpp b/src/boost/libs/contract/test/constructor/decl_post_none.cpp new file mode 100644 index 00000000..2b837e19 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_post_none.cpp @@ -0,0 +1,109 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with 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_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + ; + + a_post = true; + b_post = true; + c_post = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_post = false; + b_post = true; + c_post = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_post = true; + b_post = false; + c_post = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_post = true; + b_post = true; + c_post = false; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_post = false; + b_post = false; + c_post = false; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_pre_all.cpp b/src/boost/libs/contract/test/constructor/decl_pre_all.cpp new file mode 100644 index 00000000..4714a742 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_pre_all.cpp @@ -0,0 +1,178 @@ + +// 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_after() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_pre = true; + b_pre = true; + c_pre = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + << ok_after() + ; + BOOST_TEST(out.eq(ok.str())); + } + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_pre = false; + b_pre = true; + c_pre = true; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl // Test this failed. + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = true; + b_pre = false; + c_pre = true; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl // Test this failed. + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = true; + b_pre = true; + c_pre = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl // Test this failed. + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = false; + b_pre = false; + c_pre = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl // Test this failed (as all did). + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_pre_ends.cpp b/src/boost/libs/contract/test/constructor/decl_pre_ends.cpp new file mode 100644 index 00000000..6a6a1c13 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_pre_ends.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 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_after() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_pre = true; + b_pre = true; + c_pre = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + << ok_after() + ; + BOOST_TEST(out.eq(ok.str())); + } + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_pre = false; + b_pre = true; + c_pre = true; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl // Test this failed. + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = true; + b_pre = false; + c_pre = true; + { + out.str(""); + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + // Test no failure here. + << "c::ctor::pre" << std::endl + #endif + << ok_after() + ; + BOOST_TEST(out.eq(ok.str())); + } + + a_pre = true; + b_pre = true; + c_pre = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl // Test this failed. + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_pre = false; + b_pre = false; + c_pre = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl // Test this failed (as all did). + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_pre_mid.cpp b/src/boost/libs/contract/test/constructor/decl_pre_mid.cpp new file mode 100644 index 00000000..a4e7761e --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_pre_mid.cpp @@ -0,0 +1,164 @@ + +// 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 classes 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_after() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_pre = true; + b_pre = true; + c_pre = true; + { + out.str(""); + a aa; + ok.str(""); ok // Test nothing failed. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl + #endif + << ok_after() + ; + BOOST_TEST(out.eq(ok.str())); + } + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw err(); }); + + a_pre = false; + b_pre = true; + c_pre = true; + { + out.str(""); + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl // Test no failure here. + #endif + << ok_after() + ; + BOOST_TEST(out.eq(ok.str())); + } + + a_pre = true; + b_pre = false; + c_pre = true; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl // Test this failed. + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + + a_pre = true; + b_pre = true; + c_pre = false; + { + out.str(""); + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl // Test no failure here. + #endif + << ok_after() + ; + BOOST_TEST(out.eq(ok.str())); + } + + a_pre = false; + b_pre = false; + c_pre = false; + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl // Test this failed (as all did). + #else + << ok_after() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/decl_pre_none.cpp b/src/boost/libs/contract/test/constructor/decl_pre_none.cpp new file mode 100644 index 00000000..4fa27f03 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/decl_pre_none.cpp @@ -0,0 +1,114 @@ + +// 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 no preconditions here. + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + + a_pre = true; + b_pre = true; + c_pre = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_pre = false; + b_pre = true; + c_pre = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_pre = true; + b_pre = false; + c_pre = true; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_pre = true; + b_pre = true; + c_pre = false; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + a_pre = false; + b_pre = false; + c_pre = false; + { + out.str(""); + a aa; + BOOST_TEST(out.eq(ok.str())); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/ifdef.cpp b/src/boost/libs/contract/test/constructor/ifdef.cpp new file mode 100644 index 00000000..8f58c5b9 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/ifdef.cpp @@ -0,0 +1,133 @@ + +// 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> +#if !defined(BOOST_CONTRACT_NO_CONSTRUCTORS) || \ + !defined(BOOST_CONTRACT_NO_PRECONDITIONS) + #include <boost/contract/constructor.hpp> +#endif +#ifndef BOOST_CONTRACT_NO_CONSTRUCTORS + #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_PRECONDITIONS + : private boost::contract::constructor_precondition<b> + #endif +{ + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + #endif + + explicit b(int x) + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + : boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + }) + #endif + { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); + #endif + #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS + boost::contract::check c = boost::contract::constructor(this) + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::ctor::post" << std::endl; }) + #endif + ; + #endif + out << "b::ctor::body" << std::endl; + } +}; + +struct a : + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + private boost::contract::constructor_precondition<a>, + #endif + public b +{ + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + #endif + + explicit a(int x) : + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + }), + #endif + b(x) + { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); + #endif + #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS + boost::contract::check c = boost::contract::constructor(this) + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::ctor::post" << std::endl; }) + #endif + ; + #endif + out << "a::ctor::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + out.str(""); + a aa(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::f::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/ifdef_macro.cpp b/src/boost/libs/contract/test/constructor/ifdef_macro.cpp new file mode 100644 index 00000000..2041cdaa --- /dev/null +++ b/src/boost/libs/contract/test/constructor/ifdef_macro.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 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/constructor.hpp> // Outside #if below for ctor pre. +#include <boost/contract_macro.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct b : + private boost::contract::constructor_precondition<b> // OK, always in code. +{ + 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; + }) + + explicit b(int x) : + BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(b)([] { + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + out << "b::ctor::pre" << std::endl; + }) + { + 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_CONSTRUCTOR(this) + 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::ctor::post" << std::endl; + }) + ; + out << "b::ctor::body" << std::endl; + } +}; + +struct a: + private boost::contract::constructor_precondition<a>, // OK, always in code. + public b +{ + BOOST_CONTRACT_STATIC_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::static_inv" << std::endl; + }) + + BOOST_CONTRACT_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::inv" << std::endl; + }) + + explicit a(int x) : + BOOST_CONTRACT_CONSTRUCTOR_PRECONDITION(a)([] { + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + out << "a::ctor::pre" << std::endl; } + ), + b(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_CONSTRUCTOR(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::f::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::ctor::post" << std::endl; + }) + ; + out << "a::ctor::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + out.str(""); + a aa(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::f::old" << std::endl + #endif + << "a::ctor::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::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/pre_error.cpp b/src/boost/libs/contract/test/constructor/pre_error.cpp new file mode 100644 index 00000000..36e06c4c --- /dev/null +++ b/src/boost/libs/contract/test/constructor/pre_error.cpp @@ -0,0 +1,24 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test constructor cannot use `.precondition(...)`. + +#include <boost/contract/constructor.hpp> +#include <boost/contract/check.hpp> + +struct a { + a() { + boost::contract::check c = boost::contract::constructor(this) + .precondition([] {}) // Error (must use constructor_precondition). + ; + } +}; + +int main() { + a aa; + return 0; +} + diff --git a/src/boost/libs/contract/test/constructor/smoke.cpp b/src/boost/libs/contract/test/constructor/smoke.cpp new file mode 100644 index 00000000..133cc140 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/smoke.cpp @@ -0,0 +1,410 @@ + +// 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 constructor subcontracting. + +#include "../detail/oteststream.hpp" +#include "../detail/counter.hpp" +#include <boost/contract/constructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/bind.hpp> +#include <boost/ref.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +template<char Id> +struct t + #define BASES private boost::contract::constructor_precondition<t<Id> > + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { + out << Id << "::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(l.value >= 0); + } + + void invariant() const { + out << Id << "::inv" << std::endl; + BOOST_CONTRACT_ASSERT(k_ < 0); + } + + struct l_tag; + typedef boost::contract::test::detail::counter<l_tag, int> l_type; + static l_type l; + + struct z_tag; + typedef boost::contract::test::detail::counter<z_tag, int> z_type; + + explicit t(z_type& z) : + boost::contract::constructor_precondition<t<Id> >([&] { + out << Id << "::ctor::pre" << std::endl; + BOOST_CONTRACT_ASSERT(z.value < 0); + }) + { + boost::contract::old_ptr<z_type> old_z; + boost::contract::old_ptr<l_type> old_l = + BOOST_CONTRACT_OLDOF(l_type::eval(l)); + boost::contract::check c = boost::contract::constructor(this) + .old([&] { + out << Id << "::ctor::old" << std::endl; + old_z = BOOST_CONTRACT_OLDOF(z_type::eval(z)); + }) + .postcondition([&] { + out << Id << "::ctor::post" << std::endl; + BOOST_CONTRACT_ASSERT(k_ == old_z->value); + BOOST_CONTRACT_ASSERT(z.value == l.value); + BOOST_CONTRACT_ASSERT(l.value == old_l->value + 1); + }) + ; + out << Id << "::ctor::body" << std::endl; + k_ = z.value; + z.value = ++l.value; + } + + virtual ~t() { --l.value; } + +private: + int k_; +}; +template<char Id> typename t<Id>::l_type t<Id>::l; + +// Test deep inheritance (2 vertical levels), multiple inheritance (4 +// horizontal levels), and that all public/protected/private part of +// subcontracting for constructors (not just public, because all access levels +// are part of C++ object construction mechanism). +struct c + #define BASES private boost::contract::constructor_precondition<c>, \ + public t<'d'>, protected t<'p'>, private t<'q'>, public t<'e'> + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { + out << "c::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(m.value >= 0); + } + + void invariant() const { + out << "c::inv" << std::endl; + BOOST_CONTRACT_ASSERT(j_ < 0); + } + + struct m_tag; + typedef boost::contract::test::detail::counter<m_tag, int> m_type; + static m_type m; + + struct y_tag; + typedef boost::contract::test::detail::counter<y_tag, int> y_type; + + explicit c(y_type& y, t<'d'>::z_type& dz, t<'p'>::z_type& pz, + t<'q'>::z_type& qz, t<'e'>::z_type& ez) : + boost::contract::constructor_precondition<c>([&] { + out << "c::ctor::pre" << std::endl; + BOOST_CONTRACT_ASSERT(y.value < 0); + }), + t<'d'>(dz), t<'p'>(pz), t<'q'>(qz), t<'e'>(ez) + { + boost::contract::old_ptr<y_type> old_y = + BOOST_CONTRACT_OLDOF(y_type::eval(y)); + boost::contract::old_ptr<m_type> old_m; + boost::contract::check c = boost::contract::constructor(this) + .old([&] { + out << "c::ctor::old" << std::endl; + old_m = BOOST_CONTRACT_OLDOF(m_type::eval(m)); + }) + .postcondition([&] { + out << "c::ctor::post" << std::endl; + BOOST_CONTRACT_ASSERT(j_ == old_y->value); + BOOST_CONTRACT_ASSERT(y.value == m.value); + BOOST_CONTRACT_ASSERT(m.value == old_m->value + 1); + }) + ; + out << "c::ctor::body" << std::endl; + j_ = y.value; + y.value = ++m.value; + } + + virtual ~c() { --m.value; } + +private: + int j_; +}; +c::m_type c::m; + +// Test not (fully) contracted base is not part of constructor subcontracting. +struct b + #define BASES private boost::contract::constructor_precondition<b> + : 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; } + + explicit b() {} // No contract. + virtual ~b() {} +}; + +// Test constructor with both non-contracted and contracted bases. +struct a + #define BASES private boost::contract::constructor_precondition<a>, \ + public b, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { + out << "a::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(n.value >= 0); + } + + void invariant() const { + out << "a::inv" << std::endl; + BOOST_CONTRACT_ASSERT(i_ < 0); + } + + struct n_tag; + typedef boost::contract::test::detail::counter<n_tag, int> n_type; + static n_type n; + + struct x_tag; + typedef boost::contract::test::detail::counter<x_tag, int> x_type; + + explicit a(x_type& x, c::y_type& y, t<'d'>::z_type& dz, + t<'p'>::z_type& pz, t<'q'>::z_type& qz, t<'e'>::z_type& ez) : + boost::contract::constructor_precondition<a>([&] { + out << "a::ctor::pre" << std::endl; + BOOST_CONTRACT_ASSERT(x.value < 0); + }), + b(), c(y, dz, pz, qz, ez) + { + boost::contract::old_ptr<x_type> old_x; + boost::contract::old_ptr<n_type> old_n = + BOOST_CONTRACT_OLDOF(n_type::eval(n)); + boost::contract::check c = boost::contract::constructor(this) + .old([&] { + out << "a::ctor::old" << std::endl; + old_x = BOOST_CONTRACT_OLDOF(x_type::eval(x)); + }) + .postcondition([&] { + out << "a::ctor::post" << std::endl; + BOOST_CONTRACT_ASSERT(i_ == old_x->value); + BOOST_CONTRACT_ASSERT(x.value == n.value); + BOOST_CONTRACT_ASSERT(n.value == old_n->value + 1); + }) + ; + out << "a::ctor::body" << std::endl; + i_ = x.value; + x.value = ++n.value; + } + + virtual ~a() { --n.value; } + +private: + int i_; +}; +a::n_type a::n; + +int main() { + std::ostringstream ok; + + { + t<'e'>::z_type ez; ez.value = -5; + t<'q'>::z_type qz; qz.value = -5; + t<'p'>::z_type pz; pz.value = -4; + t<'d'>::z_type dz; dz.value = -3; + c::y_type y; y.value = -2; + a::x_type x; x.value = -1; + + out.str(""); + a aa(x, y, dz, pz, qz, ez); + ok.str(""); ok + // Test all constructor pre checked first. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + // Test static inv, but not const inv, checked before ctor body. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::ctor::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::ctor::old" << std::endl + #endif + << "d::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::ctor::post" << std::endl + #endif + + // Test check also protected bases (because part of C++ constr.). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "p::ctor::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "p::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "p::ctor::old" << std::endl + #endif + << "p::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "p::static_inv" << std::endl + << "p::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "p::ctor::post" << std::endl + #endif + + // Test check also private bases (because part of C++ constr.). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "q::ctor::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "q::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "q::ctor::old" << std::endl + #endif + << "q::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "q::static_inv" << std::endl + << "q::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "q::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "e::ctor::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "e::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "e::ctor::old" << std::endl + #endif + << "e::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "e::static_inv" << std::endl + << "e::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "e::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::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 + + std::clog << a::x_type::copies() << std::endl; + std::clog << BOOST_CONTRACT_TEST_old << std::endl; + BOOST_TEST_EQ(a::x_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a::x_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a::x_type::ctors(), a::x_type::dtors()); // No leak. + + BOOST_TEST_EQ(c::y_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::y_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::y_type::ctors(), c::y_type::dtors()); // No leak. + + BOOST_TEST_EQ(t<'d'>::z_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'d'>::z_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'d'>::z_type::ctors(), t<'d'>::z_type::dtors()); // No leak. + + BOOST_TEST_EQ(t<'p'>::z_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'p'>::z_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'p'>::z_type::ctors(), t<'p'>::z_type::dtors()); // No leak. + + BOOST_TEST_EQ(t<'q'>::z_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'q'>::z_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'q'>::z_type::ctors(), t<'q'>::z_type::dtors()); // No leak. + + BOOST_TEST_EQ(t<'e'>::z_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::z_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::z_type::ctors(), t<'e'>::z_type::dtors()); // No leak. + + // Following destroy only copies (actual objects are static data members). + + BOOST_TEST_EQ(a::n_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a::n_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a::n_type::copies(), a::n_type::dtors()); // No leak. + + BOOST_TEST_EQ(c::m_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::m_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::m_type::copies(), c::m_type::dtors()); // No leak. + + BOOST_TEST_EQ(t<'d'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'d'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::copies(), t<'e'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'p'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'p'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::copies(), t<'e'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'q'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'q'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::copies(), t<'e'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'e'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::copies(), t<'e'>::l_type::dtors()); // No leak + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/constructor/throwing_body.cpp b/src/boost/libs/contract/test/constructor/throwing_body.cpp new file mode 100644 index 00000000..cb385eb7 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/throwing_body.cpp @@ -0,0 +1,145 @@ + +// 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 form constructor body (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/constructor.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 c + #define BASES private boost::contract::constructor_precondition<c> + : 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; } + + c() : + boost::contract::constructor_precondition<c>([] { + out << "c::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "c::ctor::old" << std::endl; }) + .postcondition([] { out << "c::ctor::post" << std::endl; }) + .except([] { out << "c::ctor::except" << std::endl; }) + ; + out << "c::ctor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES private boost::contract::constructor_precondition<b>, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + b() : + boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "b::ctor::old" << std::endl; }) + .postcondition([] { out << "b::ctor::post" << std::endl; }) + .except([] { out << "b::ctor::except" << std::endl; }) + ; + out << "b::ctor::body" << std::endl; + throw b_err(); // Test body throws (from inheritance mid branch). + } +}; + +struct a + #define BASES private boost::contract::constructor_precondition<a>, public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + a() : + boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "a::ctor::old" << std::endl; }) + .postcondition([] { out << "a::ctor::post" << std::endl; }) + .except([] { out << "a::ctor::except" << std::endl; }) + ; + out << "a::ctor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + try { + out.str(""); + a aa; + BOOST_TEST(false); + } catch(b_err const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl // Test this threw... + // ... so check only following after (no post, no a ctor, etc.). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "b::ctor::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/constructor/throwing_old.cpp b/src/boost/libs/contract/test/constructor/throwing_old.cpp new file mode 100644 index 00000000..432641e1 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/throwing_old.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 throw form constructor .old() (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/constructor.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 c + #define BASES private boost::contract::constructor_precondition<c> + : 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; } + + c() : + boost::contract::constructor_precondition<c>([] { + out << "c::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "c::ctor::old" << std::endl; }) + .postcondition([] { out << "c::ctor::post" << std::endl; }) + .except([] { out << "c::ctor::except" << std::endl; }) + ; + out << "c::ctor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES private boost::contract::constructor_precondition<b>, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + b() : + boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { + out << "b::ctor::old" << std::endl; + throw b_err(); // Test this throws (from mid branch). + }) + .postcondition([] { out << "b::ctor::post" << std::endl; }) + .except([] { out << "b::ctor::except" << std::endl; }) + ; + out << "b::ctor::body" << std::endl; + } +}; + +struct a + #define BASES private boost::contract::constructor_precondition<a>, public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + a() : + boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "a::ctor::old" << std::endl; }) + .postcondition([] { out << "a::ctor::post" << std::endl; }) + .except([] { out << "a::ctor::except" << std::endl; }) + ; + out << "a::ctor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_old_failure([] (boost::contract::from) { throw; }); + + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(false); + } catch(b_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl // Test this threw. + #else + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "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/constructor/throwing_post.cpp b/src/boost/libs/contract/test/constructor/throwing_post.cpp new file mode 100644 index 00000000..beaa31ac --- /dev/null +++ b/src/boost/libs/contract/test/constructor/throwing_post.cpp @@ -0,0 +1,164 @@ + +// 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 form constructor .post() (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/constructor.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 c + #define BASES private boost::contract::constructor_precondition<c> + : 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; } + + c() : + boost::contract::constructor_precondition<c>([] { + out << "c::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "c::ctor::old" << std::endl; }) + .postcondition([] { out << "c::ctor::post" << std::endl; }) + .except([] { out << "c::ctor::except" << std::endl; }) + ; + out << "c::ctor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES private boost::contract::constructor_precondition<b>, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + b() : + boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "b::ctor::old" << std::endl; }) + .postcondition([] { + out << "b::ctor::post" << std::endl; + throw b_err(); // Test this throws (from mid branch). + }) + .except([] { out << "b::ctor::except" << std::endl; }) + ; + out << "b::ctor::body" << std::endl; + } +}; + +struct a + #define BASES private boost::contract::constructor_precondition<a>, public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + a() : + boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "a::ctor::old" << std::endl; }) + .postcondition([] { out << "a::ctor::post" << std::endl; }) + .except([] { out << "a::ctor::except" << std::endl; }) + ; + out << "a::ctor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw; }); + + try { + out.str(""); + a aa; + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(b_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + << "c::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl // Test this threw. + #else + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "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/constructor/throwing_pre.cpp b/src/boost/libs/contract/test/constructor/throwing_pre.cpp new file mode 100644 index 00000000..e06a8542 --- /dev/null +++ b/src/boost/libs/contract/test/constructor/throwing_pre.cpp @@ -0,0 +1,164 @@ + +// 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 form constructor .pre() (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/constructor.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 c + #define BASES private boost::contract::constructor_precondition<c> + : 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; } + + c() : + boost::contract::constructor_precondition<c>([] { + out << "c::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "c::ctor::old" << std::endl; }) + .postcondition([] { out << "c::ctor::post" << std::endl; }) + .except([] { out << "c::ctor::except" << std::endl; }) + ; + out << "c::ctor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES private boost::contract::constructor_precondition<b>, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + b() : + boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + throw b_err(); // Test this throws (from mid branch). + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "b::ctor::old" << std::endl; }) + .postcondition([] { out << "b::ctor::post" << std::endl; }) + .except([] { out << "b::ctor::except" << std::endl; }) + ; + out << "b::ctor::body" << std::endl; + } +}; + +struct a + #define BASES private boost::contract::constructor_precondition<a>, public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + a() : + boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + }) + { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "a::ctor::old" << std::endl; }) + .postcondition([] { out << "a::ctor::post" << std::endl; }) + .except([] { out << "a::ctor::except" << std::endl; }) + ; + out << "a::ctor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw; }); + + try { + out.str(""); + a aa; +#ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(b_err const&) { +#endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl // Test this threw. + #else + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::ctor::old" << std::endl + #endif + << "c::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::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::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::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::ctor::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/destructor/access.cpp b/src/boost/libs/contract/test/destructor/access.cpp new file mode 100644 index 00000000..757248e6 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/access.cpp @@ -0,0 +1,122 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test making all contract extra declarations (base types, inv, etc.) private. + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +class b { + friend class boost::contract::access; + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + +public: + virtual ~b() { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + } +}; + +class a + #define BASES public b + : BASES +{ + friend class boost::contract::access; + + // Private base types (always OK because never used by dtors). + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + // Private invariants. + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + +public: + virtual ~a() { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + { + a aa; + out.str(""); + } // Call aa's destructor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + { + b bb; + out.str(""); + } // Call bb's destructor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl.hpp b/src/boost/libs/contract/test/destructor/decl.hpp new file mode 100644 index 00000000..8fdc8c3d --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl.hpp @@ -0,0 +1,145 @@ + +#ifndef BOOST_CONTRACT_TEST_DESTRUCTOR_DECL_HPP_ +#define BOOST_CONTRACT_TEST_DESTRUCTOR_DECL_HPP_ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test with and without pre, post, and inv declarations. + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/config.hpp> + +boost::contract::test::detail::oteststream out; + +bool c_pre = true, c_post = true; +bool c_entering_static_inv = true, c_entry_static_inv = true, + c_exit_static_inv = true; +bool c_entry_inv = true; // Only entry non-static inv for dtors. +struct c { + #ifndef BOOST_CONTRACT_TEST_NO_C_STATIC_INV + static void static_invariant() { + out << "c::static_inv" << std::endl; + if(c_entering_static_inv) BOOST_CONTRACT_ASSERT(c_entry_static_inv); + else BOOST_CONTRACT_ASSERT(c_exit_static_inv); + c_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_C_INV + void invariant() const { + out << "c::inv" << std::endl; + BOOST_CONTRACT_ASSERT(c_entry_inv); + } + #endif + + virtual ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + #ifdef BOOST_CONTRACT_TEST_NO_C_PRE + #error "destructors cannot have preconditions" + #endif + .old([] { out << "c::dtor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_C_POST + .postcondition([] { + out << "c::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(c_post); + }) + #endif + ; + out << "c::dtor::body" << std::endl; + } +}; + +bool b_pre = true, b_post = true; +bool b_entering_static_inv = true, b_entry_static_inv = true, + b_exit_static_inv = true; +bool b_entry_inv = true; // Only entry non-static inv for dtors. +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + #ifndef BOOST_CONTRACT_TEST_NO_B_STATIC_INV + static void static_invariant() { + out << "b::static_inv" << std::endl; + if(b_entering_static_inv) BOOST_CONTRACT_ASSERT(b_entry_static_inv); + else BOOST_CONTRACT_ASSERT(b_exit_static_inv); + b_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_B_INV + void invariant() const { + out << "b::inv" << std::endl; + BOOST_CONTRACT_ASSERT(b_entry_inv); + } + #endif + + virtual ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + #ifdef BOOST_CONTRACT_TEST_NO_B_PRE + #error "destructors cannot have preconditions" + #endif + .old([] { out << "b::dtor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_B_POST + .postcondition([] { + out << "b::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(b_post); + }) + #endif + ; + out << "b::dtor::body" << std::endl; + } +}; + +bool a_pre = true, a_post = true; +bool a_entering_static_inv = true, a_entry_static_inv = true, + a_exit_static_inv = true; +bool a_entry_inv = true; // Only entry non-static inv for dtors. +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + #ifndef BOOST_CONTRACT_TEST_NO_A_STATIC_INV + static void static_invariant() { + out << "a::static_inv" << std::endl; + if(a_entering_static_inv) BOOST_CONTRACT_ASSERT(a_entry_static_inv); + else BOOST_CONTRACT_ASSERT(a_exit_static_inv); + a_entering_static_inv = false; + } + #endif + #ifndef BOOST_CONTRACT_TEST_NO_A_INV + void invariant() const { + out << "a::inv" << std::endl; + BOOST_CONTRACT_ASSERT(a_entry_inv); + } + #endif + + virtual ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + #ifdef BOOST_CONTRACT_TEST_NO_A_PRE + #error "destructors cannot have preconditions" + #endif + .old([] { out << "a::dtor::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_A_POST + .postcondition([] { + out << "a::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(a_post); + }) + #endif + ; + out << "a::dtor::body" << std::endl; + } +}; + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_all.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_all.cpp new file mode 100644 index 00000000..39395c7a --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_all.cpp @@ -0,0 +1,222 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with entry static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_INV +#undef BOOST_CONTRACT_TEST_NO_B_INV +#undef BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl // This can fail. + #endif + ; + if(!failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_b(checked check = passed) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl // This can fail. + #endif + ; + if(check != failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (check == threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // This can fail. + #endif + ; + if(check != failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + // Test entry a::inv failed... + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test entry b::inv failed... + << ok_b(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test entry c::inv failed... + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple except, + // just ignore failure and continue test program (for testing only). + }); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test entry a::inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::dtor::body" << std::endl + #endif + + // Test entry b::inv failed (as all did). + << ok_b(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::dtor::body" << std::endl + #endif + + // Test entry c::inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::dtor::body" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_ends.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_ends.cpp new file mode 100644 index 00000000..f7cee609 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_ends.cpp @@ -0,0 +1,206 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with entry invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_INV +#define BOOST_CONTRACT_TEST_NO_B_INV +#undef BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl // This can fail. + #endif + ; + if(!failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + // No b::inv here (not even when threw). + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl // This can fail. + #endif + ; + if(check != failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // for testing (as dtors should never throw anyways). + }); + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + // Test entry a::inv failed... + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv) + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no entry b::inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test entry c::inv failed... + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test entry a::inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_entry_inv) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::dtor::body" << std::endl + #endif + + << ok_b() // Test no entry b::inv so no failure here. + + // Test entry c::inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_entry_inv ? failed : passed) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::dtor::body" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_mid.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_mid.cpp new file mode 100644 index 00000000..247d68ce --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_mid.cpp @@ -0,0 +1,194 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with entry invariants. + +#define BOOST_CONTRACT_TEST_NO_A_INV +#undef BOOST_CONTRACT_TEST_NO_B_INV +#define BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool failed = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl // This can fail. + #endif + ; + if(!failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + // No b::inv here (not even when threw). + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // for testing (as dtors should never throw anyways). + }); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no entry a::inv so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 2 + #endif + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test entry b::inv failed... + << ok_b(bool(BOOST_CONTRACT_TEST_entry_inv)) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(bool(BOOST_CONTRACT_TEST_entry_inv)) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test no entry c::inv so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no entry a::inv so no failure here. + + // Test entry b::inv failed (as all did). + << ok_b(bool(BOOST_CONTRACT_TEST_entry_inv)) + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::dtor::body" << std::endl + #endif + + << ok_c() // Test no entry c::inv so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_inv_none.cpp b/src/boost/libs/contract/test/destructor/decl_entry_inv_none.cpp new file mode 100644 index 00000000..342a7893 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_inv_none.cpp @@ -0,0 +1,109 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without entry invariants. + +#define BOOST_CONTRACT_TEST_NO_A_INV +#define BOOST_CONTRACT_TEST_NO_B_INV +#define BOOST_CONTRACT_TEST_NO_C_INV +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + ; + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = false; + b_entry_inv = true; + c_entry_inv = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = false; + c_entry_inv = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = true; + b_entry_inv = true; + c_entry_inv = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_inv = false; + b_entry_inv = false; + c_entry_inv = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_all.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_all.cpp new file mode 100644 index 00000000..34476bb8 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_all.cpp @@ -0,0 +1,231 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with entry static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed... + #else + << ok_a() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv) + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl // Test this failed... + #else + << ok_b() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // Test this failed... + #else + << ok_c() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed (as all did)... + << "a::dtor::body" << std::endl + + << "b::static_inv" << std::endl // Test this failed (as all did)... + << "b::dtor::body" << std::endl + + << "c::static_inv" << std::endl // Test this failed (as all did)... + << "c::dtor::body" << std::endl + #else + << ok_a() + << ok_b() + << ok_c() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_ends.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_ends.cpp new file mode 100644 index 00000000..11bb1ced --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_ends.cpp @@ -0,0 +1,216 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with entry static inv. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed... + #else + << ok_a() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_entry_inv) + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no b::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl // Test this failed... + #else + << ok_c() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program. + }); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl // Test this failed (as all did). + << "a::dtor::body" << std::endl + + << ok_b() // Test no b::static_inv so no failure here. + + << "c::static_inv" << std::endl // Test this failed (as all did). + << "c::dtor::body" << std::endl + #else + << ok_a() + << ok_b() + << ok_c() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_mid.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_mid.cpp new file mode 100644 index 00000000..6f813212 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_mid.cpp @@ -0,0 +1,203 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with entry static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_entry_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (dtors should never throw otherwise). + }); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no a::static_inv so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl // Test this failed... + #else + << ok_b() + #endif + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_entry_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test no c::static_inv so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_entry_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << ok_a() // Test no a::static_inv so no failure here. + + << "b::static_inv" << std::endl // Test this failed (as all did)... + << "b::dtor::body" << std::endl + + << ok_c() // Test no c::static_inv so no failure here. + #else + << ok_a() + << ok_b() + << ok_c() + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_entry_static_inv_none.cpp b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_none.cpp new file mode 100644 index 00000000..acc7b682 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_entry_static_inv_none.cpp @@ -0,0 +1,118 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without entry static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + ; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = false; + b_entry_static_inv = true; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = true; + b_entry_static_inv = false; + c_entry_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = true; + b_entry_static_inv = true; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_entry_static_inv = false; + b_entry_static_inv = false; + c_entry_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_all.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_all.cpp new file mode 100644 index 00000000..4cb68fea --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_all.cpp @@ -0,0 +1,222 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with exit static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl // This can fail. + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!failed ? "a::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_b(checked check = passed) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl // This can fail. + << (check == threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // This can fail. + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #define BOOST_CONTRACT_TEST_exit_inv 0 + #else + #define BOOST_CONTRACT_TEST_exit_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (as dtors should not throw otherwise). + }); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + // Test a::static_inv failed... + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test b::static_inv failed... + << ok_b(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test exit c::static_inv failed. + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ... then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_exit_invariant_failure([] (boost::contract::from) { + // Testing multiple failures but dtors must not throw multiple except, + // just ignore failure and continue test program (for testing only). + }); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test exit a::static_inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + // Test exit b::static_inv failed (as all did). + << ok_b(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + // Test exit c::static_inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + #undef BOOST_CONTRACT_TEST_exit_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_ends.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_ends.cpp new file mode 100644 index 00000000..cbce7514 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_ends.cpp @@ -0,0 +1,211 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with exit static invariants. + +#undef BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a(bool failed = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl // This can fail. + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!failed ? "a::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +enum checked { passed, failed, threw }; + +std::string ok_c(checked check = passed) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl // This can fail. + << (check == threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (check == passed ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #define BOOST_CONTRACT_TEST_exit_inv 0 + #else + #define BOOST_CONTRACT_TEST_exit_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (as dtors should not throw otherwise). + }); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + // Test a::static_inv failed... + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_exit_inv) + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? threw : passed) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no exit b::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + // Test c::static_inv failed... + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_exit_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple + // exceptions, just ignore failure and continue test program... + }); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test a::static_inv failed (as all did). + << ok_a(BOOST_CONTRACT_TEST_exit_inv) + // Test no exit b::static_inv so no failure here. + << ok_b() + // Test c::static_inv failed (as all did). + << ok_c(BOOST_CONTRACT_TEST_exit_inv ? failed : passed) + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + #undef BOOST_CONTRACT_TEST_exit_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_mid.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_mid.cpp new file mode 100644 index 00000000..bd5cce64 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_mid.cpp @@ -0,0 +1,203 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with exit static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#undef BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b(bool failed = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl // This can fail. + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!failed ? "b::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + #ifdef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #define BOOST_CONTRACT_TEST_exit_inv 0 + #else + #define BOOST_CONTRACT_TEST_exit_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_exit_invariant_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws. + throw err(); // For testing only (as dtors should not throw otherwise). + }); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no exit a::static_inv so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); ok + << ok_a() + // Test exit b::static_inv failed... + << ok_b(BOOST_CONTRACT_TEST_exit_inv) + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_exit_inv) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + try { + { + a aa; + ok.str(""); + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + // Test no exit c::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + boost::contract::set_exit_invariant_failure([] (boost::contract::from) { + // Testing multiple failures so dtors must not throw multiple except, + // just ignore failure and continue test program (for testing only). + }); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + ok.str(""); ok + // Test no exit a::static_inv so no faliure here. + << ok_a() + // Test exit b::static_inv failed (as all did). + << ok_b(BOOST_CONTRACT_TEST_exit_inv) + // Test no exit c::static_inv so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + #undef BOOST_CONTRACT_TEST_exit_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_exit_static_inv_none.cpp b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_none.cpp new file mode 100644 index 00000000..0d572adb --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_exit_static_inv_none.cpp @@ -0,0 +1,118 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without exit static invariants. + +#define BOOST_CONTRACT_TEST_NO_A_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_B_STATIC_INV +#define BOOST_CONTRACT_TEST_NO_C_STATIC_INV +#include "decl.hpp" + +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + ; + + #ifdef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #define BOOST_CONTRACT_TEST_entry_inv 0 + #else + #define BOOST_CONTRACT_TEST_entry_inv 1 + #endif + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = false; + b_exit_static_inv = true; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = true; + b_exit_static_inv = false; + c_exit_static_inv = true; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = true; + b_exit_static_inv = true; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_exit_static_inv = false; + b_exit_static_inv = false; + c_exit_static_inv = false; + a_entering_static_inv = b_entering_static_inv = c_entering_static_inv = + BOOST_PP_IIF(BOOST_CONTRACT_TEST_entry_inv, true, false); + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + #undef BOOST_CONTRACT_TEST_entry_inv + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_all.cpp b/src/boost/libs/contract/test/destructor/decl_post_all.cpp new file mode 100644 index 00000000..8617b478 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_all.cpp @@ -0,0 +1,200 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes with postconditions. + +#undef BOOST_CONTRACT_TEST_NO_A_POST +#undef BOOST_CONTRACT_TEST_NO_B_POST +#undef BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (threw ? "b::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "b::dtor::post\n" : "") // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") // This can fail. + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // for testing (as dtors should never throw anyways). + }); + + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + #define BOOST_CONTRACT_TEST_post 0 + #else + #define BOOST_CONTRACT_TEST_post 1 + #endif + + a_post = false; + b_post = true; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() // Test b::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test c::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ...then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed... + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ...then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_post + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_ends.cpp b/src/boost/libs/contract/test/destructor/decl_post_ends.cpp new file mode 100644 index 00000000..942d2ed9 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_ends.cpp @@ -0,0 +1,191 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only derived and grandparent classes (ends) with postconditions. + +#undef BOOST_CONTRACT_TEST_NO_A_POST +#define BOOST_CONTRACT_TEST_NO_B_POST +#undef BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_b(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << (threw ? "b::inv\n" : "") + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << (!threw ? "c::dtor::post\n" : "") // This can fail. + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // ... for testing (as dtors should never throw anyways). + }); + + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + #define BOOST_CONTRACT_TEST_post 0 + #else + #define BOOST_CONTRACT_TEST_post 1 + #endif + + a_post = false; + b_post = true; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = false; + c_post = true; + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() // Test no b::dtor::post so no failure here. + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test c::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + // ... then exec other dtors and check inv on throw (as dtor threw). + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() // Test a::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_b(BOOST_CONTRACT_TEST_post) + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_post + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_mid.cpp b/src/boost/libs/contract/test/destructor/decl_post_mid.cpp new file mode 100644 index 00000000..54197b1a --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_mid.cpp @@ -0,0 +1,182 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test only middle base class with postconditions. + +#define BOOST_CONTRACT_TEST_NO_A_POST +#undef BOOST_CONTRACT_TEST_NO_B_POST +#define BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_a() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + ; + return ok.str(); +} + +std::string ok_b() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +std::string ok_c(bool threw = false) { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << (threw ? "c::inv\n" : "") + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + ok.str(""); ok // Test nothing failed. + << ok_a() + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure([&ok] (boost::contract::from) { + BOOST_TEST(out.eq(ok.str())); // Must check before dtor throws... + throw err(); // ... for testing (as dtors should never throw anyways). + }); + + a_post = false; + b_post = true; + c_post = true; + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() // Test no a::dtor::post so no failure here. + << ok_b() + << ok_c() + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #ifdef BOOST_CONTRACT_NO_POSTCONDITIONS + #define BOOST_CONTRACT_TEST_post 0 + #else + #define BOOST_CONTRACT_TEST_post 1 + #endif + + a_post = true; + b_post = false; + c_post = true; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() // Test b::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = true; + b_post = true; + c_post = false; + try { + { + a aa; + out.str(""); + } + ok.str(""); ok + << ok_a() + << ok_b() + << ok_c() // Test no c::dtor::post so no failure here. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + a_post = false; + b_post = false; + c_post = false; + try { + { + a aa; + ok.str(""); ok + << ok_a() + << ok_b() // Test b::dtor::post failed. + ; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok // ... then exec other dtors and check inv on throw (as dtor threw). + << ok_c(BOOST_CONTRACT_TEST_post) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_post + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/decl_post_none.cpp b/src/boost/libs/contract/test/destructor/decl_post_none.cpp new file mode 100644 index 00000000..9b3eb4df --- /dev/null +++ b/src/boost/libs/contract/test/destructor/decl_post_none.cpp @@ -0,0 +1,103 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test all derived and base classes without postconditions. + +#define BOOST_CONTRACT_TEST_NO_A_POST +#define BOOST_CONTRACT_TEST_NO_B_POST +#define BOOST_CONTRACT_TEST_NO_C_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +int main() { + std::ostringstream ok; ok // Test nothing fails. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + ; + + a_post = true; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = false; + b_post = true; + c_post = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = true; + b_post = false; + c_post = true; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = true; + b_post = true; + c_post = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + a_post = false; + b_post = false; + c_post = false; + { + a aa; + out.str(""); + } + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/ifdef.cpp b/src/boost/libs/contract/test/destructor/ifdef.cpp new file mode 100644 index 00000000..53c4c89d --- /dev/null +++ b/src/boost/libs/contract/test/destructor/ifdef.cpp @@ -0,0 +1,111 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test contract compilation on/off. + +#include "../detail/oteststream.hpp" +#include <boost/contract/core/config.hpp> +#ifndef BOOST_CONTRACT_NO_DESTRUCTORS + #include <boost/contract/destructor.hpp> + #include <boost/contract/check.hpp> + #include <boost/contract/old.hpp> +#endif +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct b { + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + #endif + + virtual ~b() { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_y = BOOST_CONTRACT_OLDOF(y); + #endif + #ifndef BOOST_CONTRACT_NO_DESTRUCTORS + boost::contract::check c = boost::contract::destructor(this) + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + #endif + ; + #endif + out << "b::dtor::body" << std::endl; + } + + static int y; +}; +int b::y = 0; + +struct a : public b { + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + #endif + + virtual ~a() { + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + boost::contract::old_ptr<int> old_x = BOOST_CONTRACT_OLDOF(x); + #endif + #ifndef BOOST_CONTRACT_NO_DESTRUCTORS + boost::contract::check c = boost::contract::destructor(this) + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + #endif + ; + #endif + out << "a::dtor::body" << std::endl; + } + + static int x; +}; +int a::x = 0; + +int main() { + std::ostringstream ok; + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/ifdef_macro.cpp b/src/boost/libs/contract/test/destructor/ifdef_macro.cpp new file mode 100644 index 00000000..cc14b469 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/ifdef_macro.cpp @@ -0,0 +1,142 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test contract compilation on/off (using macro interface). + +#include "../detail/oteststream.hpp" +#include "../detail/unprotected_commas.hpp" +#include <boost/contract/core/config.hpp> +#include <boost/contract_macro.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct b { + BOOST_CONTRACT_STATIC_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "b::static_inv" << std::endl; + }) + + BOOST_CONTRACT_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "b::inv" << std::endl; + }) + + virtual ~b() { + BOOST_CONTRACT_OLD_PTR( + boost::contract::test::detail::unprotected_commas<int, void, + void>::type1 + )( + old_y, + (boost::contract::test::detail::unprotected_commas<void, void, + void>::same(y)) + ); + BOOST_CONTRACT_DESTRUCTOR(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "b::dtor::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "b::dtor::post" << std::endl; + }) + ; + out << "b::dtor::body" << std::endl; + } + + static int y; +}; +int b::y = 0; + +struct a : public b { + BOOST_CONTRACT_STATIC_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::static_inv" << std::endl; + }) + + BOOST_CONTRACT_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::inv" << std::endl; + }) + + virtual ~a() { + BOOST_CONTRACT_OLD_PTR( + boost::contract::test::detail::unprotected_commas<int, void, void>:: + type1 + )( + old_x, + (boost::contract::test::detail::unprotected_commas<void, void, + void>::same(x)) + ); + BOOST_CONTRACT_DESTRUCTOR(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::dtor::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + out << "a::dtor::post" << std::endl; + }) + ; + out << "a::dtor::body" << std::endl; + } + + static int x; +}; +int a::x = 0; + +int main() { + std::ostringstream ok; + { + a aa; + out.str(""); + } + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/pre_error.cpp b/src/boost/libs/contract/test/destructor/pre_error.cpp new file mode 100644 index 00000000..49b49e79 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/pre_error.cpp @@ -0,0 +1,24 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test destructor cannot use `.precondition(...)`. + +#include <boost/contract/destructor.hpp> +#include <boost/contract/check.hpp> + +struct a { + ~a() { + boost::contract::check c = boost::contract::destructor(this) + .precondition([] {}) // Error (no dtor func arg so never pre). + ; + } +}; + +int main() { + a aa; + return 0; +} + diff --git a/src/boost/libs/contract/test/destructor/smoke.cpp b/src/boost/libs/contract/test/destructor/smoke.cpp new file mode 100644 index 00000000..d1a9e18a --- /dev/null +++ b/src/boost/libs/contract/test/destructor/smoke.cpp @@ -0,0 +1,306 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test destructor subcontracting. + +#include "../detail/oteststream.hpp" +#include "../detail/counter.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +template<char Id> +struct t { + static void static_invariant() { + out << Id << "::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(l.value >= 0); + } + + void invariant() const { + out << Id << "::inv" << std::endl; + BOOST_CONTRACT_ASSERT(k_ < 0); + } + + struct l_tag; + typedef boost::contract::test::detail::counter<l_tag, int> l_type; + static l_type l; + + explicit t() : k_(-1) { ++l.value; } + + virtual ~t() { + boost::contract::old_ptr<l_type> old_l; + boost::contract::check c = boost::contract::destructor(this) + .old([&] { + out << Id << "::dtor::old" << std::endl; + old_l = BOOST_CONTRACT_OLDOF(l_type::eval(l)); + }) + .postcondition([&old_l] { + out << Id << "::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(t<Id>::l.value == old_l->value - 1); + }) + ; + out << Id << "::dtor::body" << std::endl; + --l.value; + } + +private: + int k_; +}; +template<char Id> typename t<Id>::l_type t<Id>::l; + +// Test deep inheritance (2 vertical levels), multiple inheritance (4 +// horizontal levels), and that all public/protected/private part of +// subcontracting for destructors (not just public, because all access levels +// are part of C++ object destruction mechanism). +struct c + #define BASES public t<'d'>, protected t<'p'>, private t<'q'>, public t<'e'> + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { + out << "c::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(m.value >= 0); + } + + void invariant() const { + out << "c::inv" << std::endl; + BOOST_CONTRACT_ASSERT(j_ < 0); + } + + struct m_tag; + typedef boost::contract::test::detail::counter<m_tag, int> m_type; + static m_type m; + + explicit c() : j_(-1) { ++m.value; } + + virtual ~c() { + boost::contract::old_ptr<m_type> old_m = + BOOST_CONTRACT_OLDOF(m_type::eval(m)); + boost::contract::check c = boost::contract::destructor(this) + .old([] { + out << "c::dtor::old" << std::endl; + // Test old-of assignment above instead. + }) + .postcondition([&old_m] { + out << "c::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(c::m.value == old_m->value - 1); + }) + ; + out << "c::dtor::body" << std::endl; + --m.value; + } + +private: + int j_; +}; +c::m_type c::m; + +// Test not (fully) contracted base is not part of destructor subcontracting. +struct b { + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + explicit b() {} + virtual ~b() {} // No contract. +}; + +struct a_n_tag; // Global decl so visible in MSVC10 lambdas. +typedef boost::contract::test::detail::counter<a_n_tag, int> a_n_type; + +// Test destructor with both non-contracted and contracted bases. +struct a + #define BASES public b, public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { + out << "a::static_inv" << std::endl; + BOOST_CONTRACT_ASSERT(n.value >= 0); + } + + void invariant() const { + out << "a::inv" << std::endl; + BOOST_CONTRACT_ASSERT(i_ < 0); + } + + static a_n_type n; + + explicit a() : i_(-1) { + ++i_; --i_; // To avoid a warning when all contracts off. + ++n.value; + } + + virtual ~a() { + boost::contract::old_ptr<a_n_type> old_n; + boost::contract::check c = boost::contract::destructor(this) + .old([&] { + out << "a::dtor::old" << std::endl; + old_n = BOOST_CONTRACT_OLDOF(a_n_type::eval(n)); + }) + .postcondition([&old_n] { + out << "a::dtor::post" << std::endl; + BOOST_CONTRACT_ASSERT(a::n.value == old_n->value - 1); + }) + ; + out << "a::dtor::body" << std::endl; + --n.value; + } + +private: + int i_; +}; +a_n_type a::n; + +int main() { + std::ostringstream ok; + + { + a aa; + out.str(""); + } // Call aa's destructor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + // Test static inv, but not const inv, checked after destructor body. + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "c::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "e::static_inv" << std::endl + << "e::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "e::dtor::old" << std::endl + #endif + << "e::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "e::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "e::dtor::post" << std::endl + #endif + + // Test check also private bases (because part of C++ destruction). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "q::static_inv" << std::endl + << "q::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "q::dtor::old" << std::endl + #endif + << "q::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "q::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "q::dtor::post" << std::endl + #endif + + // Test check also protected bases (because part of C++ destruction). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "p::static_inv" << std::endl + << "p::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "p::dtor::old" << std::endl + #endif + << "p::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "p::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "p::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::dtor::old" << std::endl + #endif + << "d::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + #ifndef BOOST_CONTRACT_NO_OLDS + #define BOOST_CONTRACT_TEST_old 1u + #else + #define BOOST_CONTRACT_TEST_old 0u + #endif + + // Followings destroy only copies (actual objects are static data members). + + BOOST_TEST_EQ(a_n_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a_n_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a_n_type::copies(), a_n_type::dtors()); // No leak. + + BOOST_TEST_EQ(c::m_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::m_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(c::m_type::copies(), c::m_type::dtors()); // No leak. + + BOOST_TEST_EQ(t<'d'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'d'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'d'>::l_type::copies(), t<'d'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'p'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'p'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'p'>::l_type::copies(), t<'p'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'q'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'q'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'q'>::l_type::copies(), t<'q'>::l_type::dtors()); // No leak + + BOOST_TEST_EQ(t<'e'>::l_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(t<'e'>::l_type::copies(), t<'e'>::l_type::dtors()); // No leak + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/throwing_body.cpp b/src/boost/libs/contract/test/destructor/throwing_body.cpp new file mode 100644 index 00000000..f14612ed --- /dev/null +++ b/src/boost/libs/contract/test/destructor/throwing_body.cpp @@ -0,0 +1,144 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test throw from destructor body (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "c::dtor::old" << std::endl; }) + .postcondition([] { out << "c::dtor::post" << std::endl; }) + .except([] { out << "c::dtor::except" << std::endl; }) + ; + out << "c::dtor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + .except([] { out << "b::dtor::except" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + throw b_err(); // Test body throw (from inheritance mid branch). + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + .except([] { out << "a::dtor::except" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + try { + { + a aa; + out.str(""); + } + BOOST_TEST(false); + } catch(b_err const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + // Test a destructed (so only static_inv and post, but no inv). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl // Test this threw. + // Test b not destructed (so static_inv, inv, and except, no post). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "b::dtor::except" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + // Test c not destructed (so static_inv, inv, and except, no post). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "c::dtor::except" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/throwing_old.cpp b/src/boost/libs/contract/test/destructor/throwing_old.cpp new file mode 100644 index 00000000..cdfc13bc --- /dev/null +++ b/src/boost/libs/contract/test/destructor/throwing_old.cpp @@ -0,0 +1,150 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test throw from destructor .old() (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "c::dtor::old" << std::endl; }) + .postcondition([] { out << "c::dtor::post" << std::endl; }) + .except([] { out << "c::dtor::except" << std::endl; }) + ; + out << "c::dtor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { + out << "b::dtor::old" << std::endl; + throw b_err(); // Test this throws (from mid branch). + }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + .except([] { out << "b::dtor::except" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + .except([] { out << "a::dtor::except" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_old_failure([] (boost::contract::from) { throw; }); + + try { + { + a aa; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(false); + } catch(b_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + // Test a destructed (so only static_inv and post, but no inv). + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl // Test this threw. + #else + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + // Test c not destructed (so both inv and except). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "c::dtor::except" << std::endl + #endif + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/destructor/throwing_post.cpp b/src/boost/libs/contract/test/destructor/throwing_post.cpp new file mode 100644 index 00000000..83186493 --- /dev/null +++ b/src/boost/libs/contract/test/destructor/throwing_post.cpp @@ -0,0 +1,153 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test throw from destructor .post() (in middle branch of inheritance tree). + +#include "../detail/oteststream.hpp" +#include <boost/contract/destructor.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> +#include <boost/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct c { + static void static_invariant() { out << "c::static_inv" << std::endl; } + void invariant() const { out << "c::inv" << std::endl; } + + ~c() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "c::dtor::old" << std::endl; }) + .postcondition([] { out << "c::dtor::post" << std::endl; }) + .except([] { out << "c::dtor::except" << std::endl; }) + ; + out << "c::dtor::body" << std::endl; + // Do not throw (from inheritance root). + } +}; + +struct b_err {}; // Global decl so visible in MSVC10 lambdas. + +struct b + #define BASES public c + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "b::static_inv" << std::endl; } + void invariant() const { out << "b::inv" << std::endl; } + + ~b() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { + out << "b::dtor::post" << std::endl; + throw b_err(); // Test this throws (from mid branch). + }) + .except([] { out << "b::dtor::except" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + static void static_invariant() { out << "a::static_inv" << std::endl; } + void invariant() const { out << "a::inv" << std::endl; } + + ~a() BOOST_NOEXCEPT_IF(false) { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + .except([] { out << "a::dtor::except" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + // Do not throw (from inheritance leaf). + } +}; + +int main() { + std::ostringstream ok; + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw; }); + + try { + { + a aa; + out.str(""); + } + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(b_err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + // Test a destructed (so only static_inv and post, but no inv). + << "a::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "b::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl // Test this threw. + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "c::dtor::old" << std::endl + #endif + << "c::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::static_inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + // Test c not destructed (so both inv and except). + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "c::dtor::except" << std::endl + #endif + #endif + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/detail/counter.hpp b/src/boost/libs/contract/test/detail/counter.hpp new file mode 100644 index 00000000..ab40dfcd --- /dev/null +++ b/src/boost/libs/contract/test/detail/counter.hpp @@ -0,0 +1,56 @@ + +#ifndef BOOST_CONTRACT_TEST_DETAIL_COUNTER_HPP_ +#define BOOST_CONTRACT_TEST_DETAIL_COUNTER_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 + +namespace boost { namespace contract { namespace test { namespace detail { + +// Helper to count copies and evaluations of type (e.g., for old values). +template<class Tag, typename T> +struct counter { + T value; + + counter() : value() { ++ctors_; } + static unsigned ctors() { return ctors_; } + + ~counter() { ++dtors_; } + static unsigned dtors() { return dtors_; } + + /* implicit */ counter(counter const& other) : value(other.value) { + ++ctor_copies_; + ++ctors_; + } + + counter& operator=(counter const& other) { + value = other.value; + ++op_copies_; + return *this; + } + + static unsigned copies() { return ctor_copies_ + op_copies_; } + + static counter const& eval(counter const& me) { ++me.evals_; return me; } + static unsigned evals() { return evals_; } + +private: + static unsigned ctors_; // Total constructions (including copies). + static unsigned dtors_; + static unsigned ctor_copies_; + static unsigned op_copies_; + static unsigned evals_; +}; + +template<class Tag, typename T> unsigned counter<Tag, T>::ctors_ = 0; +template<class Tag, typename T> unsigned counter<Tag, T>::dtors_ = 0; +template<class Tag, typename T> unsigned counter<Tag, T>::ctor_copies_ = 0; +template<class Tag, typename T> unsigned counter<Tag, T>::op_copies_ = 0; +template<class Tag, typename T> unsigned counter<Tag, T>::evals_ = 0; + +} } } } // namespace + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/detail/oteststream.hpp b/src/boost/libs/contract/test/detail/oteststream.hpp new file mode 100644 index 00000000..5bf5a031 --- /dev/null +++ b/src/boost/libs/contract/test/detail/oteststream.hpp @@ -0,0 +1,82 @@ + +#ifndef BOOST_CONTRACT_TEST_DETAIL_OTESTSTREAM_HPP_ +#define BOOST_CONTRACT_TEST_DETAIL_OTESTSTREAM_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 + +#include <boost/iostreams/tee.hpp> +#include <boost/iostreams/stream.hpp> +#include <string> +#include <sstream> +#include <iostream> +#include <algorithm> + +namespace boost { namespace contract { namespace test { namespace detail { + +namespace oteststream_ { + struct oss_base { // Wrap oss data member for proper initialization order. + protected: + std::ostringstream oss_; + }; +} + +// Print to clog plus build internal string (using ostringstream) for checking. +struct oteststream : + private oteststream_::oss_base, + public boost::iostreams::stream<boost::iostreams::tee_device<std::ostream, + std::ostringstream> > +{ + oteststream() : + oteststream_::oss_base(), + boost::iostreams::stream<boost::iostreams::tee_device< + std::ostream, std::ostringstream> >( + boost::iostreams::tee_device<std::ostream, std::ostringstream>( + std::clog, oss_) + ) + {} + + std::string str() const { return oss_.str(); } + void str(std::string const& s) { oss_.str(s); } + + bool eq(std::string const& s) { return eq(str(), s); } + + // Also display mismatching characters. + static bool eq(std::string const& r, std::string const& s) { + std::string::size_type i = 0; + for(; i < r.size() && i < s.size(); ++i) if(r[i] != s[i]) break; + if(i < r.size() || i < s.size()) { + std::cout << std::endl; + std::cout << + "Error: Following strings differ at position " << i << + ", because '" << r[i] << "' != '" << s[i] << "':" << std::endl + ; + std::cout << std::endl; + std::cout + << r.substr(0, i) + << "(((" << r[i] << ")))" + // Extra () to avoid clashes with MSVC min macro. + << r.substr((std::min)(i + 1, r.size()), r.size()) + << std::endl + ; + std::cout << std::endl; + std::cout + << s.substr(0, i) + << "(((" << s[i] << ")))" + // Extra () to avoid clashes with MSVC min macro. + << s.substr((std::min)(i + 1, s.size()), s.size()) + << std::endl + ; + std::cout << std::endl; + return false; + } + return true; + } +}; + +} } } } // namespace + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/detail/out.hpp b/src/boost/libs/contract/test/detail/out.hpp new file mode 100644 index 00000000..fd9cd4c5 --- /dev/null +++ b/src/boost/libs/contract/test/detail/out.hpp @@ -0,0 +1,23 @@ + +#ifndef BOOST_CONTRACT_TEST_DETAIL_OUT_HPP_ +#define BOOST_CONTRACT_TEST_DETAIL_OUT_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 + +// To declare test string functions across shared libraries. + +#include <string> + +namespace boost { namespace contract { namespace test { namespace detail { + +std::string BOOST_CONTRACT_TEST_DETAIL_OUT_DECLSPEC out(); + +void BOOST_CONTRACT_TEST_DETAIL_OUT_DECLSPEC out(std::string const& text); + +} } } } + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/detail/out_inlined.hpp b/src/boost/libs/contract/test/detail/out_inlined.hpp new file mode 100644 index 00000000..954088f3 --- /dev/null +++ b/src/boost/libs/contract/test/detail/out_inlined.hpp @@ -0,0 +1,33 @@ + +#ifndef BOOST_CONTRACT_TEST_OUT_INLINED_HPP_ +#define BOOST_CONTRACT_TEST_OUT_INLINED_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 + +#include "out.hpp" +#include <iostream> + +namespace boost { namespace contract { namespace test { namespace detail { + +namespace out_ { + std::string out; +} + +std::string out() { return out_::out; } + +void out(std::string const& text) { + if(text == "") out_::out = ""; + else { + out_::out = out_::out + text; + std::clog << text; + std::clog.flush(); + } +} + +} } } } + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/detail/unprotected_commas.hpp b/src/boost/libs/contract/test/detail/unprotected_commas.hpp new file mode 100644 index 00000000..c20dd404 --- /dev/null +++ b/src/boost/libs/contract/test/detail/unprotected_commas.hpp @@ -0,0 +1,27 @@ + +#ifndef BOOST_CONTRACT_TEST_DETAIL_UNPROTECTED_COMMAS_HPP_ +#define BOOST_CONTRACT_TEST_DETAIL_UNPROTECTED_COMMAS_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 + +namespace boost { namespace contract { namespace test { namespace detail { + +// Used to test passing unprotected commas into macro parameters. +template<typename T1, typename Unused2, typename Unused3> +struct unprotected_commas { + typedef T1 type1; // For type macro parameters. + + static void call() {} // For code block macro parameters. + + // For value macro parameters. + template<typename U> static U& same(U& x) { return x; } + template<typename U> static U* same(U* x) { return x; } +}; + +} } } } // namespace + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/disable/audit.cpp b/src/boost/libs/contract/test/disable/audit.cpp new file mode 100644 index 00000000..cb0765ea --- /dev/null +++ b/src/boost/libs/contract/test/disable/audit.cpp @@ -0,0 +1,11 @@ + +// 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 + +#ifndef BOOST_CONTRACT_AUDITS + #error "build must define AUDITS" +#endif +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/disable/audit.hpp b/src/boost/libs/contract/test/disable/audit.hpp new file mode 100644 index 00000000..c2b2236c --- /dev/null +++ b/src/boost/libs/contract/test/disable/audit.hpp @@ -0,0 +1,32 @@ + +// 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 + +#include <boost/contract/assert.hpp> +#include <boost/contract/core/exception.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() { + bool threw = false; + try { + #ifdef BOOST_CONTRACT_TEST_ERROR + BOOST_CONTRACT_ASSERT_AUDIT( + BOOST_CONTRACT_TEST_ERROR_expected_undeclared_identifier); + #else + BOOST_CONTRACT_ASSERT_AUDIT(false); + #endif + } catch(boost::contract::assertion_failure const&) { threw = true; } + + #if defined(BOOST_CONTRACT_AUDITS) && !defined(BOOST_CONTRACT_NO_ALL) + BOOST_TEST(threw); + #else + BOOST_TEST(!threw); + #endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/disable/audit_disabled.cpp b/src/boost/libs/contract/test/disable/audit_disabled.cpp new file mode 100644 index 00000000..18c6ad03 --- /dev/null +++ b/src/boost/libs/contract/test/disable/audit_disabled.cpp @@ -0,0 +1,8 @@ + +// 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 + +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/disable/audit_disabled_error.cpp b/src/boost/libs/contract/test/disable/audit_disabled_error.cpp new file mode 100644 index 00000000..c58714dc --- /dev/null +++ b/src/boost/libs/contract/test/disable/audit_disabled_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_ERROR +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/disable/audit_error.cpp b/src/boost/libs/contract/test/disable/audit_error.cpp new file mode 100644 index 00000000..c58714dc --- /dev/null +++ b/src/boost/libs/contract/test/disable/audit_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_ERROR +#include "audit.hpp" + diff --git a/src/boost/libs/contract/test/disable/axiom.cpp b/src/boost/libs/contract/test/disable/axiom.cpp new file mode 100644 index 00000000..b24af7a4 --- /dev/null +++ b/src/boost/libs/contract/test/disable/axiom.cpp @@ -0,0 +1,8 @@ + +// 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 + +#include "axiom.hpp" + diff --git a/src/boost/libs/contract/test/disable/axiom.hpp b/src/boost/libs/contract/test/disable/axiom.hpp new file mode 100644 index 00000000..df5231bb --- /dev/null +++ b/src/boost/libs/contract/test/disable/axiom.hpp @@ -0,0 +1,23 @@ + +// 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 + +#include <boost/contract/assert.hpp> + +bool no_impl(); // Test func that cannot be impl in C++ sill OK in axioms. + +int main() { + #ifdef BOOST_CONTRACT_TEST_ERROR + BOOST_CONTRACT_ASSERT_AXIOM( + BOOST_CONRACT_TEST_ERROR_expected_undeclared_identifier); + #else + BOOST_CONTRACT_ASSERT_AXIOM(false); // Test always false, OK. + BOOST_CONTRACT_ASSERT_AXIOM(no_impl()); // Test no implementation, OK. + #endif + return 0; +} + diff --git a/src/boost/libs/contract/test/disable/axiom_error.cpp b/src/boost/libs/contract/test/disable/axiom_error.cpp new file mode 100644 index 00000000..a7c4c406 --- /dev/null +++ b/src/boost/libs/contract/test/disable/axiom_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_ERROR +#include "axiom.hpp" + diff --git a/src/boost/libs/contract/test/disable/lib_a.cpp b/src/boost/libs/contract/test/disable/lib_a.cpp new file mode 100644 index 00000000..a4f283de --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_a.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 + +#define BOOST_CONTRACT_TEST_LIB_A_SOURCE +#include "lib_a.hpp" +#include <boost/contract.hpp> // All headers so test ODR for entire lib. +#ifndef BOOST_CONTRACT_HEADER_ONLY + #include "lib_a_inlined.hpp" +#endif +#include "../detail/out_inlined.hpp" + diff --git a/src/boost/libs/contract/test/disable/lib_a.hpp b/src/boost/libs/contract/test/disable/lib_a.hpp new file mode 100644 index 00000000..7f26276e --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_a.hpp @@ -0,0 +1,51 @@ + +#ifndef BOOST_CONTRACT_TEST_LIB_A_HPP_ +#define BOOST_CONTRACT_TEST_LIB_A_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 + +#include "../detail/counter.hpp" +#include <boost/contract.hpp> // All headers so test ODR for entire lib. +#include <boost/config.hpp> +#include <string> + +#ifdef BOOST_CONTRACT_TEST_LIB_A_DYN_LINK + #ifdef BOOST_CONTRACT_TEST_LIB_A_SOURCE + #define BOOST_CONTRACT_TEST_LIB_A_DECLSPEC BOOST_SYMBOL_EXPORT + #else + #define BOOST_CONTRACT_TEST_LIB_A_DECLSPEC BOOST_SYMBOL_IMPORT + #endif +#else + #define BOOST_CONTRACT_TEST_LIB_A_DECLSPEC /* nothing */ +#endif + +#define BOOST_CONTRACT_TEST_DETAIL_OUT_DECLSPEC \ + BOOST_CONTRACT_TEST_LIB_A_DECLSPEC +#include "../detail/out.hpp" + +struct BOOST_CONTRACT_TEST_LIB_A_DECLSPEC a { + static void static_invariant(); + void invariant() const; + + struct x_tag; + typedef boost::contract::test::detail::counter<x_tag, int> x_type; + + int f(x_type& x); + + static void disable_pre_failure(); + static void disable_post_failure(); + static void disable_entry_inv_failure(); + static void disable_exit_inv_failure(); + static void disable_inv_failure(); + static void disable_failure(); +}; + +#ifdef BOOST_CONTRACT_HEADER_ONLY + #include "lib_a_inlined.hpp" +#endif + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/disable/lib_a_inlined.hpp b/src/boost/libs/contract/test/disable/lib_a_inlined.hpp new file mode 100644 index 00000000..f139bd2b --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_a_inlined.hpp @@ -0,0 +1,101 @@ + +#ifndef BOOST_CONTRACT_TEST_LIB_A_INLINED_HPP_ +#define BOOST_CONTRACT_TEST_LIB_A_INLINED_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 + +#include "lib_a.hpp" +#include <boost/contract.hpp> // All headers so test ODR for entire lib. + +#ifdef BOOST_CONTRACT_HEADER_ONLY + #define BOOST_CONTRACT_TEST_LIB_A_DECLINLINE inline +#else + #define BOOST_CONTRACT_TEST_LIB_A_DECLINLINE /* nothing */ +#endif + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::static_invariant() { + using boost::contract::test::detail::out; + out("a::static_inv\n"); +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::invariant() const { + using boost::contract::test::detail::out; + out("a::inv\n"); +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +int a::f(x_type& x) { + using boost::contract::test::detail::out; + int result; + boost::contract::old_ptr<x_type> old_x = + BOOST_CONTRACT_OLDOF(x_type::eval(x)); + boost::contract::check c = boost::contract::public_function(this) + // Capturing [&] so out() visible in MSVC10 lambdas. + .precondition([&] { out("a::f::pre\n"); }) + .old([&] { out("a::f::old\n"); }) + .postcondition([&] { + out("a::f::post\n"); + BOOST_CONTRACT_ASSERT(x.value == -old_x->value); + BOOST_CONTRACT_ASSERT(result == old_x->value); + }) + ; + out("a::f::body\n"); + result = x.value; + x.value = -x.value; + return result; +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::disable_pre_failure() { + using boost::contract::test::detail::out; + boost::contract::set_precondition_failure([] (boost::contract::from) + { out("a::pre_failure\n"); }); +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::disable_post_failure() { + using boost::contract::test::detail::out; + boost::contract::set_postcondition_failure([] (boost::contract::from) + { out("a::post_failure\n"); }); +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::disable_entry_inv_failure() { + using boost::contract::test::detail::out; + boost::contract::set_entry_invariant_failure([] (boost::contract::from) + { out("a::entry_inv_failure\n"); }); +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::disable_exit_inv_failure() { + using boost::contract::test::detail::out; + boost::contract::set_exit_invariant_failure([] (boost::contract::from) + { out("a::exit_inv_failure\n"); }); +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::disable_inv_failure() { + using boost::contract::test::detail::out; + boost::contract::set_invariant_failure([] (boost::contract::from) + { out("a::inv_failure\n"); }); +} + +BOOST_CONTRACT_TEST_LIB_A_DECLINLINE +void a::disable_failure() { + using boost::contract::test::detail::out; + boost::contract::set_precondition_failure( + boost::contract::set_postcondition_failure( + boost::contract::set_except_failure( + boost::contract::set_old_failure( + boost::contract::set_invariant_failure( + [] (boost::contract::from) { out("a::failure\n"); } + ))))); +} + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/disable/lib_ab.hpp b/src/boost/libs/contract/test/disable/lib_ab.hpp new file mode 100644 index 00000000..f6aafdb3 --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_ab.hpp @@ -0,0 +1,164 @@ + +// 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 + +#include "lib_a.hpp" +#include "lib_b.hpp" +#include "../detail/oteststream.hpp" +#include <boost/contract/core/exception.hpp> +#include <boost/contract/core/config.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_f() { + std::ostringstream ok; 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 + ; + return ok.str(); +} + +int main() { + using boost::contract::test::detail::out; + std::ostringstream ok; + b bb; + + out(""); + bb.g(); + 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::g::pre" << std::endl + #ifdef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION + // Test preconditions have disabled no contract. + << ok_f() + #else + // Test call while checking executes body (but no contracts). + << "a::f::body" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::g::old" << std::endl + #endif + << "b::g::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::g::post" << std::endl + // Test call while checking executes body (but no contracts). + << "a::f::body" << std::endl + #endif + ; + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), ok.str())); + + // Test old values not copied for disabled contracts. + + #if defined(BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION) && \ + !defined(BOOST_CONTRACT_NO_PRECONDITIONS) && \ + !defined(BOOST_CONTRACT_NO_OLDS) + #define BOOST_CONTRACT_TEST_old 1u + #else + #define BOOST_CONTRACT_TEST_old 0u + #endif + + BOOST_TEST_EQ(a::x_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a::x_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(a::x_type::ctors(), a::x_type::dtors()); + + // Double check a call to f outside another contract checks f's contracts. + + out(""); + call_f(); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), ok_f())); + + // Test setting failure handlers (from this program using a lib). + + a::disable_pre_failure(); + out(""); + boost::contract::precondition_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::pre_failure\n")); + + a::disable_post_failure(); + out(""); + boost::contract::postcondition_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::post_failure\n")); + + a::disable_entry_inv_failure(); + out(""); + boost::contract::entry_invariant_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::entry_inv_failure\n")); + + a::disable_exit_inv_failure(); + out(""); + boost::contract::exit_invariant_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::exit_inv_failure\n")); + + a::disable_inv_failure(); + out(""); + boost::contract::entry_invariant_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::inv_failure\n")); + out(""); + boost::contract::exit_invariant_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::inv_failure\n")); + + a::disable_failure(); + out(""); + boost::contract::precondition_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n")); + out(""); + boost::contract::postcondition_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n")); + out(""); + boost::contract::entry_invariant_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n")); + out(""); + boost::contract::exit_invariant_failure(boost::contract::from()); + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n")); + + // Test setting failure handlers (from a lib using another lib). + + BOOST_TEST(b::test_disable_pre_failure()); + BOOST_TEST(b::test_disable_post_failure()); + BOOST_TEST(b::test_disable_entry_inv_failure()); + BOOST_TEST(b::test_disable_exit_inv_failure()); + BOOST_TEST(b::test_disable_inv_failure()); + BOOST_TEST(b::test_disable_failure()); + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/disable/lib_b.cpp b/src/boost/libs/contract/test/disable/lib_b.cpp new file mode 100644 index 00000000..7d9a94a9 --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_b.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_LIB_B_SOURCE +#include "lib_b_inlined.hpp" + diff --git a/src/boost/libs/contract/test/disable/lib_b.hpp b/src/boost/libs/contract/test/disable/lib_b.hpp new file mode 100644 index 00000000..8cc34cbc --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_b.hpp @@ -0,0 +1,41 @@ + +#ifndef BOOST_CONTRACT_TEST_LIB_B_HPP_ +#define BOOST_CONTRACT_TEST_LIB_B_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 + +#include <boost/config.hpp> + +#ifdef BOOST_CONTRACT_TEST_LIB_B_DYN_LINK + #ifdef BOOST_CONTRACT_TEST_LIB_B_SOURCE + #define BOOST_CONTRACT_TEST_LIB_B_DECLSPEC BOOST_SYMBOL_EXPORT + #else + #define BOOST_CONTRACT_TEST_LIB_B_DECLSPEC BOOST_SYMBOL_IMPORT + #endif +#else + #define BOOST_CONTRACT_TEST_LIB_B_DECLSPEC /* nothing */ +#endif + +bool BOOST_CONTRACT_TEST_LIB_B_DECLSPEC call_f(); + +struct BOOST_CONTRACT_TEST_LIB_B_DECLSPEC b { + static void static_invariant(); + void invariant() const; + + void g(); + + static bool test_disable_pre_failure(); + static bool test_disable_post_failure(); + static bool test_disable_entry_inv_failure(); + static bool test_disable_exit_inv_failure(); + static bool test_disable_inv_failure(); + static bool test_disable_failure(); + +}; + +#endif // #include guard + + diff --git a/src/boost/libs/contract/test/disable/lib_b_inlined.hpp b/src/boost/libs/contract/test/disable/lib_b_inlined.hpp new file mode 100644 index 00000000..0a7bf5a9 --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_b_inlined.hpp @@ -0,0 +1,124 @@ + +#ifndef BOOST_CONTRACT_TEST_LIB_B_INLINED_HPP_ +#define BOOST_CONTRACT_TEST_LIB_B_INLINED_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 + +#include "lib_b.hpp" +#include "lib_a.hpp" +#include "../detail/oteststream.hpp" +#include <boost/contract.hpp> // All headers to test ODR for entire lib. + +bool call_f() { + a aa; + a::x_type x; x.value = -123; + return aa.f(x) == -123; +} + +void b::static_invariant() { + using boost::contract::test::detail::out; + out("b::static_inv\n"); +} + +void b::invariant() const { + using boost::contract::test::detail::out; + out("b::inv\n"); +} + +void b::g() { + using boost::contract::test::detail::out; + boost::contract::check c = boost::contract::public_function(this) + .precondition([&] { + out("b::g::pre\n"); + BOOST_CONTRACT_ASSERT(call_f()); + }) + .old([&] { out("b::g::old\n"); }) + .postcondition([&] { + out("b::g::post\n"); + BOOST_CONTRACT_ASSERT(call_f()); + }) + ; + out("b::g::body\n"); +} + +bool b::test_disable_pre_failure() { + using boost::contract::test::detail::out; + a::disable_pre_failure(); + out(""); + boost::contract::precondition_failure(boost::contract::from()); + return boost::contract::test::detail::oteststream::eq(out(), + "a::pre_failure\n"); +} + +bool b::test_disable_post_failure() { + using boost::contract::test::detail::out; + a::disable_post_failure(); + out(""); + boost::contract::postcondition_failure(boost::contract::from()); + return boost::contract::test::detail::oteststream::eq(out(), + "a::post_failure\n"); +} + +bool b::test_disable_entry_inv_failure() { + using boost::contract::test::detail::out; + a::disable_entry_inv_failure(); + out(""); + boost::contract::entry_invariant_failure(boost::contract::from()); + return boost::contract::test::detail::oteststream::eq(out(), + "a::entry_inv_failure\n"); +} + +bool b::test_disable_exit_inv_failure() { + using boost::contract::test::detail::out; + a::disable_exit_inv_failure(); + out(""); + boost::contract::exit_invariant_failure(boost::contract::from()); + return boost::contract::test::detail::oteststream::eq(out(), + "a::exit_inv_failure\n"); +} + +bool b::test_disable_inv_failure() { + using boost::contract::test::detail::out; + + a::disable_inv_failure(); + out(""); + boost::contract::entry_invariant_failure(boost::contract::from()); + bool entry_inv = boost::contract::test::detail::oteststream::eq(out(), + "a::inv_failure\n"); + out(""); + boost::contract::exit_invariant_failure(boost::contract::from()); + bool exit_inv = boost::contract::test::detail::oteststream::eq(out(), + "a::inv_failure\n"); + + return entry_inv && exit_inv; +} + +bool b::test_disable_failure() { + using boost::contract::test::detail::out; + + a::disable_failure(); + out(""); + boost::contract::precondition_failure(boost::contract::from()); + bool pre = boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n"); + out(""); + boost::contract::postcondition_failure(boost::contract::from()); + bool post = boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n"); + out(""); + boost::contract::entry_invariant_failure(boost::contract::from()); + bool entry_inv = boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n"); + out(""); + boost::contract::exit_invariant_failure(boost::contract::from()); + bool exit_inv = boost::contract::test::detail::oteststream::eq(out(), + "a::failure\n"); + + return pre && post && entry_inv && exit_inv; +} + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/disable/lib_x.cpp b/src/boost/libs/contract/test/disable/lib_x.cpp new file mode 100644 index 00000000..e928b47e --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_x.cpp @@ -0,0 +1,29 @@ + +// 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 + +// Force .cpp never check post/except. +#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + #error "build must define NO_POSTCONDITIONS" +#endif +#ifndef BOOST_CONTRACT_NO_EXCEPTS + #error "build must define NO_EXCEPTS" +#endif + +#define BOOST_CONTRACT_TEST_LIB_X_SOURCE +#include "lib_x.hpp" +#include <boost/contract.hpp> // All headers so test ODR for entire lib. +#include "../detail/out_inlined.hpp" + +void x() { + using boost::contract::test::detail::out; + boost::contract::check c = boost::contract::function() + .precondition([] { out("x::pre\n"); }) + .old([] { out("x::old\n"); }) + .postcondition([] { out("x::post\n"); }) + ; + out("x::body\n"); +} + diff --git a/src/boost/libs/contract/test/disable/lib_x.hpp b/src/boost/libs/contract/test/disable/lib_x.hpp new file mode 100644 index 00000000..e64a74cc --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_x.hpp @@ -0,0 +1,30 @@ + +#ifndef BOOST_CONTRACT_TEST_LIB_X_HPP_ +#define BOOST_CONTRACT_TEST_LIB_X_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 + +#include <boost/config.hpp> +#include <string> + +#ifdef BOOST_CONTRACT_TEST_LIB_X_DYN_LINK + #ifdef BOOST_CONTRACT_TEST_LIB_X_SOURCE + #define BOOST_CONTRACT_TEST_LIB_X_DECLSPEC BOOST_SYMBOL_EXPORT + #else + #define BOOST_CONTRACT_TEST_LIB_X_DECLSPEC BOOST_SYMBOL_IMPORT + #endif +#else + #define BOOST_CONTRACT_TEST_LIB_X_DECLSPEC /* nothing */ +#endif + +#define BOOST_CONTRACT_TEST_DETAIL_OUT_DECLSPEC \ + BOOST_CONTRACT_TEST_LIB_X_DECLSPEC +#include "../detail/out.hpp" + +void BOOST_CONTRACT_TEST_LIB_X_DECLSPEC x(); + +#endif + diff --git a/src/boost/libs/contract/test/disable/lib_xy.hpp b/src/boost/libs/contract/test/disable/lib_xy.hpp new file mode 100644 index 00000000..0c52262e --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_xy.hpp @@ -0,0 +1,76 @@ + +// 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 contracts in .cpp compiled to never check post/except (but not in .hpp). + +#include "lib_x.hpp" +#include "lib_y.hpp" +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +void f() { + using boost::contract::test::detail::out; + boost::contract::check c = boost::contract::function() + // Capturing [&] so out() visible in MSVC10 lambdas. + .precondition([&] { out("f::pre\n"); }) + .old([&] { out("f::old\n"); }) + .postcondition([&] { out("f::post\n"); }) + ; + out("f::body\n"); +} + +int main() { + using boost::contract::test::detail::out; + std::ostringstream ok; + + out(""); + f(); + ok.str(""); ok // Test normal (no lib) case. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), ok.str())); + + out(""); + x(); + ok.str(""); ok // Test contracts in .cpp so no post (NO_POST in build file). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "x::pre" << std::endl + #endif + << "x::body" << std::endl + ; + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), ok.str())); + + out(""); + y(); + ok.str(""); ok // Test contracts in .hpp so post (NO_POST in build file). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "y::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "y::old" << std::endl + #endif + << "y::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "y::post" << std::endl + #endif + ; + BOOST_TEST(boost::contract::test::detail::oteststream::eq(out(), ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/disable/lib_y.cpp b/src/boost/libs/contract/test/disable/lib_y.cpp new file mode 100644 index 00000000..eade2541 --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_y.cpp @@ -0,0 +1,24 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Force .cpp never check post/except. +#ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + #error "build must define NO_POSTCONDITIONS" +#endif +#ifndef BOOST_CONTRACT_NO_EXCEPTS + #error "build must define NO_EXCEPTS" +#endif + +#define BOOST_CONTRACT_TEST_LIB_Y_SOURCE +#include "lib_y.hpp" + +namespace lib_y_ { + void y_body() { + using boost::contract::test::detail::out; + out("y::body\n"); + } +} + diff --git a/src/boost/libs/contract/test/disable/lib_y.hpp b/src/boost/libs/contract/test/disable/lib_y.hpp new file mode 100644 index 00000000..f2444096 --- /dev/null +++ b/src/boost/libs/contract/test/disable/lib_y.hpp @@ -0,0 +1,40 @@ + +#ifndef BOOST_CONTRACT_TEST_LIB_Y_HPP_ +#define BOOST_CONTRACT_TEST_LIB_Y_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 + +#include "lib_x.hpp" +#include <boost/contract.hpp> // All headers so test ODR for entire lib. +#include <boost/config.hpp> + +#ifdef BOOST_CONTRACT_TEST_LIB_Y_DYN_LINK + #ifdef BOOST_CONTRACT_TEST_LIB_Y_SOURCE + #define BOOST_CONTRACT_TEST_LIB_Y_DECLSPEC BOOST_SYMBOL_EXPORT + #else + #define BOOST_CONTRACT_TEST_LIB_Y_DECLSPEC BOOST_SYMBOL_IMPORT + #endif +#else + #define BOOST_CONTRACT_TEST_LIB_Y_DECLSPEC /* nothing */ +#endif + +namespace lib_y_ { // Internal namepsace. + void BOOST_CONTRACT_TEST_LIB_Y_DECLSPEC y_body(); +} + +inline void y() { + using boost::contract::test::detail::out; + boost::contract::check c = boost::contract::function() + // Capturing [&] so out() visible in MSVC10 lambdas. + .precondition([&] { out("y::pre\n"); }) + .old([&] { out("y::old\n"); }) + .postcondition([&] { out("y::post\n"); }) + ; + lib_y_::y_body(); +} + +#endif + diff --git a/src/boost/libs/contract/test/disable/no_post_except_lib.cpp b/src/boost/libs/contract/test/disable/no_post_except_lib.cpp new file mode 100644 index 00000000..eaa52e38 --- /dev/null +++ b/src/boost/libs/contract/test/disable/no_post_except_lib.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 contracts in .cpp compiled to never check post/except (but not in .hpp). + +#include "lib_xy.hpp" + diff --git a/src/boost/libs/contract/test/disable/no_post_except_unit.cpp b/src/boost/libs/contract/test/disable/no_post_except_unit.cpp new file mode 100644 index 00000000..c5db4a7e --- /dev/null +++ b/src/boost/libs/contract/test/disable/no_post_except_unit.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 .cpp never check post/except (in multiple compilation units). + +#include "lib_xy.hpp" + diff --git a/src/boost/libs/contract/test/disable/nothing_for_pre_prog.cpp b/src/boost/libs/contract/test/disable/nothing_for_pre_prog.cpp new file mode 100644 index 00000000..c8286f72 --- /dev/null +++ b/src/boost/libs/contract/test/disable/nothing_for_pre_prog.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 pre disable no assertion (in programs, but same for libraries). + +#ifndef BOOST_CONTRACT_PRECONDITIONS_DISABLE_NO_ASSERTION + #error "build must define PRECONDITIONS_DISABLE_NO_ASSERTION" +#endif +#include "prog.hpp" + diff --git a/src/boost/libs/contract/test/disable/other_assertions_lib.cpp b/src/boost/libs/contract/test/disable/other_assertions_lib.cpp new file mode 100644 index 00000000..2e68b943 --- /dev/null +++ b/src/boost/libs/contract/test/disable/other_assertions_lib.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 assertion checking disables other assertion checking (in libraries). + +#include "lib_ab.hpp" + diff --git a/src/boost/libs/contract/test/disable/other_assertions_prog.cpp b/src/boost/libs/contract/test/disable/other_assertions_prog.cpp new file mode 100644 index 00000000..b5fc359c --- /dev/null +++ b/src/boost/libs/contract/test/disable/other_assertions_prog.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 assertion checking disables other assertion checking (in programs). + +#include "prog.hpp" + diff --git a/src/boost/libs/contract/test/disable/other_assertions_unit.cpp b/src/boost/libs/contract/test/disable/other_assertions_unit.cpp new file mode 100644 index 00000000..c1bdea41 --- /dev/null +++ b/src/boost/libs/contract/test/disable/other_assertions_unit.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 assertions disables other assertions (in multiple compilation units). + +#include "lib_ab.hpp" + diff --git a/src/boost/libs/contract/test/disable/prog.hpp b/src/boost/libs/contract/test/disable/prog.hpp new file mode 100644 index 00000000..a20bb723 --- /dev/null +++ b/src/boost/libs/contract/test/disable/prog.hpp @@ -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 + +#include "lib_a.hpp" +#include "lib_a_inlined.hpp" +#include "lib_b.hpp" +#include "lib_b_inlined.hpp" +#include "lib_ab.hpp" +#include "../detail/out_inlined.hpp" + diff --git a/src/boost/libs/contract/test/function/decl.hpp b/src/boost/libs/contract/test/function/decl.hpp new file mode 100644 index 00000000..360f7c5d --- /dev/null +++ b/src/boost/libs/contract/test/function/decl.hpp @@ -0,0 +1,40 @@ + +#ifndef BOOST_CONTRACT_TEST_FUNCTION_DECL_HPP_ +#define BOOST_CONTRACT_TEST_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 and post declarations. + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> + +boost::contract::test::detail::oteststream out; + +bool f_pre = true, f_post = true; +void f() { + boost::contract::check c = boost::contract::function() + #ifndef BOOST_CONTRACT_TEST_NO_F_PRE + .precondition([] { + out << "f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(f_pre); + }) + #endif + .old([] { out << "f::old" << std::endl; }) + #ifndef BOOST_CONTRACT_TEST_NO_F_POST + .postcondition([] { + out << "f::post" << std::endl; + BOOST_CONTRACT_ASSERT(f_post); + }) + #endif + ; + out << "f::body" << std::endl; +} + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/function/decl_post_all.cpp b/src/boost/libs/contract/test/function/decl_post_all.cpp new file mode 100644 index 00000000..59dce860 --- /dev/null +++ b/src/boost/libs/contract/test/function/decl_post_all.cpp @@ -0,0 +1,64 @@ + +// 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 postconditions. + +#undef BOOST_CONTRACT_TEST_NO_F_POST +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_f() { + std::ostringstream ok; ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl // This can fail. + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + f_post = true; + out.str(""); + f(); + ok.str(""); ok // Test nothing failed. + << ok_f() + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw err(); }); + + f_post = false; + out.str(""); + try { + f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_f() // Test f::post failed. + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/function/decl_post_none.cpp b/src/boost/libs/contract/test/function/decl_post_none.cpp new file mode 100644 index 00000000..514e9858 --- /dev/null +++ b/src/boost/libs/contract/test/function/decl_post_none.cpp @@ -0,0 +1,38 @@ + +// 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 without postconditions. + +#define BOOST_CONTRACT_TEST_NO_F_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_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + ; + + f_post = true; + out.str(""); + f(); + BOOST_TEST(out.eq(ok.str())); + + f_post = false; + out.str(""); + f(); + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/function/decl_pre_all.cpp b/src/boost/libs/contract/test/function/decl_pre_all.cpp new file mode 100644 index 00000000..1ff33a55 --- /dev/null +++ b/src/boost/libs/contract/test/function/decl_pre_all.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 with preconditions. + +#undef BOOST_CONTRACT_TEST_NO_F_PRE +#include "decl.hpp" + +#include <boost/detail/lightweight_test.hpp> +#include <sstream> +#include <string> + +std::string ok_f(bool failed = false) { + std::ostringstream ok; ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl // Test no failure here. + #endif + ; + if(!failed) ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + return ok.str(); +} + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +int main() { + std::ostringstream ok; + + f_pre = true; + out.str(""); + f(); + ok.str(""); ok + << ok_f() + ; + BOOST_TEST(out.eq(ok.str())); + + #ifdef BOOST_CONTRACT_NO_PRECONDITIONS + #define BOOST_CONTRACT_TEST_pre 0 + #else + #define BOOST_CONTRACT_TEST_pre 1 + #endif + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw err(); }); + + f_pre = false; + out.str(""); + try { + f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + << ok_f(BOOST_CONTRACT_TEST_pre) + ; + BOOST_TEST(out.eq(ok.str())); + } catch(...) { BOOST_TEST(false); } + + #undef BOOST_CONTRACT_TEST_pre + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/function/decl_pre_none.cpp b/src/boost/libs/contract/test/function/decl_pre_none.cpp new file mode 100644 index 00000000..a9c51132 --- /dev/null +++ b/src/boost/libs/contract/test/function/decl_pre_none.cpp @@ -0,0 +1,38 @@ + +// 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 without preconditions. + +#define BOOST_CONTRACT_TEST_NO_F_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_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + + f_pre = true; + out.str(""); + f(); + BOOST_TEST(out.eq(ok.str())); + + f_pre = false; + out.str(""); + f(); + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/function/ifdef.cpp b/src/boost/libs/contract/test/function/ifdef.cpp new file mode 100644 index 00000000..fe9a1cee --- /dev/null +++ b/src/boost/libs/contract/test/function/ifdef.cpp @@ -0,0 +1,58 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test contract compilation on/off. + +#include "../detail/oteststream.hpp" +#include <boost/contract/core/config.hpp> +#ifndef BOOST_CONTRACT_NO_FUNCTIONS + #include <boost/contract/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; + +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_FUNCTIONS + boost::contract::check c = boost::contract::function() + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + .precondition([] { out << "f::pre" << std::endl; }) + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + #endif + ; + #endif + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + out.str(""); + f(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/function/ifdef_macro.cpp b/src/boost/libs/contract/test/function/ifdef_macro.cpp new file mode 100644 index 00000000..ffd7e668 --- /dev/null +++ b/src/boost/libs/contract/test/function/ifdef_macro.cpp @@ -0,0 +1,95 @@ + +// 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 (including EXCEPT, using macro interface). + +#include "../detail/oteststream.hpp" +#include "../detail/unprotected_commas.hpp" +#include <boost/contract_macro.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct except_error {}; + +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_FUNCTION() + BOOST_CONTRACT_PRECONDITION([] { + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + out << "f::pre" << std::endl; + }) + BOOST_CONTRACT_OLD([] { + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + out << "f::old" << std::endl; + }) + BOOST_CONTRACT_POSTCONDITION([] { + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + out << "f::post" << std::endl; + }) + BOOST_CONTRACT_EXCEPT([] { // Test EXCEPT macro (at least 1 time here). + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + out << "f::except" << std::endl; + }) + ; + out << "f::body" << std::endl; + if(x == -1) throw except_error(); +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(123); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + boost::contract::set_except_failure([] (boost::contract::from) {}); + out.str(""); + try { + f(-1); // Test throw and EXCEPT macro (test only here... that's fine). + BOOST_TEST(false); + } catch(except_error const&) {} // OK. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "f::except" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/function/smoke.cpp b/src/boost/libs/contract/test/function/smoke.cpp new file mode 100644 index 00000000..a4a733fd --- /dev/null +++ b/src/boost/libs/contract/test/function/smoke.cpp @@ -0,0 +1,99 @@ + +// 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 free function contracts. + +#include "../detail/oteststream.hpp" +#include "../detail/counter.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/check.hpp> +#include <boost/preprocessor/control/iif.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct x_tag; typedef boost::contract::test::detail::counter<x_tag, int> x_type; +struct y_tag; typedef boost::contract::test::detail::counter<y_tag, int> y_type; + +bool swap(x_type& x, y_type& y) { + bool result; + boost::contract::old_ptr<x_type> old_x = + BOOST_CONTRACT_OLDOF(x_type::eval(x)); + boost::contract::old_ptr<y_type> old_y; + boost::contract::check c = boost::contract::function() + .precondition([&] { + out << "swap::pre" << std::endl; + BOOST_CONTRACT_ASSERT(x.value != y.value); + }) + .old([&] { + out << "swap::old" << std::endl; + old_y = BOOST_CONTRACT_OLDOF(y_type::eval(y)); + }) + .postcondition([&] { + out << "swap::post" << std::endl; + BOOST_CONTRACT_ASSERT(x.value == old_y->value); + BOOST_CONTRACT_ASSERT(y.value == old_x->value); + BOOST_CONTRACT_ASSERT(result == (old_x->value != old_y->value)); + }) + ; + + out << "swap::body" << std::endl; + if(x.value == y.value) return result = false; + int save_x = x.value; + x.value = y.value; + y.value = save_x; + return result = true; +} + +int main() { + std::ostringstream ok; + + { + x_type x; x.value = 123; + y_type y; y.value = 456; + + out.str(""); + bool r = swap(x, y); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "swap::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "swap::old" << std::endl + #endif + << "swap::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "swap::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + BOOST_TEST(r); + BOOST_TEST_EQ(x.value, 456); + BOOST_TEST_EQ(y.value, 123); + } + + #ifndef BOOST_CONTRACT_NO_OLDS + #define BOOST_CONTRACT_TEST_old 1u + #else + #define BOOST_CONTRACT_TEST_old 0u + #endif + + BOOST_TEST_EQ(x_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(x_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(x_type::ctors(), x_type::dtors()); // No leak. + + BOOST_TEST_EQ(y_type::copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(y_type::evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(y_type::ctors(), y_type::dtors()); // No leak. + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/function/throwing_body.cpp b/src/boost/libs/contract/test/function/throwing_body.cpp new file mode 100644 index 00000000..7a64ba1d --- /dev/null +++ b/src/boost/libs/contract/test/function/throwing_body.cpp @@ -0,0 +1,55 @@ + +// 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 free function body. + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; + throw err(); // Test body throws. +} + +int main() { + std::ostringstream ok; + + try { + out.str(""); + f(); + BOOST_TEST(false); + } catch(err const&) { + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl // Test this threw. + #ifndef BOOST_CONTRACT_NO_EXCEPTS + << "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/function/throwing_old.cpp b/src/boost/libs/contract/test/function/throwing_old.cpp new file mode 100644 index 00000000..9bae8662 --- /dev/null +++ b/src/boost/libs/contract/test/function/throwing_old.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 throw from free function .old(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .old([] { + out << "f::old" << std::endl; + throw err(); // Test this throws. + }) + .postcondition([] { out << "f::post" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + boost::contract::set_old_failure([] (boost::contract::from) { throw; }); + + try { + out.str(""); + f(); + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl // Test this threw. + #else + << "f::body" << 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/function/throwing_post.cpp b/src/boost/libs/contract/test/function/throwing_post.cpp new file mode 100644 index 00000000..16d24813 --- /dev/null +++ b/src/boost/libs/contract/test/function/throwing_post.cpp @@ -0,0 +1,62 @@ + +// 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 free function .post(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { + out << "f::post" << std::endl; + throw err(); // Test this throws. + }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + boost::contract::set_postcondition_failure( + [] (boost::contract::from) { throw; }); + + try { + out.str(""); + f(); + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok << "" // Suppress a warning. + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "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/function/throwing_pre.cpp b/src/boost/libs/contract/test/function/throwing_pre.cpp new file mode 100644 index 00000000..3f2669d0 --- /dev/null +++ b/src/boost/libs/contract/test/function/throwing_pre.cpp @@ -0,0 +1,63 @@ + +// 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 free function .pre(). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +struct err {}; // Global decl so visible in MSVC10 lambdas. + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { + out << "f::pre" << std::endl; + throw err(); // Test this throws. + }) + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + boost::contract::set_precondition_failure( + [] (boost::contract::from) { throw; }); + + try { + out.str(""); + f(); + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + BOOST_TEST(false); + } catch(err const&) { + #endif + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl // Test this threw. + #else + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "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/invariant/decl.hpp b/src/boost/libs/contract/test/invariant/decl.hpp new file mode 100644 index 00000000..b4ae9a48 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl.hpp @@ -0,0 +1,840 @@ + +// 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 with and without all invariants (static/cv/const-only) declarations. + +#include "../detail/oteststream.hpp" +#include <boost/contract/base_types.hpp> +#include <boost/contract/constructor.hpp> +#include <boost/contract/destructor.hpp> +#include <boost/contract/public_function.hpp> +#include <boost/contract/function.hpp> +#include <boost/contract/override.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; + +struct b : private boost::contract::constructor_precondition<b> { + // Test also with no base_types. + + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + static void static_invariant() { out << "b::static_inv" << std::endl; } + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + void invariant() const volatile { out << "b::cv_inv" << std::endl; } + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + void invariant() const { out << "b::const_inv" << std::endl; } + #endif + + b() : boost::contract::constructor_precondition<b>([] { + out << "b::ctor::pre" << std::endl; + }) { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "b::ctor::old" << std::endl; }) + .postcondition([] { out << "b::ctor::post" << std::endl; }) + ; + out << "b::ctor::body" << std::endl; + } + + virtual ~b() { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "b::dtor::old" << std::endl; }) + .postcondition([] { out << "b::dtor::post" << std::endl; }) + ; + out << "b::dtor::body" << std::endl; + } + + virtual void f(char x, boost::contract::virtual_* v = 0) volatile { + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([&] { + out << "b::f::volatile_pre" << std::endl; + BOOST_CONTRACT_ASSERT(x == 'b'); + }) + .old([] { out << "b::f::volatile_old" << std::endl; }) + .postcondition([] { out << "b::f::volatile_post" << std::endl; }) + ; + out << "b::f::volatile_body" << std::endl; + } + + virtual void f(char x, 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(x == 'b'); + }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([] { out << "b::f::post" << std::endl; }) + ; + out << "b::f::body" << std::endl; + } +}; + +struct a + #define BASES private boost::contract::constructor_precondition<a>, public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + static void static_invariant() { out << "a::static_inv" << std::endl; } + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + void invariant() const volatile { out << "a::cv_inv" << std::endl; } + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + void invariant() const { out << "a::const_inv" << std::endl; } + #endif + + a() : boost::contract::constructor_precondition<a>([] { + out << "a::ctor::pre" << std::endl; + }) { + boost::contract::check c = boost::contract::constructor(this) + .old([] { out << "a::ctor::old" << std::endl; }) + .postcondition([] { out << "a::ctor::post" << std::endl; }) + ; + out << "a::ctor::body" << std::endl; + } + + virtual ~a() { + boost::contract::check c = boost::contract::destructor(this) + .old([] { out << "a::dtor::old" << std::endl; }) + .postcondition([] { out << "a::dtor::post" << std::endl; }) + ; + out << "a::dtor::body" << std::endl; + } + + virtual void f(char x, boost::contract::virtual_* v = 0) + volatile /* override */ { + boost::contract::check c = boost::contract::public_function< + override_f>( + v, + static_cast<void (a::*)(char x, boost::contract::virtual_*) + volatile>(&a::f), + this, x + ) + .precondition([&] { + out << "a::f::volatile_pre" << std::endl; + BOOST_CONTRACT_ASSERT(x == 'a'); + }) + .old([] { out << "a::f::volatile_old" << std::endl; }) + .postcondition([] { out << "a::f::volatile_post" << std::endl; }) + ; + out << "a::f::volatile_body" << std::endl; + } + + virtual void f(char x, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::check c = boost::contract::public_function< + override_f>( + v, + static_cast<void (a::*)(char x, boost::contract::virtual_*)>(&a::f), + this, x + ) + .precondition([&] { + out << "a::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(x == 'a'); + }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([] { out << "a::f::post" << std::endl; }) + ; + out << "a::f::body" << std::endl; + } + + static void s() { + boost::contract::check c = boost::contract::public_function<a>() + .precondition([] { out << "a::s::pre" << std::endl; }) + .old([] { out << "a::s::old" << std::endl; }) + .postcondition([] { out << "a::s::post" << std::endl; }) + ; + out << "a::s::body" << std::endl; + } + +protected: + void p() volatile { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "a::p::volatile_pre" << std::endl; }) + .old([] { out << "a::p::volatile_old" << std::endl; }) + .postcondition([] { out << "a::p::volatile_post" << std::endl; }) + ; + out << "a::p::volatile_body" << std::endl; + } + + void p() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "a::p::pre" << std::endl; }) + .old([] { out << "a::p::old" << std::endl; }) + .postcondition([] { out << "a::p::post" << std::endl; }) + ; + out << "a::p::body" << std::endl; + } +public: + void call_p() volatile { p(); } + void call_p() { p(); } + +private: + void q() volatile { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "a::q::volatile_pre" << std::endl; }) + .old([] { out << "a::q::volatile_old" << std::endl; }) + .postcondition([] { out << "a::q::volatile_post" << std::endl; }) + ; + out << "a::q::volatile_body" << std::endl; + } + + void q() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "a::q::pre" << std::endl; }) + .old([] { out << "a::q::old" << std::endl; }) + .postcondition([] { out << "a::q::post" << std::endl; }) + ; + out << "a::q::body" << std::endl; + } +public: + void call_q() volatile { q(); } + void call_q() { q(); } + + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + std::ostringstream ok; + + { // Test volatile call with bases. + out.str(""); + a volatile av; + ok.str(""); ok // Ctors always check const_inv (even if volatile). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "a::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "a::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + av.f('a'); + ok.str(""); ok // Volatile checks static and cv (but not const) inv. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "a::cv_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::volatile_pre" << std::endl + << "a::f::volatile_pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::volatile_old" << std::endl + << "a::f::volatile_old" << std::endl + #endif + << "a::f::volatile_body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "a::cv_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::volatile_old" << std::endl + << "b::f::volatile_post" << std::endl + << "a::f::volatile_post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + av.s(); // Test static call. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::s::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::s::old" << std::endl + #endif + << "a::s::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::s::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + av.call_p(); // Test (indirect) protected call. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::p::volatile_pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::p::volatile_old" << std::endl + #endif + << "a::p::volatile_body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::p::volatile_post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + av.call_q(); // Test (indirect) private call. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::q::volatile_pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::q::volatile_old" << std::endl + #endif + << "a::q::volatile_body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::q::volatile_post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + } // Call a's destructor. + ok.str(""); ok // Dtors always check const_inv (even if volatile). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "a::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "a::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + { // Test non-volatile call with bases. + out.str(""); + a aa; + ok.str(""); ok // Ctors always check cv_inv (even if not volatile). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::ctor::pre" << std::endl + << "b::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::ctor::old" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "a::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "a::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.f('a'); + ok.str(""); ok // Non-cv checks static and const (but not cv) inv. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "a::const_inv" << std::endl + #endif + #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 + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "a::const_inv" << std::endl + #endif + #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())); + + out.str(""); + aa.s(); // Test static call. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::s::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::s::old" << std::endl + #endif + << "a::s::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::s::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.call_p(); // Test (indirect) protected call. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::p::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::p::old" << std::endl + #endif + << "a::p::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::p::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.call_q(); // Test (indirect) private call. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "a::q::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::q::old" << std::endl + #endif + << "a::q::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::q::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + } // Call a's destructor. + ok.str(""); ok // Dtors always check cv_inv (even if not volatile). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "a::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "a::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "a::dtor::old" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "a::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "a::dtor::post" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + + { // Test volatile call with no bases. + out.str(""); + b volatile bv; + ok.str(""); ok // Ctors always check const_inv (even if volatile). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + bv.f('b'); + ok.str(""); ok // Volatile checks static and cv (but not const) inv. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::f::volatile_pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::f::volatile_old" << std::endl + #endif + << "b::f::volatile_body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::volatile_post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + } // Call b's destructor. + ok.str(""); ok // Dtors always check const_inv (even if volatile). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + { // Test non-volatile call with no bases. + out.str(""); + b bb; + ok.str(""); ok // Ctors always check cv_inv (even if not volatile). + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::ctor::pre" << std::endl + #endif + + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::ctor::old" << std::endl + #endif + << "b::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::ctor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + bb.f('b'); + ok.str(""); ok // Non-cv checks static and const (but not cv) inv. + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #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 + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + } // Call b's destructor. + ok.str(""); ok // Dtors always check cv_inv (even if not volatile). + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CV_INV + << "b::cv_inv" << std::endl + #endif + #ifdef BOOST_CONTRACT_TEST_CONST_INV + << "b::const_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::dtor::old" << std::endl + #endif + << "b::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + #ifdef BOOST_CONTRACT_TEST_STATIC_INV + << "b::static_inv" << std::endl + #endif + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::dtor::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/invariant/decl_const.cpp b/src/boost/libs/contract/test/invariant/decl_const.cpp new file mode 100644 index 00000000..b936449d --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_const.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 all invariants (static, cv, and const-only). + +#undef BOOST_CONTRACT_TEST_STATIC_INV +#undef BOOST_CONTRACT_TEST_CV_INV +#define BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/decl_cv.cpp b/src/boost/libs/contract/test/invariant/decl_cv.cpp new file mode 100644 index 00000000..5607dafb --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_cv.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 all invariants (static, cv, and const-only). + +#undef BOOST_CONTRACT_TEST_STATIC_INV +#define BOOST_CONTRACT_TEST_CV_INV +#undef BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/decl_cv_const.cpp b/src/boost/libs/contract/test/invariant/decl_cv_const.cpp new file mode 100644 index 00000000..c762bbbc --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_cv_const.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 all invariants (static, cv, and const-only). + +#undef BOOST_CONTRACT_TEST_STATIC_INV +#define BOOST_CONTRACT_TEST_CV_INV +#define BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/decl_nothing.cpp b/src/boost/libs/contract/test/invariant/decl_nothing.cpp new file mode 100644 index 00000000..ad89d1f1 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_nothing.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 all invariants (static, cv, and const-only). + +#undef BOOST_CONTRACT_TEST_STATIC_INV +#undef BOOST_CONTRACT_TEST_CV_INV +#undef BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/decl_static.cpp b/src/boost/libs/contract/test/invariant/decl_static.cpp new file mode 100644 index 00000000..8db92edc --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_static.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 all invariants (static, cv, and const-only). + +#define BOOST_CONTRACT_TEST_STATIC_INV +#undef BOOST_CONTRACT_TEST_CV_INV +#undef BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/decl_static_const.cpp b/src/boost/libs/contract/test/invariant/decl_static_const.cpp new file mode 100644 index 00000000..7060c21c --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_static_const.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 all invariants (static, cv, and const-only). + +#define BOOST_CONTRACT_TEST_STATIC_INV +#undef BOOST_CONTRACT_TEST_CV_INV +#define BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/decl_static_cv.cpp b/src/boost/libs/contract/test/invariant/decl_static_cv.cpp new file mode 100644 index 00000000..a87be0f2 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_static_cv.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 all invariants (static, cv, and const-only). + +#define BOOST_CONTRACT_TEST_STATIC_INV +#define BOOST_CONTRACT_TEST_CV_INV +#undef BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/decl_static_cv_const.cpp b/src/boost/libs/contract/test/invariant/decl_static_cv_const.cpp new file mode 100644 index 00000000..a4c97760 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/decl_static_cv_const.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 all invariants (static, cv, and const-only). + +#define BOOST_CONTRACT_TEST_STATIC_INV +#define BOOST_CONTRACT_TEST_CV_INV +#define BOOST_CONTRACT_TEST_CONST_INV +#include "decl.hpp" + diff --git a/src/boost/libs/contract/test/invariant/ifdef.cpp b/src/boost/libs/contract/test/invariant/ifdef.cpp new file mode 100644 index 00000000..16ebf75f --- /dev/null +++ b/src/boost/libs/contract/test/invariant/ifdef.cpp @@ -0,0 +1,174 @@ + +// 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 invariant compilation on/off. + +#include "../detail/oteststream.hpp" +#include <boost/contract/constructor.hpp> +#include <boost/contract/destructor.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; + +class a { +public: + #ifndef BOOST_CONTRACT_NO_INVARIANTS + static void static_invariant() { + out << "a::static_inv" << std::endl; + } + + void invariant() const volatile { + out << "a::cv_inv" << std::endl; + } + + void invariant() const { + out << "a::const_inv" << std::endl; + } + #endif + + a() { // Test check both cv and const invariant (at exit if no throw). + #ifndef BOOST_CONTRACT_NO_CONSTRUCTORS + boost::contract::check c= boost::contract::constructor(this); + #endif + out << "a::ctor::body" << std::endl; + } + + ~a() { // Test check both cv and const invariant (at entry). + #ifndef BOOSTT_CONTRACT_NO_DESTRUCTORS + boost::contract::check c = boost::contract::destructor(this); + #endif + out << "a::dtor::body" << std::endl; + } + + void m() { // Test check const invariant (at entry and exit). + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + boost::contract::check c = boost::contract::public_function(this); + #endif + out << "a::m::body" << std::endl; + } + + void c() const { // Test check const invariant (at entry and exit). + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + boost::contract::check c = boost::contract::public_function(this); + #endif + out << "a::c::body" << std::endl; + } + + void v() volatile { // Test check cv invariant (at entry and exit). + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + boost::contract::check c = boost::contract::public_function(this); + #endif + out << "a::v::body" << std::endl; + } + + void cv() const volatile { // Test check cv invariant (at entry and exit). + #ifndef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + boost::contract::check c = boost::contract::public_function(this); + #endif + out << "a::cv::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + { + out.str(""); + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + << "a::const_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.m(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + << "a::m::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.c(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + << "a::c::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.v(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + << "a::v::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.cv(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + << "a::cv::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + } // Call dtor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + << "a::const_inv" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/invariant/ifdef_macro.cpp b/src/boost/libs/contract/test/invariant/ifdef_macro.cpp new file mode 100644 index 00000000..5955fa01 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/ifdef_macro.cpp @@ -0,0 +1,170 @@ + +// 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 invariant compilation on/off (using macro interface). + +#include "../detail/oteststream.hpp" +#include "../detail/unprotected_commas.hpp" +#include <boost/contract_macro.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +class a { +public: + BOOST_CONTRACT_STATIC_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::static_inv" << std::endl; + }) + + BOOST_CONTRACT_INVARIANT_VOLATILE({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::cv_inv" << std::endl; + }) + + BOOST_CONTRACT_INVARIANT({ + boost::contract::test::detail::unprotected_commas<void, void, void>:: + call(); + out << "a::const_inv" << std::endl; + }) + + a() { // Test check both cv and const invariant (at exit if no throw). + BOOST_CONTRACT_CONSTRUCTOR(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)); + out << "a::ctor::body" << std::endl; + } + + ~a() { // Test check both cv and const invariant (at entry). + BOOST_CONTRACT_DESTRUCTOR(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)); + out << "a::dtor::body" << std::endl; + } + + void m() { // Test check const invariant (at entry and exit). + BOOST_CONTRACT_PUBLIC_FUNCTION(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)); + out << "a::m::body" << std::endl; + } + + void c() const { // Test check const invariant (at entry and exit). + BOOST_CONTRACT_PUBLIC_FUNCTION(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)); + out << "a::c::body" << std::endl; + } + + void v() volatile { // Test check cv invariant (at entry and exit). + BOOST_CONTRACT_PUBLIC_FUNCTION(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)); + out << "a::v::body" << std::endl; + } + + void cv() const volatile { // Test check cv invariant (at entry and exit). + BOOST_CONTRACT_PUBLIC_FUNCTION(boost::contract::test::detail:: + unprotected_commas<void, void, void>::same(this)); + out << "a::cv::body" << std::endl; + } +}; + +int main() { + std::ostringstream ok; + + { + out.str(""); + a aa; + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + #endif + << "a::ctor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + << "a::const_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.m(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + << "a::m::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.c(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + << "a::c::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::const_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.v(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + << "a::v::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + aa.cv(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + << "a::cv::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + out.str(""); + } // Call dtor. + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "a::static_inv" << std::endl + << "a::cv_inv" << std::endl + << "a::const_inv" << std::endl + #endif + << "a::dtor::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "a::static_inv" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/invariant/mutable.hpp b/src/boost/libs/contract/test/invariant/mutable.hpp new file mode 100644 index 00000000..0940bc98 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/mutable.hpp @@ -0,0 +1,28 @@ + +// 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 non-static inv declared mutable (unless PERMISSIVE #defined). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> + +struct a { + void invariant() {} + + void f() { + // Same for ctor and dtor (because they all use check_pre_post_inv). + boost::contract::check c = boost::contract::public_function(this); + } +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/invariant/mutable_error.cpp b/src/boost/libs/contract/test/invariant/mutable_error.cpp new file mode 100644 index 00000000..97a26785 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/mutable_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 compiler error when invariant() not declared const. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "mutable.hpp" +#ifdef BOOST_CONTRACT_NO_INVARIANTS + #error "Forcing error even when invariants not checked" +#endif + diff --git a/src/boost/libs/contract/test/invariant/mutable_permissive.cpp b/src/boost/libs/contract/test/invariant/mutable_permissive.cpp new file mode 100644 index 00000000..fb098ee1 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/mutable_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 if invariant() not declared const. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "mutable.hpp" + diff --git a/src/boost/libs/contract/test/invariant/static.hpp b/src/boost/libs/contract/test/invariant/static.hpp new file mode 100644 index 00000000..75e4da3f --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static.hpp @@ -0,0 +1,28 @@ + +// 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 non-static inv declared static (unless PERMISSIVE #defined). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> + +struct a { + static void invariant() {} + + void f() { + // Same for ctor and dtor (because they all use check_pre_post_inv). + boost::contract::check c = boost::contract::public_function(this); + } +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/invariant/static_const.hpp b/src/boost/libs/contract/test/invariant/static_const.hpp new file mode 100644 index 00000000..ea2f9961 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_const.hpp @@ -0,0 +1,28 @@ + +// 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 static inv declared const (unless PERMISSIVE #defined). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> + +struct a { + void static_invariant() const {} + + void f() { + // Same for ctor and dtor (because they all use check_pre_post_inv). + boost::contract::check c = boost::contract::public_function(this); + } +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/invariant/static_const_error.cpp b/src/boost/libs/contract/test/invariant/static_const_error.cpp new file mode 100644 index 00000000..e9ef5e66 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_const_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 static inv declared const. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "static_const.hpp" +#ifdef BOOST_CONTRACT_NO_INVARIANTS + #error "Forcing error even when invariants not checked" +#endif + diff --git a/src/boost/libs/contract/test/invariant/static_const_permissive.cpp b/src/boost/libs/contract/test/invariant/static_const_permissive.cpp new file mode 100644 index 00000000..efe33407 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_const_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 static inv declared const. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "static_const.hpp" + diff --git a/src/boost/libs/contract/test/invariant/static_cv.hpp b/src/boost/libs/contract/test/invariant/static_cv.hpp new file mode 100644 index 00000000..bca082e2 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_cv.hpp @@ -0,0 +1,28 @@ + +// 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 static inv declared cv (unless PERMISSIVE #defined). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> + +struct a { + void static_invariant() const volatile {} + + void f() { + // Same for ctor and dtor (because they all use check_pre_post_inv). + boost::contract::check c = boost::contract::public_function(this); + } +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/invariant/static_cv_error.cpp b/src/boost/libs/contract/test/invariant/static_cv_error.cpp new file mode 100644 index 00000000..84f9ca0d --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_cv_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 static inv declared cv. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "static_cv.hpp" +#ifdef BOOST_CONTRACT_NO_INVARIANTS + #error "Forcing error even when invariants not checked" +#endif + diff --git a/src/boost/libs/contract/test/invariant/static_cv_permissive.cpp b/src/boost/libs/contract/test/invariant/static_cv_permissive.cpp new file mode 100644 index 00000000..9ffee38f --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_cv_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 static inv declared cv. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "static_cv.hpp" + diff --git a/src/boost/libs/contract/test/invariant/static_error.cpp b/src/boost/libs/contract/test/invariant/static_error.cpp new file mode 100644 index 00000000..eeaa85f2 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_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 compiler error if invariant() declared static. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "static.hpp" +#ifdef BOOST_CONTRACT_NO_INVARIANTS + #error "Forcing error even when invariants not checked" +#endif + diff --git a/src/boost/libs/contract/test/invariant/static_mutable.hpp b/src/boost/libs/contract/test/invariant/static_mutable.hpp new file mode 100644 index 00000000..1cf1f424 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_mutable.hpp @@ -0,0 +1,28 @@ + +// 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 static inv declared mutable (unless PERMISSIVE #defined). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> + +struct a { + void static_invariant() {} // Error (unless PERMISSIVE). + + void f() { + // Same for ctor and dtor (because they all use check_pre_post_inv). + boost::contract::check c = boost::contract::public_function(this); + } +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/invariant/static_mutable_error.cpp b/src/boost/libs/contract/test/invariant/static_mutable_error.cpp new file mode 100644 index 00000000..0e45af43 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_mutable_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 static inv declared mutable. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "static_mutable.hpp" +#ifdef BOOST_CONTRACT_NO_INVARIANTS + #error "Forcing error even when invariants not checked" +#endif + diff --git a/src/boost/libs/contract/test/invariant/static_mutable_permissive.cpp b/src/boost/libs/contract/test/invariant/static_mutable_permissive.cpp new file mode 100644 index 00000000..d6f6bcbb --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_mutable_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 error if permissive even when static inv declared mutable. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "static_mutable.hpp" + diff --git a/src/boost/libs/contract/test/invariant/static_permissive.cpp b/src/boost/libs/contract/test/invariant/static_permissive.cpp new file mode 100644 index 00000000..710240cb --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_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 compiler error if permissive even when invariant() declared static. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "static.hpp" + diff --git a/src/boost/libs/contract/test/invariant/static_volatile.hpp b/src/boost/libs/contract/test/invariant/static_volatile.hpp new file mode 100644 index 00000000..ba3bb351 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_volatile.hpp @@ -0,0 +1,28 @@ + +// 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 static inv declared volatile (unless PERMISSIVE #defined). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> + +struct a { + void static_invariant() volatile {} + + void f() { + // Same for ctor and dtor (because they all use check_pre_post_inv). + boost::contract::check c = boost::contract::public_function(this); + } +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/invariant/static_volatile_error.cpp b/src/boost/libs/contract/test/invariant/static_volatile_error.cpp new file mode 100644 index 00000000..66cc9d2c --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_volatile_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 static inv declared volatile. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "static_volatile.hpp" +#ifdef BOOST_CONTRACT_NO_INVARIANTS + #error "Forcing error even when invariants not checked" +#endif + diff --git a/src/boost/libs/contract/test/invariant/static_volatile_permissive.cpp b/src/boost/libs/contract/test/invariant/static_volatile_permissive.cpp new file mode 100644 index 00000000..fd92e273 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/static_volatile_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 error if permissive even when static inv declared volatile. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "static_volatile.hpp" + diff --git a/src/boost/libs/contract/test/invariant/volatile.hpp b/src/boost/libs/contract/test/invariant/volatile.hpp new file mode 100644 index 00000000..0e7ede02 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/volatile.hpp @@ -0,0 +1,28 @@ + +// 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 non-static inv declared volatile (unless PERMISSIVE #defined). + +#include <boost/contract/public_function.hpp> +#include <boost/contract/check.hpp> + +struct a { + void invariant() volatile {} + + void f() { + // Same for ctor and dtor (because they all use check_pre_post_inv). + boost::contract::check c = boost::contract::public_function(this); + } +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/invariant/volatile_error.cpp b/src/boost/libs/contract/test/invariant/volatile_error.cpp new file mode 100644 index 00000000..3372a35d --- /dev/null +++ b/src/boost/libs/contract/test/invariant/volatile_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 non-static inv declared volatile. + +#undef BOOST_CONTRACT_PERMISSIVE +#include "volatile.hpp" +#ifdef BOOST_CONTRACT_NO_INVARIANTS + #error "Forcing error even when invariants not checked" +#endif + diff --git a/src/boost/libs/contract/test/invariant/volatile_permissive.cpp b/src/boost/libs/contract/test/invariant/volatile_permissive.cpp new file mode 100644 index 00000000..a3d1b987 --- /dev/null +++ b/src/boost/libs/contract/test/invariant/volatile_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 non-static inv declared volatile. + +#ifndef BOOST_CONTRACT_PERMISSIVE + #error "build must define PERMISSIVE" +#endif +#include "volatile.hpp" + diff --git a/src/boost/libs/contract/test/old/auto.cpp b/src/boost/libs/contract/test/old/auto.cpp new file mode 100644 index 00000000..97dd87f7 --- /dev/null +++ b/src/boost/libs/contract/test/old/auto.cpp @@ -0,0 +1,38 @@ + +// 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 that OLD macro allows to use C++11 auto declarations. + +#include <boost/config.hpp> +#include <boost/contract/old.hpp> +#include <boost/type_traits.hpp> +#include <boost/static_assert.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() { + int x = -123; + auto old_x = BOOST_CONTRACT_OLDOF(x); + x = 123; + BOOST_STATIC_ASSERT((boost::is_same<decltype(old_x), + boost::contract::old_ptr<int> >::value)); + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST_EQ(*old_x, -123); + #endif + BOOST_TEST_EQ(x, 123); + + boost::contract::virtual_* v = 0; + char y = 'j'; + auto old_y = BOOST_CONTRACT_OLDOF(v, y); + y = 'k'; + BOOST_STATIC_ASSERT((boost::is_same<decltype(old_y), + boost::contract::old_ptr<char> >::value)); + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST_EQ(*old_y, 'j'); + #endif + BOOST_TEST_EQ(y, 'k'); + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/old/copyable_traits.cpp b/src/boost/libs/contract/test/old/copyable_traits.cpp new file mode 100644 index 00000000..3792c6fe --- /dev/null +++ b/src/boost/libs/contract/test/old/copyable_traits.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 specializations of old value copy type traits. + +#include <boost/contract/old.hpp> +#include <boost/type_traits.hpp> +#include <boost/noncopyable.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> + +template<typename T> +void f(T& x) { + // No OLDOF here so C++11 not required for this test. + boost::contract::old_ptr_if_copyable<T> old_x = boost::contract::make_old( + boost::contract::copy_old() ? x : boost::contract::null_old()); +} + +// Test copyable type but... +struct w { + w() {} + w(w const&) { BOOST_TEST(false); } // Test this doesn't get copied. +}; + +// ...never copy old values for type `w` (because its copy is too expensive). +namespace boost { namespace contract { + template<> + struct is_old_value_copyable<w> : boost::false_type {}; +} } // namespace + +// Test non-copyable type but... +struct p : private boost::noncopyable { // Non-copyable via Boost. + static bool copied; + p() : num_(new int(0)) {} + ~p() { delete num_; } +private: + int* num_; + friend struct boost::contract::old_value_copy<p>; +}; +bool p::copied = false; + +// ...still copy old values for type `p` (using a deep copy). +namespace boost { namespace contract { + template<> + struct old_value_copy<p> { + explicit old_value_copy(p const& old) { + *old_.num_ = *old.num_; // Deep copy pointed value. + p::copied = true; + } + + p const& old() const { return old_; } + + private: + p old_; + }; + + template<> + struct is_old_value_copyable<p> : boost::true_type {}; +} } // namespace + +// Non-copyable type so... +struct n { + n() {} +private: + n(n const&); // Non-copyable (but not via Boost). +}; + +// ...specialize `boost::is_copy_constructible` (no need for this on C++11). +namespace boost { namespace contract { + template<> + struct is_old_value_copyable<n> : boost::false_type {}; +} } // namespace + +int main() { + // NOTE: No test::detail::counter below because that is for copyable types. + + { + int x; // Test has copy ctor so copy olds. + f(x); + } + + { + w x; // Test has copy ctor but never copy olds (see TEST(...) above). + f(x); + } + + p::copied = false; + { + p x; // Test no copy ctor but still old copies. + f(x); + } + #ifndef BOOST_CONTRACT_NO_OLDS + BOOST_TEST(p::copied); + #else + BOOST_TEST(!p::copied); + #endif + + { + n x; // Test no copy ctor so no old copies. + f(x); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/old/if_copyable.cpp b/src/boost/libs/contract/test/old/if_copyable.cpp new file mode 100644 index 00000000..0c3738f3 --- /dev/null +++ b/src/boost/libs/contract/test/old/if_copyable.cpp @@ -0,0 +1,133 @@ + +// 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 values of non-copyable types. + +#include "if_copyable.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/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/noncopyable.hpp> +#include <boost/detail/lightweight_test.hpp> + +unsigned old_checks; + +template<typename T> +struct b { + virtual void next(T& x, boost::contract::virtual_* v = 0) { + boost::contract::old_ptr_if_copyable<T> old_x = + BOOST_CONTRACT_OLDOF(v, x); + boost::contract::check c = boost::contract::public_function(v, this) + .postcondition([&] { + if(old_x) { + BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); + ++old_checks; + } + }) + ; + ++x; + } + BOOST_CONTRACT_OVERRIDE(next) +}; + +template<typename T> +struct a + #define BASES public b<T> + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + virtual void next(T& x, boost::contract::virtual_* v = 0) /* override */ { + boost::contract::old_ptr_if_copyable<T> old_x = + BOOST_CONTRACT_OLDOF(v, x); + boost::contract::check c = boost::contract::public_function< + override_next>(v, &a::next, this, x) + .postcondition([&] { + if(old_x) { + BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); + ++old_checks; + } + }) + ; + ++x; + } + BOOST_CONTRACT_OVERRIDE(next) +}; + +template<typename T> +void next(T& x) { + boost::contract::old_ptr_if_copyable<T> old_x = BOOST_CONTRACT_OLDOF(x); + boost::contract::check c = boost::contract::function() + .postcondition([&] { + if(old_x) { + BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); + ++old_checks; + } + }) + ; + ++x; +} + +int main() { + int i = 1; // Test built-in copyable type. + cp c(1); // Test custom copyable type. + ncp n(1); // Test non-copyable type. + + // Test free functions (old values without `v`). + + unsigned cnt = + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + 1 + #else + 0 + #endif + ; + + old_checks = 0; + next(i); + BOOST_TEST_EQ(old_checks, cnt); + + old_checks = 0; + next(c); + BOOST_TEST_EQ(old_checks, cnt); + + old_checks = 0; + next(n); + BOOST_TEST_EQ(old_checks, 0u); + + // Test virtual functions (old values with `v`). + + cnt = + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + 2 + #else + 0 + #endif + ; + + a<int> ai; + old_checks = 0; + ai.next(i); + BOOST_TEST_EQ(old_checks, cnt); + + a<cp> ac; + old_checks = 0; + ac.next(c); + BOOST_TEST_EQ(old_checks, cnt); + + a<ncp> an; + old_checks = 0; + an.next(n); + BOOST_TEST_EQ(old_checks, 0u); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/old/if_copyable.hpp b/src/boost/libs/contract/test/old/if_copyable.hpp new file mode 100644 index 00000000..6bb6c1f8 --- /dev/null +++ b/src/boost/libs/contract/test/old/if_copyable.hpp @@ -0,0 +1,45 @@ + +#ifndef BOOST_CONTRACT_TEST_IF_COPYABLE_HPP_ +#define BOOST_CONTRACT_TEST_IF_COPYABLE_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 old values of non-copyable types. + +#define BOOST_CONTRACT_TEST_IF_COPYABLE_TYPE(class_) \ + public: \ + explicit class_(int value) : value_(value) {} \ + \ + friend class_& operator++(class_& me) { ++me.value_; return me; } \ + \ + friend bool operator>(class_ const& left, class_ const& right) { \ + return left.value_ > right.value_; \ + } \ + \ + friend bool operator==(class_ const& left, class_ const& right) { \ + return left.value_ == right.value_; \ + } \ + \ + friend class_ operator+(class_ const& left, class_ const& right) { \ + return class_(left.value_ + right.value_); \ + } \ + \ + private: \ + int value_; + +struct cp { // Copyable type. + BOOST_CONTRACT_TEST_IF_COPYABLE_TYPE(cp) +}; + +struct ncp { + BOOST_CONTRACT_TEST_IF_COPYABLE_TYPE(ncp) + +private: // Non (publicly) copyable type. + ncp(ncp const& other) : value_(other.value_) {} +}; + +#endif // #include guard + diff --git a/src/boost/libs/contract/test/old/if_copyable_error.cpp b/src/boost/libs/contract/test/old/if_copyable_error.cpp new file mode 100644 index 00000000..34b02973 --- /dev/null +++ b/src/boost/libs/contract/test/old/if_copyable_error.cpp @@ -0,0 +1,43 @@ + +// 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 forcing compiler error for old values of non-copyable types. + +#include "if_copyable.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/noncopyable.hpp> + + +template<typename T> +void next(T& x) { + boost::contract::old_ptr<T> old_x = BOOST_CONTRACT_OLDOF(x); + boost::contract::check c = boost::contract::function() + .postcondition([&] { + // No need to check `if(old_x) ...` here. + BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); + #ifdef BOOST_CONTRACT_NO_ALL + #error "force error if no contracts (ASSERT expands to nothing)" + #endif + }) + ; + ++x; +} + +int main() { + int i = 1; // Test built-in copyable type. + cp c(1); // Test custom copyable type. + ncp n(1); // Test non-copyable type. + + next(i); // OK. + next(c); // OK. + next(n); // Error. + + return 0; +} + diff --git a/src/boost/libs/contract/test/old/if_copyable_macro.cpp b/src/boost/libs/contract/test/old/if_copyable_macro.cpp new file mode 100644 index 00000000..ac31961a --- /dev/null +++ b/src/boost/libs/contract/test/old/if_copyable_macro.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 old values of non-copyable types (using macro interface). + +#include "if_copyable.hpp" +#include "../detail/unprotected_commas.hpp" +#include <boost/contract_macro.hpp> +#include <boost/noncopyable.hpp> +#include <boost/detail/lightweight_test.hpp> + +unsigned old_checks; + +template<typename T> +struct b { + virtual void next(T& x, boost::contract::virtual_* v = 0) { + BOOST_CONTRACT_OLD_PTR_IF_COPYABLE( + typename boost::contract::test::detail::unprotected_commas<T, 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_POSTCONDITION([&] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + if(old_x) { + BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); + ++old_checks; + } + }) + ; + ++x; + } + BOOST_CONTRACT_OVERRIDE(next) +}; + +template<typename T> +struct a + #define BASES public b<T> + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + virtual void next(T& x, boost::contract::virtual_* v = 0) /* override */ { + BOOST_CONTRACT_OLD_PTR_IF_COPYABLE( + typename boost::contract::test::detail::unprotected_commas<T, 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( + typename boost::contract::test::detail::unprotected_commas< + override_next, void, void>::type1 + )( + boost::contract::test::detail::unprotected_commas<void, void, + void>::same(v), + &a::next, + boost::contract::test::detail::unprotected_commas<void, void, + void>::same(this), + boost::contract::test::detail::unprotected_commas<void, void, + void>::same(x) + ) + BOOST_CONTRACT_POSTCONDITION([&] { + boost::contract::test::detail::unprotected_commas< + void, void, void>::call(); + if(old_x) { + BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); + ++old_checks; + } + }) + ; + ++x; + } + BOOST_CONTRACT_OVERRIDE(next) +}; + +template<typename T> +void next(T& x) { + BOOST_CONTRACT_OLD_PTR_IF_COPYABLE( + typename boost::contract::test::detail::unprotected_commas<T, void, + void>::type1 + )( + old_x, + (boost::contract::test::detail::unprotected_commas<void, void, + void>::same(x)) + ); + BOOST_CONTRACT_FUNCTION() + BOOST_CONTRACT_POSTCONDITION([&] { + boost::contract::test::detail::unprotected_commas<void, void, void> + ::call(); + if(old_x) { + BOOST_CONTRACT_ASSERT(x == *old_x + T(1)); + ++old_checks; + } + }) + ; + ++x; +} + +int main() { + int i = 1; // Test built-in copyable type. + cp c(1); // Test custom copyable type. + ncp n(1); // Test non-copyable type. + + // Test free functions (old values without `v`). + + unsigned cnt = + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + 1 + #else + 0 + #endif + ; + + old_checks = 0; + next(i); + BOOST_TEST_EQ(old_checks, cnt); + + old_checks = 0; + next(c); + BOOST_TEST_EQ(old_checks, cnt); + + old_checks = 0; + next(n); + BOOST_TEST_EQ(old_checks, 0u); + + // Test virtual functions (old values with `v`). + + cnt = + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + 2 + #else + 0 + #endif + ; + + a<int> ai; + old_checks = 0; + ai.next(i); + BOOST_TEST_EQ(old_checks, cnt); + + a<cp> ac; + old_checks = 0; + ac.next(c); + BOOST_TEST_EQ(old_checks, cnt); + + a<ncp> an; + old_checks = 0; + an.next(n); + BOOST_TEST_EQ(old_checks, 0u); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/old/no_macro.cpp b/src/boost/libs/contract/test/old/no_macro.cpp new file mode 100644 index 00000000..d715f6ec --- /dev/null +++ b/src/boost/libs/contract/test/old/no_macro.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_OLD_PTR_TYPE boost::contract::old_ptr +#include "no_macro.hpp" + diff --git a/src/boost/libs/contract/test/old/no_macro.hpp b/src/boost/libs/contract/test/old/no_macro.hpp new file mode 100644 index 00000000..1e75ac44 --- /dev/null +++ b/src/boost/libs/contract/test/old/no_macro.hpp @@ -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 old values without BOOST_CONTRACT_OLD macro. + +#ifndef BOOST_CONTRACT_TEST_OLD_PTR_TYPE + #error "must define BOOST_CONTRACT_TEST_OLD_PTR_TYPE" +#endif + +#include "../detail/oteststream.hpp" +#include "../detail/counter.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/public_function.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/assert.hpp> +#include <boost/contract/old.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> + +boost::contract::test::detail::oteststream out; + +struct i_tag; typedef boost::contract::test::detail::counter<i_tag, int> i_type; +struct j_tag; typedef boost::contract::test::detail::counter<j_tag, int> j_type; + +struct b { + virtual void swap(i_type& i, j_type& j, boost::contract::virtual_* v = 0); +}; + +void b::swap(i_type& i, j_type& j, boost::contract::virtual_* v) { + BOOST_CONTRACT_TEST_OLD_PTR_TYPE<i_type> old_i = boost::contract::make_old( + v, boost::contract::copy_old(v) ? + i_type::eval(i) + : + boost::contract::null_old() + ); + BOOST_CONTRACT_TEST_OLD_PTR_TYPE<j_type> old_j; + boost::contract::check c = boost::contract::public_function(v, this) + .precondition([&] { + out << "b::swap::pre" << std::endl; + BOOST_CONTRACT_ASSERT(i.value != j.value); + }) + .old([&] { + out << "b::swap::old" << std::endl; + old_j = boost::contract::make_old(v, boost::contract::copy_old(v) ? + j_type::eval(j) : boost::contract::null_old()); + }) + .postcondition([&] { + out << "b::swap::post" << std::endl; + BOOST_CONTRACT_ASSERT(i.value == old_j->value); + BOOST_CONTRACT_ASSERT(j.value == old_i->value); + }) + ; + assert(false); +} + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + void swap(i_type& i, j_type& j, boost::contract::virtual_* v = 0) + /* override */ { + boost::contract::check c = boost::contract::public_function< + override_swap>(v, &a::swap, this, i, j); + + out << "a::swap::body" << std::endl; + int t = i.value; + i.value = j.value; + j.value = t; + } + BOOST_CONTRACT_OVERRIDE(swap) +}; + +struct x_tag; +typedef boost::contract::test::detail::counter<x_tag, char> x_type; + +struct y_tag; +typedef boost::contract::test::detail::counter<y_tag, char> y_type; + +void swap(x_type& x, y_type& y) { + BOOST_CONTRACT_TEST_OLD_PTR_TYPE<x_type> old_x = boost::contract::make_old( + boost::contract::copy_old() ? + x_type::eval(x) + : + boost::contract::null_old() + ); + BOOST_CONTRACT_TEST_OLD_PTR_TYPE<y_type> old_y; + boost::contract::check c = boost::contract::function() + .precondition([&] { + out << "swap::pre" << std::endl; + BOOST_CONTRACT_ASSERT(x.value != y.value); + }) + .old([&] { + out << "swap::old" << std::endl; + old_y = boost::contract::make_old(boost::contract::copy_old() ? + y_type::eval(y) : boost::contract::null_old()); + }) + .postcondition([&] { + out << "swap::post" << std::endl; + BOOST_CONTRACT_ASSERT(x.value == old_y->value); + BOOST_CONTRACT_ASSERT(y.value == old_x->value); + }) + ; + + out << "swap::body" << std::endl; + char t = x.value; + x.value = y.value; + y.value = t; +} + +int main() { + std::ostringstream ok; + + out.str(""); + x_type x; x.value = 'a'; + y_type y; y.value = 'b'; + swap(x, y); + + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "swap::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "swap::old" << std::endl + #endif + << "swap::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "swap::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(x.value, 'b'); + BOOST_TEST_EQ(x.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(x.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(x.ctors(), x.dtors() + 1); // 1 for local var. + + BOOST_TEST_EQ(y.value, 'a'); + BOOST_TEST_EQ(y.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(y.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(y.ctors(), y.dtors() + 1); // 1 for local var. + + a aa; + i_type i; i.value = 1; + j_type j; j.value = 2; + out.str(""); + aa.swap(i, j); + + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "b::swap::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "b::swap::old" << std::endl + #endif + << "a::swap::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "b::swap::old" << std::endl + << "b::swap::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + BOOST_TEST_EQ(i.value, 2); + BOOST_TEST_EQ(i.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(i.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(i.ctors(), i.dtors() + 1); // 1 for local var. + + BOOST_TEST_EQ(j.value, 1); + BOOST_TEST_EQ(j.copies(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(j.evals(), BOOST_CONTRACT_TEST_old); + BOOST_TEST_EQ(j.ctors(), j.dtors() + 1); // 1 for local var. + + #undef BOOST_CONTRACT_TEST_old + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/old/no_macro_if_copyable.cpp b/src/boost/libs/contract/test/old/no_macro_if_copyable.cpp new file mode 100644 index 00000000..88c30c10 --- /dev/null +++ b/src/boost/libs/contract/test/old/no_macro_if_copyable.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_OLD_PTR_TYPE boost::contract::old_ptr_if_copyable +#include "no_macro.hpp" + diff --git a/src/boost/libs/contract/test/old/no_make_old_error.cpp b/src/boost/libs/contract/test/old/no_make_old_error.cpp new file mode 100644 index 00000000..7d517fa4 --- /dev/null +++ b/src/boost/libs/contract/test/old/no_make_old_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_OLD_PTR_TYPE boost::contract::old_ptr +#include "no_make_old_error.hpp" + diff --git a/src/boost/libs/contract/test/old/no_make_old_error.hpp b/src/boost/libs/contract/test/old/no_make_old_error.hpp new file mode 100644 index 00000000..d637fade --- /dev/null +++ b/src/boost/libs/contract/test/old/no_make_old_error.hpp @@ -0,0 +1,21 @@ + +// 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 when make_old(...) not used by mistake. + +#ifndef BOOST_CONTRACT_TEST_OLD_PTR_TYPE + #error "must define BOOST_CONTRACT_TEST_OLD_PTR_TYPE" +#endif + +#include <boost/contract/old.hpp> + +int main() { + int x = 1; + BOOST_CONTRACT_TEST_OLD_PTR_TYPE<int> old_x = boost::contract::copy_old() ? + x : boost::contract::null_old(); // Error (missing make_old(...)). + return 0; +} + diff --git a/src/boost/libs/contract/test/old/no_make_old_if_copyable_error.cpp b/src/boost/libs/contract/test/old/no_make_old_if_copyable_error.cpp new file mode 100644 index 00000000..4800fe8b --- /dev/null +++ b/src/boost/libs/contract/test/old/no_make_old_if_copyable_error.cpp @@ -0,0 +1,9 @@ + +// 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 + +#define BOOST_CONTRACT_TEST_OLD_PTR_TYPE boost::contract::old_ptr_if_copyable +#include "no_make_old_error.hpp" + 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(); +} + diff --git a/src/boost/libs/contract/test/result/mixed_optional.cpp b/src/boost/libs/contract/test/result/mixed_optional.cpp new file mode 100644 index 00000000..c2002007 --- /dev/null +++ b/src/boost/libs/contract/test/result/mixed_optional.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 base and derived classes mixing boost::optional and non- result types. + +#include "mixed_optional.hpp" + diff --git a/src/boost/libs/contract/test/result/mixed_optional.hpp b/src/boost/libs/contract/test/result/mixed_optional.hpp new file mode 100644 index 00000000..425941f1 --- /dev/null +++ b/src/boost/libs/contract/test/result/mixed_optional.hpp @@ -0,0 +1,410 @@ + +// 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 base and derived classes mixing boost::optional and non- result types. + +#include "../detail/oteststream.hpp" +#include "../detail/counter.hpp" +#include <boost/contract/base_types.hpp> +#include <boost/contract/public_function.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/check.hpp> +#include <boost/contract/assert.hpp> +#include <boost/optional.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/config.hpp> +#include <sstream> +#include <cassert> + +boost::contract::test::detail::oteststream out; + +struct ch_tag; +typedef boost::contract::test::detail::counter<ch_tag, char> ch_type; + +#ifdef BOOST_CONTRACT_TEST_REF // Test with result types by reference. + #define BOOST_CONTRACT_TEST_CH_TYPE ch_type& + #define BOOST_CONTRACT_TEST_CH_INIT = ch_init + ch_type ch_init; + unsigned const ch_extras = 2; // 1 local and 1 global var. +#else // Test with result types by value. + #define BOOST_CONTRACT_TEST_CH_TYPE ch_type + #define BOOST_CONTRACT_TEST_CH_INIT /* nothing */ + unsigned const ch_extras = 1; // 1 for local var (no global var). +#endif + +bool tested_d_copies = false; +struct d { + static void static_invariant() { out << "d::static_inv" << std::endl; } + void invariant() const { out << "d::inv" << std::endl; } + + virtual BOOST_CONTRACT_TEST_CH_TYPE f( + ch_type& ch, boost::contract::virtual_* v = 0) { + unsigned const old_ch_copies = ch_type::copies(); + boost::optional<BOOST_CONTRACT_TEST_CH_TYPE> result; + boost::contract::check c = boost::contract::public_function( + v, result, this) + .precondition([&] { + out << "d::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch.value == 'd'); + }) + .old([] { out << "d::f::old" << std::endl; }) + .postcondition([&] (boost::optional<ch_type const&> const& result) { + out << "d::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(result->value == ch.value); + }) + ; + BOOST_TEST_EQ(ch_type::copies(), old_ch_copies); + tested_d_copies = true; + + out << "d::f::body" << std::endl; + return *(result = ch); + } +}; + +bool tested_c_copies = false; +struct c + #define BASES public d + : 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; } + + virtual BOOST_CONTRACT_TEST_CH_TYPE f( + ch_type& ch, boost::contract::virtual_* v = 0) /* override */ { + unsigned const old_ch_copies = ch_type::copies(); + boost::optional<BOOST_CONTRACT_TEST_CH_TYPE> result; + boost::contract::check c = boost::contract::public_function<override_f>( + v, result, &c::f, this, ch) + .precondition([&] { + out << "c::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch.value == 'c'); + }) + .old([] { out << "c::f::old" << std::endl; }) + .postcondition([&] (boost::optional<ch_type const&> const& result) { + out << "c::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(result->value == ch.value); + }) + ; + BOOST_TEST_EQ(ch_type::copies(), old_ch_copies); + tested_c_copies = true; + + out << "c::f::body" << std::endl; + return *(result = ch); + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +bool tested_b_copies = false; +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 BOOST_CONTRACT_TEST_CH_TYPE f( + ch_type& ch, boost::contract::virtual_* v = 0) /* override */ { + unsigned const old_ch_copies = ch_type::copies(); + BOOST_CONTRACT_TEST_CH_TYPE result BOOST_CONTRACT_TEST_CH_INIT; + boost::contract::check c = boost::contract::public_function<override_f>( + v, result, &b::f, this, ch) + .precondition([&] { + out << "b::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch.value == 'b'); + }) + .old([] { out << "b::f::old" << std::endl; }) + .postcondition([&] (ch_type const& result) { + out << "b::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(result.value == ch.value); + }) + ; + BOOST_TEST_EQ(ch_type::copies(), old_ch_copies); + tested_b_copies = true; + + out << "b::f::body" << std::endl; + return result = ch; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +bool tested_a_copies = false; +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; } + + virtual BOOST_CONTRACT_TEST_CH_TYPE f( + ch_type& ch, boost::contract::virtual_* v = 0) /* override */ { + unsigned const old_ch_copies = ch_type::copies(); + boost::optional<BOOST_CONTRACT_TEST_CH_TYPE> result; + boost::contract::check c = boost::contract::public_function<override_f>( + v, result, &a::f, this, ch) + .precondition([&] { + out << "a::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch.value == 'a'); + }) + .old([] { out << "a::f::old" << std::endl; }) + .postcondition([&] (boost::optional<ch_type const&> const& result) { + out << "a::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(result->value == ch.value); + }) + ; + BOOST_TEST_EQ(ch_type::copies(), old_ch_copies); + tested_a_copies = true; + + out << "a::f::body" << std::endl; + return *(result = ch); + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +bool tested_e_copies = false; +struct e + #define BASES public b + : 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 BOOST_CONTRACT_TEST_CH_TYPE f( + ch_type& ch, boost::contract::virtual_* v = 0) /* override */ { + unsigned const old_ch_copies = ch_type::copies(); + BOOST_CONTRACT_TEST_CH_TYPE result BOOST_CONTRACT_TEST_CH_INIT; + boost::contract::check c = boost::contract::public_function<override_f>( + v, result, &e::f, this, ch) + .precondition([&] { + out << "e::f::pre" << std::endl; + BOOST_CONTRACT_ASSERT(ch.value == 'e'); + }) + .old([] { out << "e::f::old" << std::endl; }) + .postcondition([&] (ch_type const& result) { + out << "e::f::post" << std::endl; + BOOST_CONTRACT_ASSERT(result.value == ch.value); + }) + ; + BOOST_TEST_EQ(ch_type::copies(), old_ch_copies); + tested_e_copies = true; + + out << "e::f::body" << std::endl; + return result = ch; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + std::ostringstream ok; + ch_type ch; + #ifdef BOOST_CONTRACT_TEST_REF + ch_init.value = '\0'; + #endif + + // Test optional in overriding a::f and non-optional in overridden b::f. + a aa; + ch.value = 'a'; + out.str(""); + aa.f(ch); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "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 + << "d::f::pre" << std::endl + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + << "a::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "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 + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "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 + << "d::f::old" << std::endl + << "d::f::post" << std::endl + << "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_TEST(tested_a_copies); + BOOST_TEST_EQ(ch_type::ctors(), ch_type::dtors() + ch_extras); + + // Test non-optional in overriding b::f and optional in overridden c::f. + b bb; + ch.value = 'b'; + out.str(""); + bb.f(ch); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "c::f::old" << std::endl + << "b::f::old" << std::endl + #endif + << "b::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::f::old" << std::endl + << "d::f::post" << std::endl + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + BOOST_TEST(tested_b_copies); + BOOST_TEST_EQ(ch_type::ctors(), ch_type::dtors() + ch_extras); + + // Test optional in both overriding c::f and overridden d::f. + c cc; + ch.value = 'c'; + out.str(""); + cc.f(ch); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + << "c::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::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 + << "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 + << "c::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + BOOST_TEST(tested_c_copies); + BOOST_TEST_EQ(ch_type::ctors(), ch_type::dtors() + ch_extras); + + // Test non-optional in both overriding c::f and overridden d::f. + e ee; + ch.value = 'e'; + out.str(""); + ee.f(ch); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "d::f::pre" << std::endl + << "c::f::pre" << std::endl + << "b::f::pre" << std::endl + << "e::f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "d::f::old" << std::endl + << "c::f::old" << std::endl + << "b::f::old" << std::endl + << "e::f::old" << std::endl + #endif + << "e::f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS + << "d::static_inv" << std::endl + << "d::inv" << std::endl + << "c::static_inv" << std::endl + << "c::inv" << std::endl + << "b::static_inv" << std::endl + << "b::inv" << std::endl + << "e::static_inv" << std::endl + << "e::inv" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "d::f::old" << std::endl + << "d::f::post" << std::endl + << "c::f::old" << std::endl + << "c::f::post" << std::endl + << "b::f::old" << std::endl + << "b::f::post" << std::endl + << "e::f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + BOOST_TEST(tested_e_copies); + BOOST_TEST_EQ(ch_type::ctors(), ch_type::dtors() + ch_extras); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/result/mixed_optional_ref.cpp b/src/boost/libs/contract/test/result/mixed_optional_ref.cpp new file mode 100644 index 00000000..e7b2acc9 --- /dev/null +++ b/src/boost/libs/contract/test/result/mixed_optional_ref.cpp @@ -0,0 +1,11 @@ + +// 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 base and derived classes mixing boost::optional and non- result by ref. + +#define BOOST_CONTRACT_TEST_REF +#include "mixed_optional.hpp" + diff --git a/src/boost/libs/contract/test/result/type_mismatch_error.cpp b/src/boost/libs/contract/test/result/type_mismatch_error.cpp new file mode 100644 index 00000000..3e6180bd --- /dev/null +++ b/src/boost/libs/contract/test/result/type_mismatch_error.cpp @@ -0,0 +1,50 @@ + +// 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 override public function error on result type mismatch. + +#include <boost/contract/public_function.hpp> +#include <boost/contract/override.hpp> +#include <boost/contract/base_types.hpp> +#include <boost/contract/check.hpp> + +struct b { + virtual int f(boost::contract::virtual_* v = 0) { + // Unfortunately, this cannot be made to error at compile-time because + // in this case public_function does not that &b::f as param (but this + // will error at run-time on a virtual call via a derived class). + char result; + boost::contract::check c = boost::contract::public_function( + v, result, this); + return result; + } +}; + +struct a + #define BASES public b + : BASES +{ + typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; + #undef BASES + + virtual int f(boost::contract::virtual_* v = 0) /* override */ { + char result; + boost::contract::check c = boost::contract::public_function<override_f>( + v, result, &a::f, this); // Error (result time mismatch). + #ifdef BOOST_CONTRACT_NO_PUBLIC_FUNCTIONS + #error "Forcing error even when public functions not checked" + #endif + return result; + } + BOOST_CONTRACT_OVERRIDE(f) +}; + +int main() { + a aa; + aa.f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/specify/auto_error.cpp b/src/boost/libs/contract/test/specify/auto_error.cpp new file mode 100644 index 00000000..04990649 --- /dev/null +++ b/src/boost/libs/contract/test/specify/auto_error.cpp @@ -0,0 +1,24 @@ + +// Copyright (C) 2008-2018 Lorenzo Caminiti +// Distributed under the Boost Software License, Version 1.0 (see accompanying +// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt). +// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html + +// Test auto error (for free func, but same for all contracts). + +#include <boost/config.hpp> +// Not just __cplusplus to detect C++17 as MSVC defines it correctly sometimes. +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + !defined(BOOST_NO_CXX17_IF_CONSTEXPR) + #error "C++17 copy elision invalidates test so forcing expected failure" +#else + +#include <boost/contract/function.hpp> + +int main() { + auto c = boost::contract::function(); // Error (can't use auto). + return 0; +} + +#endif + diff --git a/src/boost/libs/contract/test/specify/auto_pre_error.cpp b/src/boost/libs/contract/test/specify/auto_pre_error.cpp new file mode 100644 index 00000000..1a5b7f60 --- /dev/null +++ b/src/boost/libs/contract/test/specify/auto_pre_error.cpp @@ -0,0 +1,26 @@ + +// 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 auto error after pre (for free func, but same for all contracts). + +#include <boost/config.hpp> +// Not just __cplusplus to detect C++17 as MSVC defines it correctly sometimes. +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + !defined(BOOST_NO_CXX17_IF_CONSTEXPR) + #error "C++17 copy elision invalidates test so forcing expected failure" +#else + +#include <boost/contract/function.hpp> + +int main() { + auto c = boost::contract::function() // Error (can't use auto). + .precondition([] {}) + ; + return 0; +} + +#endif + diff --git a/src/boost/libs/contract/test/specify/auto_pre_old_error.cpp b/src/boost/libs/contract/test/specify/auto_pre_old_error.cpp new file mode 100644 index 00000000..6c318769 --- /dev/null +++ b/src/boost/libs/contract/test/specify/auto_pre_old_error.cpp @@ -0,0 +1,27 @@ + +// 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 auto error after old (for free func, but same for all contracts). + +#include <boost/config.hpp> +// Not just __cplusplus to detect C++17 as MSVC defines it correctly sometimes. +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + !defined(BOOST_NO_CXX17_IF_CONSTEXPR) + #error "C++17 copy elision invalidates test so forcing expected failure" +#else + +#include <boost/contract/function.hpp> + +int main() { + auto c = boost::contract::function() // Error (can't use auto). + .precondition([] {}) + .old([] {}) + ; + return 0; +} + +#endif + diff --git a/src/boost/libs/contract/test/specify/auto_pre_old_post_error.cpp b/src/boost/libs/contract/test/specify/auto_pre_old_post_error.cpp new file mode 100644 index 00000000..6d0302ff --- /dev/null +++ b/src/boost/libs/contract/test/specify/auto_pre_old_post_error.cpp @@ -0,0 +1,28 @@ + +// 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 auto error after post (for free func, but same for all contracts). + +#include <boost/config.hpp> +// Not just __cplusplus to detect C++17 as MSVC defines it correctly sometimes. +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + !defined(BOOST_NO_CXX17_IF_CONSTEXPR) + #error "C++17 copy elision invalidates test so forcing expected failure" +#else + +#include <boost/contract/function.hpp> + +int main() { + auto c = boost::contract::function() // Error (can't use auto). + .precondition([] {}) + .old([] {}) + .postcondition([] {}) + ; + return 0; +} + +#endif + diff --git a/src/boost/libs/contract/test/specify/auto_pre_old_post_except_error.cpp b/src/boost/libs/contract/test/specify/auto_pre_old_post_except_error.cpp new file mode 100644 index 00000000..c51d3295 --- /dev/null +++ b/src/boost/libs/contract/test/specify/auto_pre_old_post_except_error.cpp @@ -0,0 +1,29 @@ + +// 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 auto error after except (for free func, but same for all contracts). + +#include <boost/config.hpp> +// Not just __cplusplus to detect C++17 as MSVC defines it correctly sometimes. +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + !defined(BOOST_NO_CXX17_IF_CONSTEXPR) + #error "C++17 copy elision invalidates test so forcing expected failure" +#else + +#include <boost/contract/function.hpp> + +int main() { + auto c = boost::contract::function() // Error (can't use auto). + .precondition([] {}) + .old([] {}) + .postcondition([] {}) + .except([] {}) + ; + return 0; +} + +#endif + diff --git a/src/boost/libs/contract/test/specify/except.cpp b/src/boost/libs/contract/test/specify/except.cpp new file mode 100644 index 00000000..791ba114 --- /dev/null +++ b/src/boost/libs/contract/test/specify/except.cpp @@ -0,0 +1,37 @@ + +// 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 specifying except, no pre, old, or post (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/except_old_error.cpp b/src/boost/libs/contract/test/specify/except_old_error.cpp new file mode 100644 index 00000000..ea865e84 --- /dev/null +++ b/src/boost/libs/contract/test/specify/except_old_error.cpp @@ -0,0 +1,23 @@ + +// 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 after except error (same if not free func). + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> + +void f() { + boost::contract::check c = boost::contract::function() + .except([] {}) + .old([] {}) // Error (old after except). + ; +} + +int main() { + f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/specify/except_post_error.cpp b/src/boost/libs/contract/test/specify/except_post_error.cpp new file mode 100644 index 00000000..5b9ef354 --- /dev/null +++ b/src/boost/libs/contract/test/specify/except_post_error.cpp @@ -0,0 +1,23 @@ + +// 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 post after except error (same if not free func). + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> + +void f() { + boost::contract::check c = boost::contract::function() + .except([] {}) + .postcondition([] {}) // Error (post after except). + ; +} + +int main() { + f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/specify/except_pre_error.cpp b/src/boost/libs/contract/test/specify/except_pre_error.cpp new file mode 100644 index 00000000..3b690662 --- /dev/null +++ b/src/boost/libs/contract/test/specify/except_pre_error.cpp @@ -0,0 +1,23 @@ + +// 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 pre after except error (same if not free func). + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> + +void f() { + boost::contract::check c = boost::contract::function() + .except([] {}) + .precondition([] {}) // Error (pre after except). + ; +} + +int main() { + f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/specify/missing_check.cpp b/src/boost/libs/contract/test/specify/missing_check.cpp new file mode 100644 index 00000000..7e6f01c0 --- /dev/null +++ b/src/boost/libs/contract/test/specify/missing_check.cpp @@ -0,0 +1,43 @@ + +// 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 missing contract check declaration gives run-time error. + +struct err {}; +#ifndef BOOST_CONTRACT_ON_MISSING_CHECK_DECL + #error "build must define ON_MISSING_CHECK_DECL=`{ throw err(); }`" +#endif + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() { + boost::contract::check c = boost::contract::function() // Test this is OK. + .precondition([] {}) + .old([] {}) + .postcondition([] {}) + ; + + try { + boost::contract::function() // Test no `check c = ...` errors. + .precondition([] {}) + .old([] {}) + .postcondition([] {}) + ; + #if !defined(BOOST_CONTRACT_NO_PRECONDITIONS) || \ + !defined(BOOST_CONTRACT_NO_POSTCONDITIONS) || \ + !defined(BOOST_CONTRACT_NO_INVARIANTS) + BOOST_TEST(false); // Error, must throw. + #endif + } catch(err const&) { + // OK, threw as expected. + } catch(...) { + BOOST_TEST(false); // Error, unexpected throw. + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/nothing.cpp b/src/boost/libs/contract/test/specify/nothing.cpp new file mode 100644 index 00000000..b14a7c0c --- /dev/null +++ b/src/boost/libs/contract/test/specify/nothing.cpp @@ -0,0 +1,32 @@ + +// 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 pre or post (for free func, but same for all contracts). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function(); + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); ok << "f::body" << std::endl; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/old.cpp b/src/boost/libs/contract/test/specify/old.cpp new file mode 100644 index 00000000..a064d5f9 --- /dev/null +++ b/src/boost/libs/contract/test/specify/old.cpp @@ -0,0 +1,39 @@ + +// 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 specifying old, no pre, post, or except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .old([] { out << "f::old" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/old_except.cpp b/src/boost/libs/contract/test/specify/old_except.cpp new file mode 100644 index 00000000..31af8066 --- /dev/null +++ b/src/boost/libs/contract/test/specify/old_except.cpp @@ -0,0 +1,41 @@ + +// 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 specifying old and except, no pre or post (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .old([] { out << "f::old" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/old_post.cpp b/src/boost/libs/contract/test/specify/old_post.cpp new file mode 100644 index 00000000..97f3eb02 --- /dev/null +++ b/src/boost/libs/contract/test/specify/old_post.cpp @@ -0,0 +1,44 @@ + +// 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 specifying old and post, no pre or except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/old_post_except.cpp b/src/boost/libs/contract/test/specify/old_post_except.cpp new file mode 100644 index 00000000..36259e60 --- /dev/null +++ b/src/boost/libs/contract/test/specify/old_post_except.cpp @@ -0,0 +1,45 @@ + +// 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 specifying old, post, and except, not pre (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/old_pre_error.cpp b/src/boost/libs/contract/test/specify/old_pre_error.cpp new file mode 100644 index 00000000..9d9548ce --- /dev/null +++ b/src/boost/libs/contract/test/specify/old_pre_error.cpp @@ -0,0 +1,23 @@ + +// 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 pre after old error (same if not free func). + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> + +void f() { + boost::contract::check c = boost::contract::function() + .old([] {}) + .precondition([] {}) // Error (pre after old). + ; +} + +int main() { + f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/specify/post.cpp b/src/boost/libs/contract/test/specify/post.cpp new file mode 100644 index 00000000..4930c238 --- /dev/null +++ b/src/boost/libs/contract/test/specify/post.cpp @@ -0,0 +1,39 @@ + +// 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 specifying post, no pre, old, or except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .postcondition([] { out << "f::post" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); ok + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/post_except.cpp b/src/boost/libs/contract/test/specify/post_except.cpp new file mode 100644 index 00000000..115ab6ef --- /dev/null +++ b/src/boost/libs/contract/test/specify/post_except.cpp @@ -0,0 +1,41 @@ + +// 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 specifying post and except, no pre or old (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .postcondition([] { out << "f::post" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/post_old_error.cpp b/src/boost/libs/contract/test/specify/post_old_error.cpp new file mode 100644 index 00000000..7a3361a7 --- /dev/null +++ b/src/boost/libs/contract/test/specify/post_old_error.cpp @@ -0,0 +1,23 @@ + +// 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 after post error (same if not free func). + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> + +void f() { + boost::contract::check c = boost::contract::function() + .postcondition([] {}) + .old([] {}) // Error (old after post). + ; +} + +int main() { + f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/specify/post_pre_error.cpp b/src/boost/libs/contract/test/specify/post_pre_error.cpp new file mode 100644 index 00000000..3e50b533 --- /dev/null +++ b/src/boost/libs/contract/test/specify/post_pre_error.cpp @@ -0,0 +1,23 @@ + +// 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 pre after post error (same if not free func). + +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> + +void f() { + boost::contract::check c = boost::contract::function() + .postcondition([] {}) + .precondition([] {}) // Error (pre after post). + ; +} + +int main() { + f(); + return 0; +} + diff --git a/src/boost/libs/contract/test/specify/pre.cpp b/src/boost/libs/contract/test/specify/pre.cpp new file mode 100644 index 00000000..4c02acd2 --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre.cpp @@ -0,0 +1,39 @@ + +// 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 specifying pre, no old, post, or except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/pre_except.cpp b/src/boost/libs/contract/test/specify/pre_except.cpp new file mode 100644 index 00000000..1e7095ce --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre_except.cpp @@ -0,0 +1,41 @@ + +// 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 specifying pre and except, no old or post (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/pre_old.cpp b/src/boost/libs/contract/test/specify/pre_old.cpp new file mode 100644 index 00000000..8c1cc763 --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre_old.cpp @@ -0,0 +1,44 @@ + +// 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 specifying pre and old, no post or except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .old([] { out << "f::old" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/pre_old_except.cpp b/src/boost/libs/contract/test/specify/pre_old_except.cpp new file mode 100644 index 00000000..99de5bc2 --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre_old_except.cpp @@ -0,0 +1,45 @@ + +// 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 specify pre, old, and except, no post (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .old([] { out << "f::old" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/pre_old_post.cpp b/src/boost/libs/contract/test/specify/pre_old_post.cpp new file mode 100644 index 00000000..0ea576f2 --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre_old_post.cpp @@ -0,0 +1,48 @@ + +// 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 specifying pre, old, and post, no except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/pre_old_post_except.cpp b/src/boost/libs/contract/test/specify/pre_old_post_except.cpp new file mode 100644 index 00000000..b6992906 --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre_old_post_except.cpp @@ -0,0 +1,49 @@ + +// 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 specifying pre, old, post, and except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .old([] { out << "f::old" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + #ifndef BOOST_CONTRACT_NO_OLDS + << "f::old" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/pre_post.cpp b/src/boost/libs/contract/test/specify/pre_post.cpp new file mode 100644 index 00000000..ecedebf5 --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre_post.cpp @@ -0,0 +1,44 @@ + +// 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 specifying pre and post, no old or except (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/contract/test/specify/pre_post_except.cpp b/src/boost/libs/contract/test/specify/pre_post_except.cpp new file mode 100644 index 00000000..1b22e2ec --- /dev/null +++ b/src/boost/libs/contract/test/specify/pre_post_except.cpp @@ -0,0 +1,45 @@ + +// 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 specify pre, post, and except, no old (same if not free func). + +#include "../detail/oteststream.hpp" +#include <boost/contract/function.hpp> +#include <boost/contract/check.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <sstream> + +boost::contract::test::detail::oteststream out; + +void f() { + boost::contract::check c = boost::contract::function() + .precondition([] { out << "f::pre" << std::endl; }) + .postcondition([] { out << "f::post" << std::endl; }) + .except([] { out << "f::except" << std::endl; }) + ; + out << "f::body" << std::endl; +} + +int main() { + std::ostringstream ok; + + out.str(""); + f(); + ok.str(""); + ok + #ifndef BOOST_CONTRACT_NO_PRECONDITIONS + << "f::pre" << std::endl + #endif + << "f::body" << std::endl + #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS + << "f::post" << std::endl + #endif + ; + BOOST_TEST(out.eq(ok.str())); + + return boost::report_errors(); +} + |