Midnight Ember Theme
A warm dark theme with ember highlights for comfortable late-night coding.
Address Book
address_book.hh
#pragma once
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "contact_details.hh"
class AddressBook
{
public:
bool add(const std::string& full_name, const std::string& email,
const std::string& number);
std::vector<ContactDetails> find(const std::string& full_name);
std::size_t count(const std::string& full_name);
bool remove(const std::string& full_name, std::size_t index);
void remove_all(const std::string& full_name);
friend std::ostream& operator<<(std::ostream& os, const AddressBook& b);
private:
std::multimap<std::string, ContactDetails> book_;
};
address_book.cc
#include "address_book.hh"
#include <stdexcept>
bool AddressBook::add(const std::string& full_name, const std::string& email,
const std::string& number)
{
if (full_name.empty())
return false;
try
{
auto details = ContactDetails::makeDetails(number, email);
book_.emplace(full_name, details);
}
catch (const std::invalid_argument&)
{
return false;
}
return true;
}
std::vector<ContactDetails> AddressBook::find(const std::string& full_name)
{
auto range = book_.equal_range(full_name);
std::vector<ContactDetails> result;
for (auto it = range.first; it != range.second; it++)
result.push_back(it->second);
return result;
}
std::size_t AddressBook::count(const std::string& full_name)
{
return book_.count(full_name);
}
bool AddressBook::remove(const std::string& full_name, std::size_t index)
{
auto range = book_.equal_range(full_name);
std::size_t i = 0;
for (auto it = range.first; it != range.second; it++)
{
if (i == index)
{
book_.erase(it);
return true;
}
i++;
}
return false;
}
void AddressBook::remove_all(const std::string& full_name)
{
book_.erase(full_name);
}
std::ostream& operator<<(std::ostream& os, const AddressBook& b)
{
os << b.book_.size() << " contact(s) in the address book.\n";
for (const auto& [name, details] : b.book_)
os << "- " << name << ": " << details;
return os;
}
#pragma once
#include <iostream>
#include <string>
struct ContactDetails
{
static ContactDetails makeDetails(const std::string& telephone_number,
const std::string& personal_email);
friend std::ostream& operator<<(std::ostream& os, const ContactDetails& cd);
const std::string& get_number() const;
const std::string& get_email() const;
private:
ContactDetails(const std::string& telephone_number,
const std::string& personal_email);
std::string number_;
std::string email_;
};
#include "contact_details.hh"
#include <algorithm>
#include <stdexcept>
ContactDetails::ContactDetails(const std::string& telephone_number,
const std::string& personal_email)
: number_(telephone_number)
, email_(personal_email)
{}
ContactDetails ContactDetails::makeDetails(const std::string& telephone_number,
const std::string& personal_email)
{
if (telephone_number.empty()
|| !std::all_of(telephone_number.begin(), telephone_number.end(),
[](https://github.com/arthurnrj/char c) { return c >= '0' && c <= '9'; }))
throw std::invalid_argument("Invalid contact details");
if (personal_email.find('@') == std::string::npos)
throw std::invalid_argument("Invalid contact details");
return ContactDetails(telephone_number, personal_email);
}
std::ostream& operator<<(std::ostream& os, const ContactDetails& cd)
{
os << cd.number_ << ", " << cd.email_ << "\n";
return os;
}
const std::string& ContactDetails::get_number() const
{
return number_;
}
const std::string& ContactDetails::get_email() const
{
return email_;
}
Bimap
bimap.hh
#pragma once
#include <map>
template <typename Lhs, typename Rhs>
class Bimap
{
static_assert(!std::is_same_v<Lhs, Rhs>,
"Lhs and Rhs must be different types");
using mapLhs = std::map<Lhs, Rhs>;
using mapRhs = std::map<Rhs, Lhs>;
using iteratorLhs = typename mapLhs::const_iterator;
using iteratorRhs = typename mapRhs::const_iterator;
public:
bool insert(const Lhs& vl, const Rhs& vr);
bool insert(const Rhs& vr, const Lhs& vl);
std::size_t erase(const Lhs& vl);
std::size_t erase(const Rhs& vr);
iteratorLhs find(const Lhs& vl) const;
iteratorRhs find(const Rhs& vr) const;
std::size_t size() const;
void clear();
const mapLhs& get_lhs() const;
const mapRhs& get_rhs() const;
private:
mapLhs lhs_;
mapRhs rhs_;
};
#include "bimap.hxx"
bimap.hxx
#pragma once
#include "bimap.hh"
template <typename Lhs, typename Rhs>
bool Bimap<Lhs, Rhs>::insert(const Lhs& vl, const Rhs& vr)
{
if (lhs_.count(vl) || rhs_.count(vr))
return false;
lhs_[vl] = vr;
rhs_[vr] = vl;
return true;
}
template <typename Lhs, typename Rhs>
bool Bimap<Lhs, Rhs>::insert(const Rhs& vr, const Lhs& vl)
{
return insert(vl, vr);
}
template <typename Lhs, typename Rhs>
std::size_t Bimap<Lhs, Rhs>::erase(const Lhs& vl)
{
auto it = lhs_.find(vl);
if (it == lhs_.end())
return 0;
rhs_.erase(it->second);
lhs_.erase(it);
return 1;
}
template <typename Lhs, typename Rhs>
std::size_t Bimap<Lhs, Rhs>::erase(const Rhs& vr)
{
auto it = rhs_.find(vr);
if (it == rhs_.end())
return 0;
lhs_.erase(it->second);
rhs_.erase(it);
return 1;
}
template <typename Lhs, typename Rhs>
auto Bimap<Lhs, Rhs>::find(const Lhs& vl) const -> iteratorLhs
{
return lhs_.find(vl);
}
template <typename Lhs, typename Rhs>
auto Bimap<Lhs, Rhs>::find(const Rhs& vr) const -> iteratorRhs
{
return rhs_.find(vr);
}
template <typename Lhs, typename Rhs>
std::size_t Bimap<Lhs, Rhs>::size() const
{
return lhs_.size();
}
template <typename Lhs, typename Rhs>
void Bimap<Lhs, Rhs>::clear()
{
lhs_.clear();
rhs_.clear();
}
template <typename Lhs, typename Rhs>
auto Bimap<Lhs, Rhs>::get_lhs() const -> const mapLhs&
{
return lhs_;
}
template <typename Lhs, typename Rhs>
auto Bimap<Lhs, Rhs>::get_rhs() const -> const mapRhs&
{
return rhs_;
}
Builder
components.hh
#pragma once
#include <string>
struct Wheel
{
Wheel(int size_init)
: size(size_init)
{}
int size;
};
struct Engine
{
Engine(int horsepower_init)
: horsepower(horsepower_init)
{}
int horsepower;
};
struct Body
{
Body(const std::string& shape_init)
: shape(shape_init)
{}
std::string shape;
};
car.hh
#pragma once
#include <array>
#include <iostream>
#include <memory>
#include "components.hh"
class Builder;
class Car
{
friend Builder;
public:
Car() = default;
void print() const
{
std::cout << "body:" << body_->shape << '\n';
std::cout << "engine horsepower:" << engine_->horsepower << '\n';
std::cout << "wheel diameter:" << wheels_[0]->size << "\"\n";
}
private:
std::array<std::unique_ptr<Wheel>, 4> wheels_;
std::unique_ptr<Engine> engine_ = nullptr;
std::unique_ptr<Body> body_ = nullptr;
};
builder.hh
#pragma once
#include "car.hh"
class Builder
{
public:
Builder() = default;
Car get_car() const;
protected:
virtual std::unique_ptr<Wheel> get_wheel() const = 0;
virtual std::unique_ptr<Engine> get_engine() const = 0;
virtual std::unique_ptr<Body> get_body() const = 0;
};
class JeepBuilder : public Builder
{
protected:
std::unique_ptr<Wheel> get_wheel() const override;
std::unique_ptr<Engine> get_engine() const override;
std::unique_ptr<Body> get_body() const override;
};
class NissanBuilder : public Builder
{
protected:
std::unique_ptr<Wheel> get_wheel() const override;
std::unique_ptr<Engine> get_engine() const override;
std::unique_ptr<Body> get_body() const override;
};
builder.cc
#include "builder.hh"
Car Builder::get_car() const
{
Car car;
car.body_ = get_body();
car.engine_ = get_engine();
for (auto& wheel : car.wheels_)
wheel = get_wheel();
return car;
}
std::unique_ptr<Wheel> JeepBuilder::get_wheel() const
{
return std::make_unique<Wheel>(22);
}
std::unique_ptr<Engine> JeepBuilder::get_engine() const
{
return std::make_unique<Engine>(400);
}
std::unique_ptr<Body> JeepBuilder::get_body() const
{
return std::make_unique<Body>("SUV");
}
std::unique_ptr<Wheel> NissanBuilder::get_wheel() const
{
return std::make_unique<Wheel>(16);
}
std::unique_ptr<Engine> NissanBuilder::get_engine() const
{
return std::make_unique<Engine>(85);
}
std::unique_ptr<Body> NissanBuilder::get_body() const
{
return std::make_unique<Body>("hatchback");
}
Cartesian Vector
#pragma once
#include <ostream>
#include <string>
struct FormatNumericalData
{
std::string prefix;
std::string suffix;
int precision = -1;
bool scientific_notation = false;
bool display_plus = false;
std::ostream& formatOs(std::ostream& os) const;
};
#include "format_numerical_data.hh"
#include <iomanip>
std::ostream& FormatNumericalData::formatOs(std::ostream& os) const
{
if (precision >= 0)
os << std::setprecision(precision);
if (scientific_notation)
os << std::scientific;
if (display_plus)
os << std::showpos;
return os;
}
state_saver.hh
#pragma once
#include <iostream>
class StateSaver
{
public:
StateSaver(std::ostream& os);
~StateSaver();
private:
std::ostream& saved_stream_;
std::ios_base::fmtflags saved_flags_;
std::streamsize saved_precision_;
};
state_saver.cc
#include "state_saver.hh"
StateSaver::StateSaver(std::ostream& os)
: saved_stream_(os)
, saved_flags_(os.flags())
, saved_precision_(os.precision())
{}
StateSaver::~StateSaver()
{
saved_stream_.flags(saved_flags_);
saved_stream_.precision(saved_precision_);
}
vector.hh
#pragma once
#include <iostream>
#include "format_numerical_data.hh"
class Vector
{
public:
Vector() = default;
Vector(double x, double y);
double get_x() const;
double get_y() const;
Vector& operator+=(const Vector& rhs);
Vector& operator-=(const Vector& rhs);
Vector& operator*=(double scalar);
friend Vector operator+(const Vector& lhs, const Vector& rhs);
friend Vector operator-(const Vector& lhs, const Vector& rhs);
friend Vector operator*(const Vector& lhs, double scalar);
friend Vector operator*(double scalar, const Vector& rhs);
friend double operator*(const Vector& lhs, const Vector& rhs);
friend std::ostream& operator<<(std::ostream& os, const Vector& vec);
private:
double x_ = 0;
double y_ = 0;
static FormatNumericalData format_numerical_data_;
};
vector.cc
#include "vector.hh"
#include "state_saver.hh"
FormatNumericalData Vector::format_numerical_data_ = { "[ ", " ]", 12, true, true };
Vector::Vector(double x, double y)
: x_(x)
, y_(y)
{}
double Vector::get_x() const { return x_; }
double Vector::get_y() const { return y_; }
Vector& Vector::operator+=(const Vector& rhs)
{
x_ += rhs.x_;
y_ += rhs.y_;
return *this;
}
Vector& Vector::operator-=(const Vector& rhs)
{
x_ -= rhs.x_;
y_ -= rhs.y_;
return *this;
}
Vector& Vector::operator*=(double scalar)
{
x_ *= scalar;
y_ *= scalar;
return *this;
}
Vector operator+(const Vector& lhs, const Vector& rhs)
{
Vector result = lhs;
result += rhs;
return result;
}
Vector operator-(const Vector& lhs, const Vector& rhs)
{
Vector result = lhs;
result -= rhs;
return result;
}
Vector operator*(const Vector& lhs, double scalar)
{
Vector result = lhs;
result *= scalar;
return result;
}
Vector operator*(double scalar, const Vector& rhs) { return rhs * scalar; }
double operator*(const Vector& lhs, const Vector& rhs)
{
return lhs.x_ * rhs.x_ + lhs.y_ * rhs.y_;
}
std::ostream& operator<<(std::ostream& os, const Vector& vec)
{
StateSaver saver(os);
Vector::format_numerical_data_.formatOs(os);
os << Vector::format_numerical_data_.prefix << vec.x_ << " , " << vec.y_
<< Vector::format_numerical_data_.suffix;
return os;
}
Caste or Cast
ant.hh
#pragma once
#include <iostream>
#include <memory>
class Colony;
enum class Stage
{
EGG = 0,
LARVA,
ADULT
};
class Ant
{
public:
Ant(std::shared_ptr<Colony> c, Stage s);
virtual ~Ant() = default;
void live();
Stage get_stage() const;
int get_food() const;
void give_food(Ant& other);
virtual bool communicate(Ant* other);
friend std::ostream& operator<<(std::ostream& os, const Ant& ant);
protected:
std::weak_ptr<Colony> colony_;
Stage stage_;
int food_;
int id_;
static int counter_;
};
ant.cc
#include "ant.hh"
#include "colony.hh"
int Ant::counter_ = 0;
Ant::Ant(std::shared_ptr<Colony> c, Stage s)
: colony_(c)
, stage_(s)
, food_(0)
, id_(++counter_)
{}
void Ant::live()
{
if (food_ >= 1 && stage_ != Stage::ADULT)
{
stage_ = static_cast<Stage>(static_cast<int>(stage_) + 1);
food_--;
}
}
Stage Ant::get_stage() const { return stage_; }
int Ant::get_food() const { return food_; }
void Ant::give_food(Ant& other)
{
other.food_++;
food_--;
}
bool Ant::communicate(Ant* other)
{
if (!other)
return false;
auto my_colony = colony_.lock();
auto other_colony = other->colony_.lock();
return my_colony && other_colony && my_colony == other_colony;
}
std::ostream& operator<<(std::ostream& os, const Ant& ant)
{
os << "Ant #" << ant.id_ << " | Stage: " << static_cast<int>(ant.stage_)
<< " | Food: " << ant.food_;
return os;
}
worker.hh
#pragma once
#include "ant.hh"
class Worker : public Ant
{
public:
using Ant::Ant;
virtual ~Worker() = default;
virtual void work() = 0;
};
queen.hh
#pragma once
#include "ant.hh"
class Queen : public Ant
{
public:
using Ant::Ant;
void layEgg();
};
queen.cc
#include "queen.hh"
#include <iostream>
#include "colony.hh"
#include "nurturer.hh"
#include "provider.hh"
void Queen::layEgg()
{
if (stage_ != Stage::ADULT || food_ < 5)
return;
bool is_even = (food_ % 2 == 0);
food_ -= 5;
std::cout << "Queen " << id_ << " lays an egg" << std::endl;
auto colony = colony_.lock();
if (!colony)
return;
if (is_even)
{
auto egg = Nurturer(colony, Stage::EGG);
colony->addAnt(egg);
}
else
{
auto egg = Provider(colony, Stage::EGG);
colony->addAnt(egg);
}
}
provider.hh
#pragma once
#include "worker.hh"
class Nurturer;
class Provider : public Worker
{
public:
using Worker::Worker;
void work() override;
bool give_all_food(Nurturer& n);
};
provider.cc
#include "provider.hh"
#include <iostream>
#include "nurturer.hh"
void Provider::work()
{
if (stage_ != Stage::ADULT || !colony_.lock())
return;
std::cout << "Provider " << id_ << " works" << std::endl;
food_++;
}
bool Provider::give_all_food(Nurturer& n)
{
if (food_ <= 0)
return false;
std::cout << "Provider " << id_ << " gives all food" << std::endl;
while (food_ > 0)
give_food(n);
return true;
}
nurturer.hh
#pragma once
#include "worker.hh"
class Nurturer : public Worker
{
public:
using Worker::Worker;
void work() override;
bool communicate(Ant* other) override;
};
nurturer.cc
#include "nurturer.hh"
#include <iostream>
#include "colony.hh"
#include "provider.hh"
void Nurturer::work()
{
if (stage_ != Stage::ADULT)
return;
auto colony = colony_.lock();
if (!colony)
return;
std::cout << "Nurturer " << id_ << " works" << std::endl;
if (food_ == 0)
{
for (auto& worker : colony->workers())
{
if (communicate(worker.get()))
break;
}
}
else
{
bool fed = false;
for (auto& worker : colony->workers())
{
if (worker->get_stage() != Stage::ADULT && worker->get_food() == 0)
{
give_food(*worker);
fed = true;
break;
}
}
if (!fed)
colony->feed_queen(*this);
}
}
bool Nurturer::communicate(Ant* other)
{
if (!Ant::communicate(other))
return false;
auto* p = dynamic_cast<Provider*>(other);
if (p)
return p->give_all_food(*this);
return false;
}
colony.hh
#pragma once
#include <memory>
#include <vector>
#include "queen.hh"
class Queen;
class Worker;
class Provider;
class Nurturer;
class Colony
{
public:
Colony() = default;
void addAnt(const Ant& a);
void step();
void feed_queen(Nurturer& nurturer);
const std::vector<std::shared_ptr<Worker>>& workers() const;
void display() const;
private:
std::unique_ptr<Queen> queen_ = nullptr;
std::vector<std::shared_ptr<Worker>> workers_;
};
colony.cc
#include "colony.hh"
#include <iostream>
#include <stdexcept>
#include "nurturer.hh"
#include "provider.hh"
#include "queen.hh"
void Colony::addAnt(const Ant& a)
{
if (auto* q = dynamic_cast<const Queen*>(&a))
{
if (queen_)
throw std::runtime_error("Colony already has a queen");
if (q->get_stage() != Stage::ADULT)
throw std::runtime_error("Attempt to add non-adult Queen");
queen_ = std::make_unique<Queen>(*q);
}
else if (auto* p = dynamic_cast<const Provider*>(&a))
{
workers_.push_back(std::make_shared<Provider>(*p));
}
else if (auto* n = dynamic_cast<const Nurturer*>(&a))
{
workers_.push_back(std::make_shared<Nurturer>(*n));
}
else
{
throw std::runtime_error("Colony::addAnt: unknown Ant subtype");
}
}
void Colony::step()
{
if (queen_)
{
queen_->live();
queen_->layEgg();
}
for (auto& worker : workers_)
{
worker->live();
worker->work();
}
}
void Colony::feed_queen(Nurturer& nurturer)
{
if (queen_)
nurturer.give_food(*queen_);
}
const std::vector<std::shared_ptr<Worker>>& Colony::workers() const
{
return workers_;
}
void Colony::display() const
{
std::cout << "===== Colony state =====" << std::endl;
if (queen_)
std::cout << "Queen: " << *queen_ << std::endl;
else
std::cout << "Queen: (none)\n";
std::cout << "Workers: " << workers_.size() << std::endl;
for (const auto& w : workers_)
std::cout << " - " << *w << std::endl;
}
Chain of Responsibility
handler.hh
#pragma once
class Handler
{
public:
Handler(Handler* next = nullptr);
void set_successor(Handler* h);
virtual void handle_request(int level) = 0;
protected:
void forward_request(int level);
private:
Handler* next_;
};
handler.cc
#include "handler.hh"
#include <iostream>
Handler::Handler(Handler* next)
: next_(next)
{}
void Handler::set_successor(Handler* h) { next_ = h; }
void Handler::forward_request(int level)
{
if (next_)
next_->handle_request(level);
else
std::cout << "Nobody can handle this request\n";
}
director.hh
#pragma once
#include "handler.hh"
class Director : public Handler
{
public:
void handle_request(int level) override;
};
director.cc
#include "director.hh"
#include <iostream>
void Director::handle_request(int level)
{
if (level <= 3)
std::cout << "Director handles\n";
else
forward_request(level);
}
vice_president.hh
#pragma once
#include "handler.hh"
class VicePresident : public Handler
{
public:
void handle_request(int level) override;
};
vice_president.cc
#include "vice_president.hh"
#include <iostream>
void VicePresident::handle_request(int level)
{
if (level <= 6)
std::cout << "VicePresident handles\n";
else
forward_request(level);
}
president.hh
#pragma once
#include "handler.hh"
class President : public Handler
{
public:
void handle_request(int level) override;
};
president.cc
#include "president.hh"
#include <iostream>
void President::handle_request(int level)
{
if (level <= 9)
std::cout << "President handles\n";
else
forward_request(level);
}
Closer To
closer_to.hh
#pragma once
struct CloserTo
{
CloserTo(int i);
bool operator()(int a, int b) const;
private:
int i_;
};
closer_to.cc
#include "closer_to.hh"
CloserTo::CloserTo(int i)
: i_(i)
{}
bool CloserTo::operator()(int lol1, int lol2) const
{
int d1 = lol1 - i_;
int d2 = lol2 - i_;
if (d1 < 0)
d1 = -d1;
if (d2 < 0)
d2 = -d2;
if (d1 != d2)
return d1 < d2;
return lol1 < lol2;
}
Color Manipulator
termcolor.hh
#pragma once
#include <iostream>
#include <memory>
namespace termcolor
{
enum class background : unsigned int
{
black = 40, red = 41, green = 42, yellow = 43,
blue = 44, magenta = 45, cyan = 46, white = 47
};
enum class foreground : unsigned int
{
black = 30, red = 31, green = 32, yellow = 33,
blue = 34, magenta = 35, cyan = 36, white = 37
};
class my_ostream
{
public:
my_ostream(std::ostream& os);
my_ostream(const my_ostream& other);
my_ostream(my_ostream&& other);
~my_ostream();
template <typename T>
my_ostream& operator<<(const T& value);
my_ostream& operator<<(foreground value);
my_ostream& operator<<(background value);
my_ostream& operator<<(std::ostream& (*func)(std::ostream&));
private:
std::ostream& os_;
long* count_;
};
my_ostream operator<<(std::ostream& out, background value);
my_ostream operator<<(std::ostream& out, foreground value);
} // namespace termcolor
#include "termcolor.hxx"
termcolor.hxx
#pragma once
template <typename T>
termcolor::my_ostream& termcolor::my_ostream::operator<<(const T& value)
{
os_ << value;
return *this;
}
termcolor.cc
#include "termcolor.hh"
namespace termcolor
{
my_ostream::my_ostream(std::ostream& os)
: os_(os)
, count_(new long(1))
{}
my_ostream::my_ostream(const my_ostream& other)
: os_(other.os_)
, count_(other.count_)
{
(*count_)++;
}
my_ostream::my_ostream(my_ostream&& other)
: os_(other.os_)
, count_(other.count_)
{
other.count_ = nullptr;
}
my_ostream::~my_ostream()
{
if (!count_)
return;
(*count_)--;
if (*count_ == 0)
{
os_ << "\x1B[0m";
delete count_;
}
}
my_ostream& my_ostream::operator<<(foreground value)
{
os_ << "\x1B[" << static_cast<int>(value) << "m";
return *this;
}
my_ostream& my_ostream::operator<<(background value)
{
os_ << "\x1B[" << static_cast<int>(value) << "m";
return *this;
}
my_ostream& my_ostream::operator<<(std::ostream& (*func)(std::ostream&))
{
os_ << func;
return *this;
}
my_ostream operator<<(std::ostream& out, background value)
{
out << "\x1B[" << static_cast<int>(value) << "m";
return my_ostream(out);
}
my_ostream operator<<(std::ostream& out, foreground value)
{
out << "\x1B[" << static_cast<int>(value) << "m";
return my_ostream(out);
}
} // namespace termcolor
Const
person.hh
#pragma once
#include <string>
class Person
{
public:
std::string get_name() const;
unsigned int get_age() const;
void set_name(const std::string& lol);
void set_age(unsigned int lol);
Person();
Person(const std::string& name, unsigned int age);
private:
std::string name_;
unsigned int age_;
};
person.cc
#include "person.hh"
#include <string>
Person::Person() = default;
Person::Person(const std::string& name, unsigned int age)
{
name_ = name;
age_ = age;
}
std::string Person::get_name() const { return name_; }
unsigned int Person::get_age() const { return age_; }
void Person::set_name(const std::string& lol) { name_ = lol; }
void Person::set_age(const unsigned int lol) { age_ = lol; }