Skip to content

Commit

Permalink
Fixed move bug of 13.49 Message class
Browse files Browse the repository at this point in the history
  • Loading branch information
pezy committed May 9, 2016
1 parent 2c3cf99 commit 7689528
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 108 deletions.
2 changes: 1 addition & 1 deletion ch13/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ Exercise 13.49:
- StrVec: [hpp](ex13_49_StrVec.h) | [cpp](ex13_49_StrVec.cpp)
- String: [hpp](ex13_49_String.h) | [cpp](ex13_49_String.cpp)
- Message:[hpp](ex13_49_Message.h) | [cpp](ex13_49_Message.cpp)
- Message:[hpp](ex13_49_Message.h) | [cpp](ex13_49_Message.cpp) | [test](ex13_49_Message_TEST.cpp)
Exercise 13.50:
---------------
Expand Down
159 changes: 83 additions & 76 deletions ch13/ex13_49_Message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,150 +4,157 @@
void swap(Message& lhs, Message& rhs)
{
using std::swap;
for (auto f : lhs.folders) f->remMsg(&lhs);
std::cout << "Remove message from folders" << std::endl; // debug

for (auto f : rhs.folders) f->remMsg(&rhs);
std::cout << "Remove message from folders" << std::endl; // debug
lhs.remove_from_Folders();
rhs.remove_from_Folders();

swap(lhs.folders, rhs.folders);
swap(lhs.contents, rhs.contents);

std::cout << "Message members swaped" << std::endl; // debug

for (auto f : lhs.folders) f->addMsg(&lhs);
std::cout << "Added message to folders" << std::endl; // debug

for (auto f : rhs.folders) f->addMsg(&rhs);
std::cout << "Added message to folders" << std::endl; // debug
lhs.add_to_Folders(lhs);
rhs.add_to_Folders(rhs);
}

// Message Implementation

Message::Message(const Message& m) : contents(m.contents), folders(m.folders)
{
add_to_Folders(m);
}

Message& Message::operator=(const Message& rhs)
{
remove_from_Folders();
contents = rhs.contents;
folders = rhs.folders;
add_to_Folders(rhs);
return *this;
}

Message::Message(Message&& m) : contents(std::move(m.contents))
{
move_Folders(&m);
}

Message& Message::operator=(Message&& rhs)
{
if (this != &rhs) {
remove_from_Folders();
contents = std::move(rhs.contents);
move_Folders(&rhs);
}
return *this;
}

Message::~Message()
{
remove_from_Folders();
}

void Message::save(Folder& f)
{
folders.insert(&f);
addFldr(&f);
f.addMsg(this);
}

void Message::remove(Folder& f)
{
folders.erase(&f);
remFldr(&f);
f.remMsg(this);
}

void Message::print_debug()
{
std::cout << contents << std::endl;
}

void Message::add_to_Folders(const Message& m)
{
for (auto f : m.folders) f->addMsg(this);
std::cout << "Added message to folders" << std::endl; // debug
}

void Message::remove_from_Folders()
{
for (auto f : folders) f->remMsg(this);
std::cout << "Remove message from folders" << std::endl; // debug
}

Message& Message::operator=(const Message& rhs)
{
remove_from_Folders();
contents = rhs.contents;
folders = rhs.folders;
std::cout << "Message members assgined" << std::endl; // debug
add_to_Folders(rhs);
return *this;
}

void Message::print_debug()
{
std::cout << contents << ": ";
for (auto f : folders) std::cout << f->fldr() << " ";
std::cout << std::endl;
}

Message& Message::operator=(Message&& rhs) NOEXCEPT
void Message::move_Folders(Message* m)
{
remove_from_Folders();
contents = std::move(rhs.contents);
folders = std::move(rhs.folders);
std::cout << "Message members moved" << std::endl; // debug
return *this;
folders = std::move(m->folders);
for (auto f : folders) {
f->remMsg(m);
f->addMsg(this);
}
m->folders.clear();
}

// Folder Implementation

void swap(Folder& lhs, Folder& rhs)
{
using std::swap;
for (auto m : lhs.msgs) m->remFldr(&lhs);
std::cout << "clear folder" << std::endl; // debug

for (auto m : rhs.msgs) m->remFldr(&rhs);
std::cout << "clear folder" << std::endl; // debug
lhs.remove_from_Messages();
rhs.remove_from_Messages();

swap(lhs.name, rhs.name);
swap(lhs.msgs, rhs.msgs);
std::cout << "Folder members swaped" << std::endl; // debug

for (auto m : lhs.msgs) m->addFldr(&lhs);
std::cout << "Added messages to folder" << std::endl; // debug

for (auto m : rhs.msgs) m->addFldr(&rhs);
std::cout << "Added messages to folder" << std::endl; // debug
lhs.add_to_Messages(lhs);
rhs.add_to_Messages(rhs);
}

void Folder::add_to_Message(const Folder& f)
Folder::Folder(const Folder& f) : msgs(f.msgs)
{
for (auto m : f.msgs) m->addFldr(this);
std::cout << "Added messages to folder" << std::endl; // debug
add_to_Messages(f);
}

