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