#include "checklist.hpp"
#include <algorithm>
int main() {
CheckList makeDinner{"Sausage and Mash", 7};
makeDinner[0] = "Peel potatoes";
makeDinner[1] = "Cook potatoes";
makeDinner[2] = "Cook vegetables";
makeDinner[3] = "Grill Sausages";
makeDinner[4] = "Make Gravy";
makeDinner[5] = "Mash Potatoes";
makeDinner[6] = "Serve";
// Now we use the output operator, rather than printToSteam
std::cout << makeDinner << std::endl;
CheckList makeBevs{"Iced Tea", 3};
makeBevs[0] = "Brew Tea";
makeBevs[1] = "Chill";
makeBevs[2] = "Serve";
std::cout << makeBevs << std::endl;
// Here we use a plus operator that combines two checklists into
// one.
CheckList makeAll = makeDinner + makeBevs;
// Using the begin/past-the-end pointers, we can call built-in C++
// algorithms that work on arrays.
std::sort(makeAll.begin(), makeAll.end());
// We can make a for loop that iteraters over all the items in our
// checklist using begin/past-the-end style, much like we would for
// a built-in array. Here we go through all our check-list items
// and add a question mark.
for (std::string* p = makeAll.begin(); p != makeAll.end(); ++p) {
std::string& checkItem = *p;
checkItem += '?';
}
// And, even cooler, if we have .begin() and .end(), we can use a NEW
// KIND of for loop that works just like the loop above, but hides
// the details of calling .begin() and .end() and the pointer.
// Here we go through all our check-list items and add an exclamation
// mark.
for (std::string& checkItem : makeAll) {
checkItem += '!';
}
std::cout << makeAll << std::endl;
}
#ifndef CHECKLIST_HPP_INCLUDED
#define CHECKLIST_HPP_INCLUDED
#include <string>
#include <iostream>
class CheckList {
public:
CheckList() = delete;
CheckList(std::string task, size_t numSteps);
CheckList(const CheckList& other);
~CheckList();
CheckList& operator=(CheckList rhs); // copy-and-swap idiom
void swap(CheckList& other);
std::string task() const;
size_t size() const;
// We provide two overloaded operator[], one for writable checklists
// and one for read-only ones.
std::string& operator[](size_t index);
const std::string& operator[](size_t index) const;
// We provide two overloaded begin/end functions one for writable checklists
// and one for read-only ones.
std::string* begin();
std::string* end();
const std::string* begin() const;
const std::string* end() const;
void printToStream(std::ostream& out) const;
private:
std::string task_;
size_t numSteps_;
std::string* steps_;
};
// We'll provide a global function that adds two checklists
CheckList operator+(const CheckList& lhs, const CheckList& rhs);
// We'll provide a global function that prints a checklist.
std::ostream& operator<<(std::ostream& out, const CheckList& list);
#endif // CHECKLIST_HPP_INCLUDED
#include "checklist.hpp"
#include <string>
CheckList::CheckList(std::string task, size_t numSteps)
: task_{task}, numSteps_{numSteps}, steps_{new std::string[numSteps_]} {
// Array of strings on heap has all elements default initialized to
// empty strings, which is fine, so nothing (else) to do.
}
CheckList::CheckList(const CheckList& other)
: task_{other.task_},
numSteps_{other.numSteps_},
steps_{new std::string[numSteps_]} {
// Rather than hand-write a for loop, this code uses std::copy to copy
// the array. The arguments are:
// source_start, source_past_end, dest_start
std::copy(other.steps_, other.steps_ + other.numSteps_, steps_);
}
CheckList::~CheckList() {
delete[] steps_;
}
CheckList& CheckList::operator=(CheckList rhs) { // copy-and-swap idiom
swap(rhs);
return *this;
}
void CheckList::swap(CheckList& other) {
std::swap(task_, other.task_);
std::swap(numSteps_, other.numSteps_);
std::swap(steps_, other.steps_);
}
size_t CheckList::size() const {
return numSteps_;
}
std::string CheckList::task() const {
return task_;
}
std::string& CheckList::operator[](size_t index) {
return steps_[index];
}
const std::string& CheckList::operator[](size_t index) const {
return steps_[index];
}
std::string* CheckList::begin() {
return steps_;
}
std::string* CheckList::end() {
return steps_ + numSteps_;
}
const std::string* CheckList::begin() const {
return steps_;
}
const std::string* CheckList::end() const {
return steps_ + numSteps_;
}
void CheckList::printToStream(std::ostream& out) const {
out << task_ << ":" << std::endl;
for (std::string* p = steps_; p != steps_ + numSteps_; ++p) {
out << " - " << *p << std::endl;
}
}
CheckList operator+(const CheckList& lhs, const CheckList& rhs) {
CheckList result{lhs.task() + " & " + rhs.task(), lhs.size() + rhs.size()};
std::copy(lhs.begin(), lhs.end(), result.begin());
std::copy(rhs.begin(), rhs.end(), result.begin()+lhs.size());
return result;
}
std::ostream& operator<<(std::ostream& out, const CheckList& list) {
list.printToStream(out);
return out;
}