protected.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright (C) 2008-2018 Lorenzo Caminiti
  2. // Distributed under the Boost Software License, Version 1.0 (see accompanying
  3. // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
  4. // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
  5. // Test overriding function never overrides protected function contract.
  6. #include "../detail/oteststream.hpp"
  7. #include <boost/contract/function.hpp>
  8. #include <boost/contract/public_function.hpp>
  9. #include <boost/contract/base_types.hpp>
  10. #include <boost/contract/check.hpp>
  11. #include <boost/detail/lightweight_test.hpp>
  12. #include <sstream>
  13. boost::contract::test::detail::oteststream out;
  14. struct b {
  15. static void static_invariant() { out << "b::static_inv" << std::endl; }
  16. void invariant() const { out << "b::inv" << std::endl; }
  17. protected:
  18. // NOTE: This is the correct way of programming contracts for overridden
  19. // protected and overriding public functions: Both must use virtual_
  20. // (otherwise C++ won't override because mismatching parameters), but
  21. // overridden protected does not use public_function.
  22. virtual void f(boost::contract::virtual_* /* v */ = 0) {
  23. boost::contract::check c = boost::contract::function()
  24. .precondition([] { out << "b::f::pre" << std::endl; })
  25. .old([] { out << "b::f::old" << std::endl; })
  26. .postcondition([] { out << "b::f::post" << std::endl; })
  27. ;
  28. out << "b::f::body" << std::endl;
  29. }
  30. };
  31. struct a
  32. #define BASES public b
  33. : BASES
  34. {
  35. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  36. #undef BASES
  37. static void static_invariant() { out << "a::static_inv" << std::endl; }
  38. void invariant() const { out << "a::inv" << std::endl; }
  39. void f(boost::contract::virtual_* v = 0) /* not override */ {
  40. // C++ func a::f overrides b::f, but contracts don't (so no override_f).
  41. boost::contract::check c = boost::contract::public_function(v, this)
  42. .precondition([] { out << "a::f::pre" << std::endl; })
  43. .old([] { out << "a::f::old" << std::endl; })
  44. .postcondition([] { out << "a::f::post" << std::endl; })
  45. ;
  46. out << "a::f::body" << std::endl;
  47. }
  48. };
  49. int main() {
  50. std::ostringstream ok;
  51. a aa;
  52. out.str("");
  53. aa.f();
  54. ok.str(""); ok
  55. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  56. << "a::static_inv" << std::endl
  57. << "a::inv" << std::endl
  58. #endif
  59. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  60. << "a::f::pre" << std::endl
  61. #endif
  62. #ifndef BOOST_CONTRACT_NO_OLDS
  63. << "a::f::old" << std::endl
  64. #endif
  65. << "a::f::body" << std::endl
  66. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  67. << "a::static_inv" << std::endl
  68. << "a::inv" << std::endl
  69. #endif
  70. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  71. << "a::f::post" << std::endl
  72. #endif
  73. ;
  74. BOOST_TEST(out.eq(ok.str()));
  75. return boost::report_errors();
  76. }