Folder::Folder(const Folder& f) : name(f.name), msgs(f.msgs)
Folder& Folder::operator=(const Folder& rhs)
{
add_to_Message(f);
remove_from_Messages();
msgs = rhs.msgs;
add_to_Messages(rhs);
return *this;
}

void Folder::remove_from_Message()
Folder::Folder(Folder&& f)
{
for (auto m : msgs) m->remFldr(this);
std::cout << "clear folder" << std::endl; // debug
move_Messages(&f);
}

Folder::~Folder()
Folder& Folder::operator=(Folder&& f)
{
remove_from_Message();
if (this != &f) {
remove_from_Messages();
move_Messages(&f);
}
return *this;
}

Folder& Folder::operator=(const Folder& rhs)
Folder::~Folder()
{
remove_from_Message();
name = rhs.name;
msgs = rhs.msgs;
std::cout << "Folder members assigned" << std::endl; // debug
add_to_Message(rhs);
return *this;
remove_from_Messages();
}

void Folder::print_debug()
{
std::cout << name << ": ";
for (auto m : msgs) std::cout << m->msg() << " ";
for (auto m : msgs) std::cout << m->contents << " ";
std::cout << std::endl;
}

Folder& Folder::operator=(Folder&& rhs) NOEXCEPT
void Folder::add_to_Messages(const Folder& f)
{
remove_from_Message();
name = std::move(rhs.name);
msgs = std::move(rhs.msgs);
std::cout << "Folder members moved" << std::endl; // debug
return *this;
for (auto m : f.msgs) m->addFldr(this);
}

void Folder::remove_from_Messages()
{
for (auto m : msgs) m->remFldr(this);
}

void Folder::move_Messages(Folder* f)
{
msgs = std::move(f->msgs);
for (auto m : msgs) {
m->remFldr(f);
m->addFldr(this);
}
f->msgs.clear();
}
57 changes: 26 additions & 31 deletions ch13/ex13_49_Message.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#ifndef CP5_MESSAGE_H_
#define CP5_MESSAGE_H_
//
// ex13_49.h
// Exercise 13.49
//
// Created by pezy on 1/26/15.
// Fixed by pezy on 5/9/16.
// Copyright (c) 2015 pezy. All rights reserved.
//
// Added a move constructor and move-assignment operator to Ex13_34_36_37

#ifndef CP5_ex13_49_Message_h
#define CP5_ex13_49_Message_h

#include <string>
#include <set>

#ifndef _MSC_VER
#define NOEXCEPT noexcept
#else
#define NOEXCEPT
#endif
#include <string>

class Folder;

Expand All @@ -21,29 +25,24 @@ class Message {
explicit Message(const std::string& str = "") : contents(str) {}
Message(const Message&);
Message& operator=(const Message&);
Message(Message&& m) NOEXCEPT : contents(std::move(m.contents)),
folders(std::move(m.folders))
{
}
Message& operator=(Message&&) NOEXCEPT;
Message(Message&&);
Message& operator=(Message&&);
~Message();

void save(Folder&);
void remove(Folder&);

const std::string& msg() const { return contents; }
void print_debug();

private:
std::string contents;
std::set<Folder*> folders;

void add_to_Folders(const Message&);
void remove_from_Folders();
void move_Folders(Message*);

void addFldr(Folder* f) { folders.insert(f); }
void remFldr(Folder* f) { folders.erase(f); }

private:
std::string contents;
std::set<Folder*> folders;
};

void swap(Message&, Message&);
Expand All @@ -54,30 +53,26 @@ class Folder {
friend class Message;

public:
explicit Folder(const std::string& str = "") : name(str) {}
Folder() = default;
Folder(const Folder&);
Folder& operator=(const Folder&);
Folder(Folder&& f) NOEXCEPT : name(std::move(f.name)),
msgs(std::move(f.msgs))
{
}
Folder& operator=(Folder&&) NOEXCEPT;
Folder(Folder&&);
Folder& operator=(Folder&&);
~Folder();

const std::string& fldr() const { return name; }
void print_debug();

private:
std::string name;
std::set<Message*> msgs;

void add_to_Message(const Folder&);
void remove_from_Message();
void add_to_Messages(const Folder&);
void remove_from_Messages();
void move_Messages(Folder*);

void addMsg(Message* m) { msgs.insert(m); }
void remMsg(Message* m) { msgs.erase(m); }
};

void swap(Folder&, Folder&);

#endif
#endif // CP5_ex13_49_Message_h
17 changes: 17 additions & 0 deletions ch13/ex13_49_Message_TEST.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Unit Test for exercise 13_49_Message.

#include "ex13_49_Message.h"

int main()
{
Message firstMail("hello");
Message signInMail("welcome to cppprimer");
Folder mailBox;

firstMail.save(mailBox);
signInMail.save(mailBox);
mailBox.print_debug();

firstMail = std::move(signInMail);
mailBox.print_debug();
}

0 comments on commit 7689528

Please sign in to comment.