1 #include<iostream>
2 #include<string>
3 #include<set>
4 using namespace std;
5
6 class Folder;
7
8 class Message {
9 friend void swap(Message&, Message&);
10 friend class Folder;
11 public:
12 explicit Message(const string &str = ""): contents(str) {}
13 Message(const Message&);
14 Message& operator=(const Message&);
15 ~Message();
16
17 Message(Message&&);
18 Message& operator=(Message&&);
19
20 void save(Folder&);
21 void remove(Folder&);
22 void debug_print();
23
24 private:
25 string contents;
26 set<Folder*> folders;
27
28 void add_to_Folders(const Message&);
29 void move_Folders(Message*);
30
31 void remove_from_Folders();
32
33
34 void addFldr(Folder *f) { folders.insert(f); }
35 void remFldr(Folder *f) { folders.erase(f); }
36 };
37
38
39 class Folder {
40 friend void swap(Message&, Message&);
41 friend class Message;
42 public:
43 Folder() = default;
44 Folder(const Folder&);
45 Folder& operator=(const Folder&);
46
47 Folder(Folder&&);
48 Folder& operator=(Folder&&);
49 ~Folder();
50
51 void save(Message&);
52 void remove(Message&);
53 void debug_print();
54
55 private:
56 set<Message*> msgs;
57
58 void add_to_Messages(const Folder&);
59 void remove_from_Msgs();
60 void addMsg(Message *m) { msgs.insert(m); }
61 void remMsg(Message *m) { msgs.erase(m); }
62 void move_Messages(Folder*);
63
64 };
65
66 /*********************************************************************/
67 Message::Message(const Message &m) : contents(m.contents), folders(m.folders)
68 {
69 add_to_Folders(m);
70 }
71
72 void Message::add_to_Folders(const Message &m)
73 {
74 for (auto f : m.folders)
75 f->addMsg(this);
76 }
77
78 Message& Message::operator=(const Message &rhs)
79 {
80 remove_from_Folders();
81 contents = rhs.contents;
82 folders = rhs.folders;
83 add_to_Folders(rhs);
84 return *this;
85 }
86
87 void Message::remove_from_Folders()
88 {
89 for (auto f : folders)
90 f->remMsg(this);
91 folders.clear();
92 }
93
94 Message::Message(Message &&m) : contents(std::move(m.contents))
95 {
96 move_Folders(&m);
97 }
98
99 Message& Message::operator=(Message &&rhs)
100 {
101 if (this != &rhs)
102 {
103 remove_from_Folders();
104 contents = std::move(rhs.contents);
105 }
106 return *this;
107 }
108
109 Message::~Message()
110 {
111 remove_from_Folders();
112 }
113
114 void Message::save(Folder &f)
115 {
116 folders.insert(&f);
117 f.addMsg(this);
118 }
119
120 void Message::remove(Folder &f)
121 {
122 folders.erase(&f);
123 f.remMsg(this);
124 }
125
126 void Message::debug_print()
127 {
128 cerr << "Message:\n\t" << contents << endl;
129 cerr << "Appears in " << folders.size() << " Folders" << endl;
130 }
131
132 Folder::Folder(Folder &&f)
133 {
134 move_Messages(&f);
135 }
136
137 void Message::move_Folders(Message *m)
138 {
139 folders = std::move(m->folders);
140 for (auto f : folders)
141 {
142 f->remMsg(m);
143 f->addMsg(this);
144 }
145 m->folders.clear();
146 }
147
148 void swap(Message &lhs, Message &rhs)
149 {
150 using std::swap;
151 for (auto f : lhs.folders)
152 f->remMsg(&lhs);
153 for (auto f : rhs.folders)
154 f->remMsg(&rhs);
155 swap(lhs.folders, rhs.folders);
156 swap(lhs.contents, rhs.contents);
157 for (auto f : lhs.folders)
158 f->addMsg(&lhs);
159 for (auto f : rhs.folders)
160 f->addMsg(&rhs);
161 }
162
163 /*********************************************************************/
164
165 Folder::Folder(Folder &&f)
166 {
167 move_Messages(&f);
168 }
169
170 Folder& Folder::operator=(Folder &&f)
171 {
172 if (this != &f) {
173 remove_from_Msgs();
174 move_Messages(&f);
175 }
176 return *this;
177 }
178
179 Folder::Folder(const Folder &f) : msgs(f.msgs)
180 {
181 add_to_Messages(f);
182 }
183
184 void Folder::add_to_Messages(const Folder &f)
185 {
186 for (auto msg : f.msgs)
187 msg->addFldr(this);
188 }
189
190 Folder& Folder::operator=(const Folder &f)
191 {
192 remove_from_Msgs();
193 msgs = f.msgs;
194 add_to_Messages(f);
195 return *this;
196 }
197
198 void Folder::remove_from_Msgs()
199 {
200 while (!msgs.empty())
201 (*msgs.begin())->remove(*this);
202 }
203
204 Folder::~Folder()
205 {
206 remove_from_Msgs();
207 }
208
209 void Folder::save(Message &m)
210 {
211 msgs.insert(&m);
212 m.addFldr(this);
213 }
214
215 void Folder::remove(Message &m)
216 {
217 msgs.erase(&m);
218 m.remFldr(this);
219 }
220
221 void Folder::debug_print()
222 {
223 cerr << "Folder contains " << msgs.size() << " messages" << endl;
224 int ctr = 1;
225 for (auto m : msgs)
226 {
227 cerr << "Message " << ctr++ << ":\n\t" << m->contents << endl;
228 }
229 }
230
231
232 int main()
233 {
234 string s1("contents1");
235 string s2("contents2");
236 string s3("contents3");
237 string s4("contents4");
238 string s5("contents5");
239 string s6("contents6");
240
241 Message m1(s1);
242 Message m2(s2);
243 Message m3(s3);
244 Message m4(s4);
245 Message m5(s5);
246 Message m6(s6);
247
248 Folder f1;
249 Folder f2;
250
251 m1.save(f1); m3.save(f1); m5.save(f1);
252 m1.save(f2);
253 m2.save(f2); m4.save(f2); m6.save(f2);
254
255 m1.debug_print();
256 f2.debug_print();
257
258 Message c1(m1);
259 Message c2(m2), c4(m4), c6(m6);
260
261 m1.debug_print();
262 f2.debug_print();
263
264 m2 = m3;
265 m4 = m5;
266 m6 = m3;
267 m1 = m5;
268
269 m1.debug_print();
270 f2.debug_print();
271
272 m2 = m2;
273 m1 = m1;
274
275 m1.debug_print();
276 f2.debug_print();
277
278 vector<Message> vm;
279 cout << "capacity: " << vm.capacity() << endl;
280 vm.push_back(m1);
281
282 cout << "capacity: " << vm.capacity() << endl;
283 vm.push_back(m2);
284
285 cout << "capacity: " << vm.capacity() << endl;
286 vm.push_back(m3);
287
288 cout << "capacity: " << vm.capacity() << endl;
289 vm.push_back(m4);
290
291 cout << "capacity: " << vm.capacity() << endl;
292 vm.push_back(m5);
293
294 cout << "capacity: " << vm.capacity() << endl;
295 vm.push_back(m6);
296
297 vector<Folder> vf;
298 cout << "capacity: " << vf.capacity() << endl;
299 vf.push_back(f1);
300
301 cout << "capacity: " << vf.capacity() << endl;
302 vf.push_back(f2);
303
304 cout << "capacity: " << vf.capacity() << endl;
305 vf.push_back(Folder(f1));
306
307 cout << "capacity: " << vf.capacity() << endl;
308 vf.push_back(Folder(f2));
309
310 cout << "capacity: " << vf.capacity() << endl;
311 vf.push_back(Folder());
312
313 Folder f3;
314 f3.save(m6);
315 cout << "capacity: " << vf.capacity() << endl;
316 vf.push_back(f3);
317 return 0;
318 }