Skip to content

Commit

Permalink
Add soultions to second half of exercises in chapter 14.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaege committed Feb 24, 2016
1 parent b02929b commit 9eccc57
Show file tree
Hide file tree
Showing 53 changed files with 3,244 additions and 5 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ This repo is the solutions to exercises in book [_C++ Primer_ (5th Edition)](htt

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
--:|--:|--:|--:|--:|--:|--:|--:|--:|--:
[1](ch14/14.1.cpp)|[2](ch14/14.2.cpp)|[3](ch14/14.3.cpp)|[4](ch14/14.4.cpp)|[5](ch14/14.5.cpp)|[6](ch14/14.6.cpp)|[7](ch14/14.7.cpp)|[8](ch14/14.8.cpp)|[9](ch14/14.9.cpp)|[10](ch14/14.10.cpp)|
[11](ch14/14.11.cpp)|[12](ch14/14.12.cpp)|[13](ch14/14.13.cpp)|[14](ch14/14.14.cpp)|[15](ch14/14.15.cpp)|[16](ch14/14.16.cpp)|[17](ch14/14.17.cpp)|[18](ch14/14.18.cpp)|[19](ch14/14.19.cpp)|[20](ch14/14.20.cpp)|
[21](ch14/14.21.cpp)|[22](ch14/14.22.cpp)|[23](ch14/14.23.cpp)|[24](ch14/14.24.cpp)|[25](ch14/14.25.cpp)|[26](ch14/14.26.cpp)|[27](ch14/14.27.cpp)|[28](ch14/14.28.cpp)|[29](ch14/14.29.cpp)|[30](ch14/14.30.cpp)|
[31](ch14/14.31.cpp)|[32](ch14/14.32.cpp)|[33](ch14/14.33.cpp)|[34](ch14/14.34.cpp)|[35](ch14/14.35.cpp)|[36](ch14/14.36.cpp)|[37](ch14/14.37.cpp)|[38](ch14/14.38.cpp)|[39](ch14/14.39.cpp)|[40](ch14/14.40.cpp)|
[41](ch14/14.41.cpp)|[42](ch14/14.42.cpp)|[43](ch14/14.43.cpp)|[44](ch14/14.44.cpp)|[45](ch14/14.45.cpp)|[46](ch14/14.46.cpp)|[47](ch14/14.47.cpp)|[48](ch14/14.48.cpp)|[49](ch14/14.49.cpp)|[50](ch14/14.50.cpp)|
[1](ch14/14.1.md)|[2](ch14/14.2.cpp)|[3](ch14/14.3.md)|[4](ch14/14.4.md)|[5](ch14/14.5.md)|[6](ch14/14.6.cpp)|[7](ch14/14.7)|[8](ch14/14.8.md)|[9](ch14/14.9.cpp)|[10](ch14/14.10.md)|
[11](ch14/14.11.md)|[12](ch14/14.12.md)|[13](ch14/14.13.cpp)|[14](ch14/14.14.md)|[15](ch14/14.15.md)|[16](ch14/14.16)|[17](ch14/14.17.md)|[18](ch14/14.18)|[19](ch14/14.19.md)|[20](ch14/14.20.md)|
[21](ch14/14.21.cpp)|[22](ch14/14.22.cpp)|[23](ch14/14.23)|[24](ch14/14.24.md)|[25](ch14/14.25.md)|[26](ch14/14.26)|[27](ch14/14.27)|[28](ch14/14.28)|[29](ch14/14.29.md)|[30](ch14/14.30)|
[31](ch14/14.31.md)|[32](ch14/14.32)|[33](ch14/14.33.md)|[34](ch14/14.34.cpp)|[35](ch14/14.35.cpp)|[36](ch14/14.36.md)|[37](ch14/14.37.cpp)|[38](ch14/14.38.cpp)|[39](ch14/14.39.cpp)|[40](ch14/14.40.cpp)|
[41](ch14/14.41.md)|[42](ch14/14.42.cpp)|[43](ch14/14.43.cpp)|[44](ch14/14.44.cpp)|[45](ch14/14.45.cpp)|[46](ch14/14.46.md)|[47](ch14/14.47.md)|[48](ch14/14.48.md)|[49](ch14/14.49.md)|[50](ch14/14.50.cpp)|
[51](ch14/14.51.cpp)|[52](ch14/14.52.cpp)|[53](ch14/14.53.cpp)

<!---
Expand Down
76 changes: 76 additions & 0 deletions ch14/14.27/ConstStrBlobPtr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "ConstStrBlobPtr.h"
#include "StrBlob.h"

ConstStrBlobPtr::ConstStrBlobPtr() : wptr(), curr(0) {}
ConstStrBlobPtr::ConstStrBlobPtr(const StrBlob &sb, size_type pos)
: wptr(sb.data), curr(pos) {}

std::shared_ptr<std::vector<std::string>>
ConstStrBlobPtr::check(size_type pos, const std::string &msg) const {
auto ret = wptr.lock();
if (!ret)
throw std::runtime_error("unbound ConstStrBlobPtr");
if (pos >= ret->size())
throw std::out_of_range(msg);
return ret;
}

const std::string &ConstStrBlobPtr::deref() const {
auto sp = check(curr, "deference past end of ConstStrBlobPtr");
return (*sp)[curr];
}

//ConstStrBlobPtr &ConstStrBlobPtr::inc() {
// check(curr, "increment past end of ConstStrBlobPtr");
// ++curr;
// return *this;
//}

ConstStrBlobPtr &ConstStrBlobPtr::operator++() {
check(curr, "increment past end of ConstStrBlobPtr");
++curr;
return *this;
}

ConstStrBlobPtr ConstStrBlobPtr::operator++(int) {
auto ret = *this;
++*this;
return ret;
}

ConstStrBlobPtr &ConstStrBlobPtr::operator--() {
--curr;
check(curr, "decrement past begin of ConstStrBlobPtr");
return *this;
}

ConstStrBlobPtr ConstStrBlobPtr::operator--(int) {
auto ret = *this;
--*this;
return ret;
}

bool operator==(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs) {
// compare identity
return lhs.wptr.lock() == rhs.wptr.lock() && lhs.curr == rhs.curr;
}

bool operator!=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs) {
return !(lhs == rhs);
}

