named_override.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. #include <boost/contract.hpp>
  6. #include <boost/optional.hpp>
  7. #include <cassert>
  8. //[named_override_pure_virtual_assert_false
  9. template<typename T>
  10. class generic_unary_pack {
  11. public:
  12. virtual void _1(T const& value, boost::contract::virtual_* v = 0) = 0;
  13. virtual T _1(boost::contract::virtual_* v = 0) const = 0;
  14. };
  15. template<typename T>
  16. void generic_unary_pack<T>::_1(T const& value, boost::contract::virtual_* v) {
  17. boost::contract::check c = boost::contract::public_function(v, this)
  18. .precondition([&] {
  19. BOOST_CONTRACT_ASSERT(false); // Defer preconditions to overrides.
  20. })
  21. ;
  22. assert(false);
  23. }
  24. /* ... */
  25. //]
  26. template<typename T>
  27. T generic_unary_pack<T>::_1(boost::contract::virtual_* v) const {
  28. boost::optional<T> result; // Do not assume T has default constructor.
  29. boost::contract::check c = boost::contract::public_function(v, result, this)
  30. .postcondition([&] (boost::optional<T const&> const& result) {
  31. BOOST_CONTRACT_ASSERT(*result == _1());
  32. })
  33. ;
  34. assert(false);
  35. return *result;
  36. }
  37. //[named_override
  38. template<typename T>
  39. class positive_unary_pack
  40. #define BASES public generic_unary_pack<T>
  41. : BASES
  42. {
  43. public:
  44. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  45. #undef BASES
  46. // BOOST_CONTRACT_OVERRIDE(_1) would generate reserved name `override__1`.
  47. BOOST_CONTRACT_NAMED_OVERRIDE(override1, _1) // Generate `override1`.
  48. virtual void _1(T const& value, boost::contract::virtual_* v = 0)
  49. /* override */ {
  50. // Use `override1` generated by BOOST_CONTRACT_NAMED_OVERRIDE above.
  51. boost::contract::check c = boost::contract::public_function<override1>(
  52. v,
  53. static_cast<void (positive_unary_pack::*)(T const&,
  54. boost::contract::virtual_*)>(&positive_unary_pack::_1),
  55. this,
  56. value
  57. )
  58. .precondition([&] {
  59. BOOST_CONTRACT_ASSERT(value > 0);
  60. })
  61. ;
  62. value1_ = value;
  63. }
  64. /* ... */
  65. //]
  66. virtual T _1(boost::contract::virtual_* v = 0) const /* override */ {
  67. T result; // Class default constructor already used T's default ctor.
  68. boost::contract::check c = boost::contract::public_function<override1>(
  69. v,
  70. result,
  71. static_cast<T (positive_unary_pack::*)(boost::contract::virtual_*)
  72. const>(&positive_unary_pack::_1),
  73. this
  74. )
  75. .postcondition([&] (T const& result) {
  76. BOOST_CONTRACT_ASSERT(result > 0);
  77. })
  78. ;
  79. return result = value1_;
  80. }
  81. private:
  82. T value1_;
  83. };
  84. int main() {
  85. positive_unary_pack<int> u;
  86. u._1(123);
  87. assert(u._1() == 123);
  88. return 0;
  89. }