1 ///////////////////////////////////////////////////////////
2 // Softwarebauelemente II, Aufgabe O3.1
3 //
4 // author: Stephan Brumme
5 // last changes: May 15, 2001
6
7
8 #include "House.h"
9
10 // needed for std::find
11 #include <algorithm>
12
13
14
15 CHouse::CHouse()
16 {
17 m_Set.empty();
18 m_itCursor = m_Set.begin();
19 }
20
21 CHouse::CHouse(const CHouse& house)
22 {
23 operator=(house);
24 }
25
26 // constructs a new house using its date of foundation (default: today)
27 CHouse::CHouse(const CDate& dtDateOfFoundation)
28 {
29 m_dtDateOfFoundation = dtDateOfFoundation;
30 m_Set.empty();
31 m_itCursor = m_Set.begin();
32 }
33
34
35 // show attributes
36 string CHouse::Show() const
37 {
38 ostringstream strOutput;
39
40 // some general information
41 strOutput << "The house was founded on " << m_dtDateOfFoundation.Show()
42 << " and consists of "
43 << m_Set.size() << " rooms: " << endl;
44
45 // stream all rooms
46 TSetConstCursor itCursor;
47
48 for (itCursor = m_Set.begin(); itCursor != m_Set.end(); itCursor++)
49 strOutput << " " << itCursor->Show() << endl;
50
51 return strOutput.str();
52 }
53
54
55 // shows all internal attributes
56 string CHouse::ShowDebug() const
57 {
58 ostringstream strOutput;
59
60 // print any information about this class
61 strOutput << "DEBUG info for 'CHouse'" << endl
62 << " m_dtDateOfFoundation=" << m_dtDateOfFoundation.Show() << endl
63 << " m_nCount=" << m_Set.size() << endl;
64
65 // stream all rooms
66 // this iterator needs to be const ...
67 TSetConstCursor itCursor;
68
69 strOutput << " m_vecSet=" << endl;
70 for (itCursor = m_Set.begin(); itCursor != m_Set.end(); itCursor++)
71 strOutput << " " << itCursor->Show() << endl;
72
73 return strOutput.str();
74 }
75
76
77 // validate a house
78 bool CHouse::ClassInvariant() const
79 {
80 // check date of foundation
81 if (!m_dtDateOfFoundation.ClassInvariant())
82 return false;
83
84 // empty set
85 if (m_Set.empty())
86 return true;
87
88 // no room should be held twice in the array
89 TSetConstCursor itCursor;
90 itCursor = m_Set.begin();
91
92 while (itCursor != m_Set.end())
93 {
94 // next room
95 itCursor++;
96
97 // look for exact copy
98 TSetConstCursor itFind;
99 itFind = std::find(itCursor, m_Set.end(), *itCursor);
100
101 // copy found ?
102 if (itFind != m_Set.end())
103 return false;
104 }
105
106 return true;
107 }
108
109
110 // copy constructor
111 CHouse& CHouse::operator =(const CHouse &house)
112 {
113 m_dtDateOfFoundation = house.m_dtDateOfFoundation;
114 m_itCursor = house.m_itCursor;
115 // container performs the whole copy internally
116 m_Set = house.m_Set;
117
118 return *this;
119 }
120
121
122 // virtual, see operator=
123 bool CHouse::Copy(const CBasicClass* pClass)
124 {
125 // cast to CHouse
126 CBasicClass *basic;
127 CHouse *house;
128 basic = const_cast<CBasicClass*>(pClass);
129 house = dynamic_cast<CHouse*>(basic);
130
131 // invalid class (is NULL when pClass is not a CHouse)
132 if (house == NULL || house == this)
133 return false;
134
135 // use non virtual reference based copy
136 // return value isn't needed
137 operator=(*house);
138
139 // we're done
140 return true;
141 }
142
143
144 // compare two houses
145 bool CHouse::operator ==(const CHouse &house) const
146 {
147 // compare date of foundation
148 if (!(m_dtDateOfFoundation == house.m_dtDateOfFoundation))
149 return false;
150
151 // find each room of the given house in our house
152 TSetConstCursor itCursor;
153 for (itCursor = house.m_Set.begin(); itCursor != house.m_Set.end(); itCursor++)
154 // I re-implement the find method because of keeping this method const
155 if (std::find(m_Set.begin(), m_Set.end(), *itCursor) == m_Set.end())
156 return false;
157
158 // all rooms were found
159 return true;
160 }
161
162
163 // virtual, see operator==
164 bool CHouse::EqualValue(const CBasicClass* pClass) const
165 {
166 // cast to CHouse
167 CBasicClass *basic;
168 CHouse *house;
169 basic = const_cast<CBasicClass*>(pClass);
170 house = dynamic_cast<CHouse*>(basic);
171
172 // invalid class (is NULL when pClass is not a CHouse)
173 if (house == NULL || house == this)
174 return false;
175
176 // use non virtual reference based copy
177 return operator==(*house);
178 }
179
180
181 // return date of foundation
182 CDate CHouse::GetDateOfFoundation() const
183 {
184 return m_dtDateOfFoundation;
185 }
186
187
188 // return number of stored rooms
189 int CHouse::Card() const
190 {
191 return m_Set.size();
192 }
193
194
195 // insert a new room into the set, TRUE if successful
196 // will fail if room already exists
197 bool CHouse::Insert(const CRoom &room)
198 {
199 // there must be some memory to grow the set
200 // and the room must not be part of the list
201 if (m_Set.size() < m_Set.max_size() &&
202 !Find(room))
203 {
204 // insert at the tail of the list
205 m_Set.push_back(room);
206 return true;
207 }
208 else
209 return false;
210 }
211
212
213 // return first stored room, TRUE if successful
214 bool CHouse::GetFirst(CRoom &room)
215 {
216 // set must not be empty
217 if (m_Set.empty())
218 return false;
219
220 // set cursor to first room
221 m_itCursor = m_Set.begin();
222 // get this room
223 room = *m_itCursor;
224
225 return true;
226 }
227
228
229 // return next room, TRUE if successful
230 bool CHouse::GetNext(CRoom &room)
231 {
232 // set must not be empty, end must not be reached
233 if (m_Set.empty() && m_itCursor != m_Set.end())
234 return false;
235
236 // iterate to next object
237 m_itCursor++;
238 // get this object
239 room = *m_itCursor;
240
241 return true;
242 }
243
244
245 // look for a room and set cursor, TRUE if successful
246 bool CHouse::Find(const CRoom &room)
247 {
248 // set must not be empty
249 if (m_Set.empty())
250 return false;
251
252 // create new iterator
253 TSetCursor itCursor;
254
255 // use STL's find
256 itCursor = std::find(m_Set.begin(), m_Set.end(), room);
257
258 // change m_itCursor if room was found
259 if (itCursor != m_Set.end())
260 {
261 m_itCursor = itCursor;
262 return true;
263 }
264 else
265 return false;
266 }
267
268
269 // return the room the cursor points to, TRUE if successful
270 bool CHouse::GetCurrent(CRoom &room) const
271 {
272 // set must not be empty
273 if (m_Set.empty())
274 return false;
275
276 // return current room
277 room = *m_itCursor;
278 return true;
279 }
280
281
282 // erase current room, TRUE if successful
283 bool CHouse::Scratch()
284 {
285 // set must not be empty
286 if (m_Set.empty())
287 return false;
288
289 // erase room, set cursor to next room
290 m_itCursor = m_Set.erase(m_itCursor);
291 return true;
292 }
293