• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_observer_main
8 #include "observer/observer.hpp"
9 #include "observer/subject.hpp"
10 #include <boost/contract.hpp>
11 #include <cassert>
12 
13 int test_state; // For testing only.
14 
15 // Implement an actual subject.
16 class concrete_subject
17     #define BASES public subject
18     : BASES
19 {
20     friend class boost::contract::access;
21 
22     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Subcontracting.
23     #undef BASES
24 
25 public:
26     typedef int state; // Some state being observed.
27 
concrete_subject()28     concrete_subject() : state_() {
29         // Could have omitted contracts here (nothing to check).
30         boost::contract::check c = boost::contract::constructor(this);
31     }
32 
~concrete_subject()33     virtual ~concrete_subject() {
34         // Could have omitted contracts here (nothing to check).
35         boost::contract::check c = boost::contract::destructor(this);
36     }
37 
set_state(state const & new_state)38     void set_state(state const& new_state) {
39         // Could have omitted contracts here (nothing to check).
40         boost::contract::check c = boost::contract::public_function(this);
41 
42         state_ = new_state;
43         assert(state_ == test_state);
44         notify(); // Notify all observers.
45     }
46 
get_state() const47     state get_state() const {
48         // Could have omitted contracts here (nothing to check).
49         boost::contract::check c = boost::contract::public_function(this);
50         return state_;
51     }
52 
53 private:
54     state state_;
55 };
56 
57 // Implement an actual observer.
58 class concrete_observer
59     #define BASES public observer
60     : BASES
61 {
62     friend class boost::contract::access;
63 
64     typedef BOOST_CONTRACT_BASE_TYPES(BASES) base_types; // Subcontracting.
65     #undef BASES
66 
67     BOOST_CONTRACT_OVERRIDES(up_to_date_with_subject, update)
68 
69 public:
70     // Create concrete observer.
concrete_observer(concrete_subject const & subj)71     explicit concrete_observer(concrete_subject const& subj) :
72             subject_(subj), observed_state_() {
73         // Could have omitted contracts here (nothing to check).
74         boost::contract::check c = boost::contract::constructor(this);
75     }
76 
~concrete_observer()77     virtual ~concrete_observer() {
78         // Could have omitted contracts here (nothing to check).
79         boost::contract::check c = boost::contract::destructor(this);
80     }
81 
82     // Implement base virtual functions.
83 
up_to_date_with_subject(boost::contract::virtual_ * v=0) const84     bool up_to_date_with_subject(boost::contract::virtual_* v = 0)
85             const /* override */ {
86         bool result;
87         boost::contract::check c = boost::contract::public_function<
88             override_up_to_date_with_subject
89         >(v, result, &concrete_observer::up_to_date_with_subject, this);
90 
91         return result = true; // For simplicity, assume always up-to-date.
92     }
93 
update(boost::contract::virtual_ * v=0)94     void update(boost::contract::virtual_* v = 0) /* override */ {
95         boost::contract::check c = boost::contract::public_function<
96                 override_update>(v, &concrete_observer::update, this);
97 
98         observed_state_ = subject_.get_state();
99         assert(observed_state_ == test_state);
100     }
101 
102 private:
103     concrete_subject const& subject_;
104     concrete_subject::state observed_state_;
105 };
106 
main()107 int main() {
108     concrete_subject subj;
109     concrete_observer ob(subj);
110     subj.attach(&ob);
111 
112     subj.set_state(test_state = 123);
113     subj.set_state(test_state = 456);
114 
115     return 0;
116 }
117 //]
118 
119