forked from jaege/Cpp-Primer-5th-Exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add soultions to second half of exercises in chapter 14.
- Loading branch information
Jaege
committed
Feb 24, 2016
1 parent
b02929b
commit 9eccc57
Showing
53 changed files
with
3,244 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
Oops, something went wrong.