1 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 6 7 //[mitchell02_decrement_button 8 #ifndef DECREMENT_BUTTON_HPP_ 9 #define DECREMENT_BUTTON_HPP_ 10 11 #include "push_button.hpp" 12 #include "counter.hpp" 13 #include "../observer/observer.hpp" 14 #include <boost/contract.hpp> 15 #include <boost/noncopyable.hpp> 16 17 class decrement_button 18 #define BASES public push_button, public observer, \ 19 private boost::noncopyable 20 : BASES 21 { 22 friend class boost::contract::access; 23 24 typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; 25 #undef BASES 26 27 BOOST_CONTRACT_OVERRIDES(on_bn_clicked, up_to_date_with_subject, update); 28 29 public: 30 /* Creation */ 31 decrement_button(counter & a_counter)32 explicit decrement_button(counter& a_counter) : counter_(a_counter) { 33 boost::contract::check c = boost::contract::constructor(this) 34 .postcondition([&] { 35 // Enable iff positive value. 36 BOOST_CONTRACT_ASSERT(enabled() == (a_counter.value() > 0)); 37 }) 38 ; 39 counter_.attach(this); 40 } 41 42 // Destroy button. ~decrement_button()43 virtual ~decrement_button() { 44 // Could have omitted contracts here (nothing to check). 45 boost::contract::check c = boost::contract::destructor(this); 46 } 47 48 /* Commands */ 49 on_bn_clicked(boost::contract::virtual_ * v=0)50 virtual void on_bn_clicked(boost::contract::virtual_* v = 0) 51 /* override */ { 52 boost::contract::old_ptr<int> old_value = 53 BOOST_CONTRACT_OLDOF(v, counter_.value()); 54 boost::contract::check c = boost::contract::public_function< 55 override_on_bn_clicked 56 >(v, &decrement_button::on_bn_clicked, this) 57 .postcondition([&] { 58 // Counter decremented. 59 BOOST_CONTRACT_ASSERT(counter_.value() == *old_value - 1); 60 }) 61 ; 62 counter_.decrement(); 63 } 64 up_to_date_with_subject(boost::contract::virtual_ * v=0) const65 virtual bool up_to_date_with_subject(boost::contract::virtual_* v = 0) 66 const /* override */ { 67 bool result; 68 boost::contract::check c = boost::contract::public_function< 69 override_up_to_date_with_subject 70 >(v, result, &decrement_button::up_to_date_with_subject, this); 71 72 return result = true; // For simplicity, assume always up-to-date. 73 } 74 update(boost::contract::virtual_ * v=0)75 virtual void update(boost::contract::virtual_* v = 0) /* override */ { 76 boost::contract::check c = boost::contract::public_function< 77 override_update>(v, &decrement_button::update, this) 78 .postcondition([&] { 79 // Enabled iff positive value. 80 BOOST_CONTRACT_ASSERT(enabled() == (counter_.value() > 0)); 81 }) 82 ; 83 84 if(counter_.value() == 0) disable(); 85 else enable(); 86 } 87 88 private: 89 counter& counter_; 90 }; 91 92 #endif // #include guard 93 //] 94 95