stack.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. //[cline90_stack
  6. #include <boost/contract.hpp>
  7. #include <cassert>
  8. // NOTE: Incomplete contract assertions, addressing only `empty` and `full`.
  9. template<typename T>
  10. class stack
  11. #define BASES private boost::contract::constructor_precondition<stack<T> >
  12. : BASES
  13. {
  14. friend class boost::contract::access;
  15. typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
  16. #undef BASES
  17. public:
  18. explicit stack(int capacity) :
  19. boost::contract::constructor_precondition<stack>([&] {
  20. BOOST_CONTRACT_ASSERT(capacity >= 0);
  21. }),
  22. data_(new T[capacity]), capacity_(capacity), size_(0)
  23. {
  24. boost::contract::check c = boost::contract::constructor(this)
  25. .postcondition([&] {
  26. BOOST_CONTRACT_ASSERT(empty());
  27. BOOST_CONTRACT_ASSERT(full() == (capacity == 0));
  28. })
  29. ;
  30. for(int i = 0; i < capacity_; ++i) data_[i] = T();
  31. }
  32. virtual ~stack() {
  33. boost::contract::check c = boost::contract::destructor(this);
  34. delete[] data_;
  35. }
  36. bool empty() const {
  37. boost::contract::check c = boost::contract::public_function(this);
  38. return size_ == 0;
  39. }
  40. bool full() const {
  41. boost::contract::check c = boost::contract::public_function(this);
  42. return size_ == capacity_;
  43. }
  44. void push(T const& value) {
  45. boost::contract::check c = boost::contract::public_function(this)
  46. .precondition([&] {
  47. BOOST_CONTRACT_ASSERT(!full());
  48. })
  49. .postcondition([&] {
  50. BOOST_CONTRACT_ASSERT(!empty());
  51. })
  52. ;
  53. data_[size_++] = value;
  54. }
  55. T pop() {
  56. boost::contract::check c = boost::contract::public_function(this)
  57. .precondition([&] {
  58. BOOST_CONTRACT_ASSERT(!empty());
  59. })
  60. .postcondition([&] {
  61. BOOST_CONTRACT_ASSERT(!full());
  62. })
  63. ;
  64. return data_[--size_];
  65. }
  66. private:
  67. T* data_;
  68. int capacity_;
  69. int size_;
  70. };
  71. int main() {
  72. stack<int> s(3);
  73. s.push(123);
  74. assert(s.pop() == 123);
  75. return 0;
  76. }
  77. //]