friend.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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 friend functions (also forcing them to check invariants).
  6. #include "../detail/oteststream.hpp"
  7. #include <boost/contract/public_function.hpp>
  8. #include <boost/contract/function.hpp>
  9. #include <boost/contract/check.hpp>
  10. #include <boost/contract/assert.hpp>
  11. #include <boost/detail/lightweight_test.hpp>
  12. #include <sstream>
  13. boost::contract::test::detail::oteststream out;
  14. class y;
  15. class z;
  16. class x {
  17. public:
  18. void invariant() const {
  19. out << "x::inv" << std::endl;
  20. BOOST_CONTRACT_ASSERT(get() >= 0);
  21. }
  22. x() : value_(0) {}
  23. int get() const { return value_; }
  24. friend void f(x&, y&, int value);
  25. private:
  26. int value_;
  27. };
  28. class y {
  29. public:
  30. void invariant() const {
  31. out << "y::inv" << std::endl;
  32. BOOST_CONTRACT_ASSERT(get() >= 0);
  33. }
  34. y() : value_(0) {}
  35. int get() const { return value_; }
  36. friend void f(x&, y&, int value);
  37. private:
  38. int value_;
  39. };
  40. void f(x& a, y& b, int value) {
  41. boost::contract::check post = boost::contract::function()
  42. .postcondition([&] {
  43. out << "f::post" << std::endl;
  44. BOOST_CONTRACT_ASSERT(a.get() == value);
  45. BOOST_CONTRACT_ASSERT(b.get() == value);
  46. })
  47. ;
  48. boost::contract::check inv_b = boost::contract::public_function(&b);
  49. boost::contract::check inv_a = boost::contract::public_function(&a);
  50. boost::contract::check pre = boost::contract::function()
  51. .precondition([&] {
  52. out << "f::pre" << std::endl;
  53. BOOST_CONTRACT_ASSERT(value > 0);
  54. })
  55. ;
  56. out << "f::body" << std::endl;
  57. a.value_ = b.value_ = value;
  58. }
  59. int main() {
  60. std::ostringstream ok;
  61. x a;
  62. y b;
  63. out.str("");
  64. f(a, b, 123);
  65. ok.str(""); ok
  66. #ifndef BOOST_CONTRACT_NO_ENTRY_INVARIANTS
  67. << "y::inv" << std::endl
  68. << "x::inv" << std::endl
  69. #endif
  70. #ifndef BOOST_CONTRACT_NO_PRECONDITIONS
  71. << "f::pre" << std::endl
  72. #endif
  73. << "f::body" << std::endl
  74. #ifndef BOOST_CONTRACT_NO_EXIT_INVARIANTS
  75. << "x::inv" << std::endl
  76. << "y::inv" << std::endl
  77. #endif
  78. #ifndef BOOST_CONTRACT_NO_POSTCONDITIONS
  79. << "f::post" << std::endl
  80. #endif
  81. ;
  82. BOOST_TEST(out.eq(ok.str()));
  83. BOOST_TEST_EQ(a.get(), 123);
  84. BOOST_TEST_EQ(b.get(), 123);
  85. return boost::report_errors();
  86. }