no_lambdas_local_func.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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/local_function.hpp>
  7. #include <boost/bind.hpp>
  8. #include <cassert>
  9. class iarray :
  10. private boost::contract::constructor_precondition<iarray> {
  11. public:
  12. static void static_invariant() {
  13. BOOST_CONTRACT_ASSERT(instances() >= 0);
  14. }
  15. void invariant() const {
  16. BOOST_CONTRACT_ASSERT(size() <= capacity());
  17. }
  18. static void constructor_pre(unsigned const max, unsigned const count) {
  19. BOOST_CONTRACT_ASSERT(count <= max);
  20. }
  21. explicit iarray(unsigned max, unsigned count = 0) :
  22. boost::contract::constructor_precondition<iarray>(boost::bind(
  23. &iarray::constructor_pre, max, count)),
  24. values_(new int[max]),
  25. capacity_(max)
  26. {
  27. boost::contract::old_ptr<int> old_instances;
  28. void BOOST_LOCAL_FUNCTION(bind& old_instances) {
  29. old_instances = BOOST_CONTRACT_OLDOF(iarray::instances());
  30. } BOOST_LOCAL_FUNCTION_NAME(old)
  31. void BOOST_LOCAL_FUNCTION(const bind this_, const bind& count,
  32. const bind& old_instances) {
  33. BOOST_CONTRACT_ASSERT(this_->size() == count);
  34. BOOST_CONTRACT_ASSERT(this_->instances() == *old_instances + 1);
  35. } BOOST_LOCAL_FUNCTION_NAME(post)
  36. boost::contract::check c = boost::contract::constructor(this)
  37. .old(old).postcondition(post);
  38. for(unsigned i = 0; i < count; ++i) values_[i] = int();
  39. size_ = count;
  40. ++instances_;
  41. }
  42. virtual ~iarray() {
  43. boost::contract::old_ptr<int> old_instances;
  44. void BOOST_LOCAL_FUNCTION(const bind this_, bind& old_instances) {
  45. old_instances = BOOST_CONTRACT_OLDOF(this_->instances());
  46. } BOOST_LOCAL_FUNCTION_NAME(old)
  47. void BOOST_LOCAL_FUNCTION(const bind& old_instances) {
  48. BOOST_CONTRACT_ASSERT(iarray::instances() == *old_instances - 1);
  49. } BOOST_LOCAL_FUNCTION_NAME(post)
  50. boost::contract::check c = boost::contract::destructor(this)
  51. .old(old).postcondition(post);
  52. delete[] values_;
  53. --instances_;
  54. }
  55. virtual void push_back(int value, boost::contract::virtual_* v = 0) {
  56. boost::contract::old_ptr<unsigned> old_size;
  57. void BOOST_LOCAL_FUNCTION(const bind this_) {
  58. BOOST_CONTRACT_ASSERT(this_->size() < this_->capacity());
  59. } BOOST_LOCAL_FUNCTION_NAME(pre)
  60. void BOOST_LOCAL_FUNCTION(const bind v, const bind this_,
  61. bind& old_size) {
  62. old_size = BOOST_CONTRACT_OLDOF(v, this_->size());
  63. } BOOST_LOCAL_FUNCTION_NAME(old)
  64. void BOOST_LOCAL_FUNCTION(const bind this_, const bind& old_size) {
  65. BOOST_CONTRACT_ASSERT(this_->size() == *old_size + 1);
  66. } BOOST_LOCAL_FUNCTION_NAME(post)
  67. boost::contract::check c = boost::contract::public_function(v, this)
  68. .precondition(pre).old(old).postcondition(post);
  69. values_[size_++] = value;
  70. }
  71. unsigned capacity() const {
  72. // Check invariants.
  73. boost::contract::check c = boost::contract::public_function(this);
  74. return capacity_;
  75. }
  76. unsigned size() const {
  77. // Check invariants.
  78. boost::contract::check c = boost::contract::public_function(this);
  79. return size_;
  80. }
  81. static int instances() {
  82. // Check static invariants.
  83. boost::contract::check c = boost::contract::public_function<iarray>();
  84. return instances_;
  85. }
  86. private:
  87. int* values_;
  88. unsigned capacity_;
  89. unsigned size_;
  90. static int instances_;
  91. };
  92. int iarray::instances_ = 0;
  93. int main() {
  94. iarray a(3, 2);
  95. assert(a.capacity() == 3);
  96. assert(a.size() == 2);
  97. a.push_back('x');
  98. assert(a.size() == 3);
  99. return 0;
  100. }