2 // Copyright (C) 2008-2018 Lorenzo Caminiti
3 // Distributed under the Boost Software License, Version 1.0 (see accompanying
4 // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
5 // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
12 #include <boost/contract.hpp>
14 // Dispenser with LIFO access policy and fixed max capacity.
17 #define BASES private boost::contract::constructor_precondition<stack4<T> >
20 friend boost::contract::access;
21 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types;
24 void invariant() const {
25 BOOST_CONTRACT_ASSERT(count() >= 0); // Count non-negative.
26 BOOST_CONTRACT_ASSERT(count() <= capacity()); // Count bounded.
27 BOOST_CONTRACT_ASSERT(empty() == (count() == 0)); // Empty if no elem.
33 // Allocate static from a maximum of n elements.
34 explicit stack4(int n) :
35 boost::contract::constructor_precondition<stack4>([&] {
36 BOOST_CONTRACT_ASSERT(n >= 0); // Non-negative capacity.
39 boost::contract::check c = boost::contract::constructor(this)
41 BOOST_CONTRACT_ASSERT(capacity() == n); // Capacity set.
50 // Deep copy via constructor.
51 /* implicit */ stack4(stack4 const& other) {
52 boost::contract::check c = boost::contract::constructor(this)
54 BOOST_CONTRACT_ASSERT(capacity() == other.capacity());
55 BOOST_CONTRACT_ASSERT(count() == other.count());
56 BOOST_CONTRACT_ASSERT_AXIOM(*this == other);
60 capacity_ = other.capacity_;
61 count_ = other.count_;
62 array_ = new T[other.capacity_];
63 for(int i = 0; i < other.count_; ++i) array_[i] = other.array_[i];
66 // Deep copy via assignment.
67 stack4& operator=(stack4 const& other) {
68 boost::contract::check c = boost::contract::public_function(this)
70 BOOST_CONTRACT_ASSERT(capacity() == other.capacity());
71 BOOST_CONTRACT_ASSERT(count() == other.count());
72 BOOST_CONTRACT_ASSERT_AXIOM(*this == other);
77 capacity_ = other.capacity_;
78 count_ = other.count_;
79 array_ = new T[other.capacity_];
80 for(int i = 0; i < other.count_; ++i) array_[i] = other.array_[i];
84 // Destroy this stack.
87 boost::contract::check c = boost::contract::destructor(this);
93 // Max number of stack elements.
94 int capacity() const {
96 boost::contract::check c = boost::contract::public_function(this);
100 // Number of stack elements.
103 boost::contract::check c = boost::contract::public_function(this);
108 T const& item() const {
109 boost::contract::check c = boost::contract::public_function(this)
111 BOOST_CONTRACT_ASSERT(!empty()); // Not empty (i.e., count > 0).
115 return array_[count_ - 1];
123 boost::contract::check c = boost::contract::public_function(this)
126 BOOST_CONTRACT_ASSERT(result == (count() == 0));
130 return result = (count_ == 0);
136 boost::contract::check c = boost::contract::public_function(this)
138 BOOST_CONTRACT_ASSERT( // Full definition.
139 result == (count() == capacity()));
143 return result = (count_ == capacity_);
149 void put(T const& x) {
150 boost::contract::old_ptr<int> old_count = BOOST_CONTRACT_OLDOF(count());
151 boost::contract::check c = boost::contract::public_function(this)
153 BOOST_CONTRACT_ASSERT(!full()); // Not full.
156 BOOST_CONTRACT_ASSERT(!empty()); // Not empty.
157 BOOST_CONTRACT_ASSERT(item() == x); // Added to top.
158 BOOST_CONTRACT_ASSERT(count() == *old_count + 1); // One more.
162 array_[count_++] = x;
165 // Remove top element.
167 boost::contract::old_ptr<int> old_count = BOOST_CONTRACT_OLDOF(count());
168 boost::contract::check c = boost::contract::public_function(this)
170 BOOST_CONTRACT_ASSERT(!empty()); // Not empty (i.e., count > 0).
173 BOOST_CONTRACT_ASSERT(!full()); // Not full.
174 BOOST_CONTRACT_ASSERT(count() == *old_count - 1); // One less.
183 friend bool operator==(stack4 const& left, stack4 const& right) {
184 boost::contract::check inv1 = boost::contract::public_function(&left);
185 boost::contract::check inv2 = boost::contract::public_function(&right);
186 if(left.count_ != right.count_) return false;
187 for(int i = 0; i < left.count_; ++i) {
188 if(left.array_[i] != right.array_[i]) return false;
196 T* array_; // Internally use C-style array.
199 #endif // #include guard