bool operator<(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs) {
return lhs.wptr.lock() == rhs.wptr.lock() && lhs.curr < rhs.curr;
}

bool operator>(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs) {
return rhs < lhs;
}

bool operator<=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs) {
return !(lhs > rhs);
}

bool operator>=(const ConstStrBlobPtr &lhs, const ConstStrBlobPtr &rhs) {
return !(lhs < rhs);
}
49 changes: 49 additions & 0 deletions ch14/14.27/ConstStrBlobPtr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef CONSTSTRBLOBPTR_H
#define CONSTSTRBLOBPTR_H

class StrBlob;

#include <vector>
#include <string>
#include <memory>

class ConstStrBlobPtr {
friend bool operator==(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
friend bool operator!=(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
friend bool operator<(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
friend bool operator>(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
friend bool operator<=(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
friend bool operator>=(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
public:
typedef std::vector<std::string>::size_type size_type;

ConstStrBlobPtr();
explicit ConstStrBlobPtr(const StrBlob &sb, size_type pos = 0);

// do not check range
const std::string &operator[](size_type n) const { return (*wptr.lock())[n]; }

const std::string &deref() const;
//ConstStrBlobPtr &inc();

ConstStrBlobPtr &operator++();
ConstStrBlobPtr operator++(int);
ConstStrBlobPtr &operator--();
ConstStrBlobPtr operator--(int);

private:
std::weak_ptr<std::vector<std::string>> wptr;
size_type curr;

std::shared_ptr<std::vector<std::string>>
check(size_type pos, const std::string &msg) const;
};

bool operator==(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
bool operator!=(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
bool operator<(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
bool operator>(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
bool operator<=(const ConstStrBlobPtr &, const ConstStrBlobPtr &);
bool operator>=(const ConstStrBlobPtr &, const ConstStrBlobPtr &);

#endif
85 changes: 85 additions & 0 deletions ch14/14.27/StrBlob.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "StrBlob.h"
#include "StrBlobPtr.h"
#include "ConstStrBlobPtr.h"

StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {}
StrBlob::StrBlob(std::initializer_list<std::string> il)
: data(std::make_shared<std::vector<std::string>>(il)) {}
StrBlob::StrBlob(const StrBlob &sb)
: data(std::make_shared<std::vector<std::string>>(*sb.data)) {}

StrBlob &StrBlob::operator=(const StrBlob &sb) {
data = std::make_shared<std::vector<std::string>>(*sb.data);
return *this;
}

void StrBlob::check(size_type pos, const std::string &msg) const {
if (pos >= data->size())
throw std::out_of_range(msg);
}

void StrBlob::pop_back() {
check(0, "pop_back on empty StrBlob");
data->pop_back();
}

std::string &StrBlob::front() {
check(0, "front on empty StrBlob");
return data->front();
}

const std::string &StrBlob::front() const {
check(0, "front on empty StrBlob");
return data->front();
}

std::string &StrBlob::back() {
check(0, "back on empty StrBlob");
return data->back();
}

const std::string &StrBlob::back() const {
check(0, "back on empty StrBlob");
return data->back();
}

StrBlobPtr StrBlob::begin() {
return StrBlobPtr(*this);
}

StrBlobPtr StrBlob::end() {
return StrBlobPtr(*this, data->size());
}

ConstStrBlobPtr StrBlob::cbegin() const {
return ConstStrBlobPtr(*this);
}

ConstStrBlobPtr StrBlob::cend() const {
return ConstStrBlobPtr(*this, data->size());
}

bool operator==(const StrBlob &lhs, const StrBlob &rhs) {
//return lhs.data == rhs.data; // compare identity(address)
return *lhs.data == *rhs.data; // compare value
}

bool operator!=(const StrBlob &lhs, const StrBlob &rhs) {
return !(lhs == rhs);
}

bool operator<(const StrBlob &lhs, const StrBlob &rhs) {
return *lhs.data < *rhs.data; // compare value
}

bool operator>(const StrBlob &lhs, const StrBlob &rhs) {
return rhs < lhs;
}

bool operator<=(const StrBlob &lhs, const StrBlob &rhs) {
return !(lhs > rhs);
}

bool operator>=(const StrBlob &lhs, const StrBlob &rhs) {
return !(lhs < rhs);
}
75 changes: 75 additions & 0 deletions ch14/14.27/StrBlob.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#ifndef STRBLOB_H
#define STRBLOB_H

class StrBlobPtr;
class ConstStrBlobPtr;

#include <vector>
#include <string>
#include <initializer_list>
#include <memory>
#include <iostream>

class StrBlob {
friend class StrBlobPtr;
friend class ConstStrBlobPtr;
friend bool operator==(const StrBlob &, const StrBlob &);
friend bool operator!=(const StrBlob &, const StrBlob &);
friend bool operator<(const StrBlob &, const StrBlob &);
friend bool operator>(const StrBlob &, const StrBlob &);
friend bool operator<=(const StrBlob &, const StrBlob &);
friend bool operator>=(const StrBlob &, const StrBlob &);
public:
typedef std::vector<std::string>::size_type size_type;

StrBlob();
StrBlob(std::initializer_list<std::string> il);

StrBlob(const StrBlob &);
StrBlob &operator=(const StrBlob &);

// do not check range
std::string &operator[](size_type n) { return (*data)[n]; }
const std::string &operator[](size_type n) const { return (*data)[n]; }

size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }

void push_back(const std::string &s);
void push_back(std::string &&s);
void pop_back();

std::string &front();
const std::string &front() const;
std::string &back();
const std::string &back() const;

StrBlobPtr begin();
StrBlobPtr end();

ConstStrBlobPtr cbegin() const;
ConstStrBlobPtr cend() const;

private:
std::shared_ptr<std::vector<std::string>> data;

void check(size_type pos, const std::string &msg) const;
};

bool operator==(const StrBlob &, const StrBlob &);
bool operator!=(const StrBlob &, const StrBlob &);
bool operator<(const StrBlob &, const StrBlob &);
bool operator>(const StrBlob &, const StrBlob &);
bool operator<=(const StrBlob &, const StrBlob &);
bool operator>=(const StrBlob &, const StrBlob &);

inline void StrBlob::push_back(const std::string &s) {
data->push_back(s);
}

inline void StrBlob::push_back(std::string &&s) {
std::cout << "StrBlob::push_back(std::string &&s)" << std::endl;
data->push_back(std::move(s));
}

#endif
76 changes: 76 additions & 0 deletions ch14/14.27/StrBlobPtr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "StrBlobPtr.h"
#include "StrBlob.h"

StrBlobPtr::StrBlobPtr() : wptr(), curr(0) {}
StrBlobPtr::StrBlobPtr(StrBlob &sb, size_type pos)
: wptr(sb.data), curr(pos) {}

std::shared_ptr<std::vector<std::string>>
StrBlobPtr::check(size_type pos, const std::string &msg) const {
auto ret = wptr.lock();
if (!ret)
throw std::runtime_error("unbound StrBlobPtr");
if (pos >= ret->size())
throw std::out_of_range(msg);
return ret;
}

std::string &StrBlobPtr::deref() const {
auto sp = check(curr, "deference past end of StrBlobPtr");
return (*sp)[curr];
}

//StrBlobPtr &StrBlobPtr::inc() {
// check(curr, "increment past end of StrBlobPtr");
// ++curr;
// return *this;
//}

StrBlobPtr &StrBlobPtr::operator++() {
check(curr, "increment past end of StrBlobPtr");
++curr;
return *this;
}

StrBlobPtr StrBlobPtr::operator++(int) {
auto ret = *this;
++*this;
return ret;
}

StrBlobPtr &StrBlobPtr::operator--() {
--curr;
check(curr, "decrement past begin of StrBlobPtr");
return *this;
}

StrBlobPtr StrBlobPtr::operator--(int) {
auto ret = *this;
--*this;
return ret;
}

bool operator==(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
// compare identity
return lhs.wptr.lock() == rhs.wptr.lock() && lhs.curr == rhs.curr;
}

bool operator!=(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
return !(lhs == rhs);
}

bool operator<(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
return lhs.wptr.lock() == rhs.wptr.lock() && lhs.curr < rhs.curr;
}

bool operator>(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
return rhs < lhs;
}

bool operator<=(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
return !(lhs > rhs);
}

bool operator>=(const StrBlobPtr &lhs, const StrBlobPtr &rhs) {
return !(lhs < rhs);
}
Loading

0 comments on commit 9eccc57

Please sign in to comment.