Program Listing for File container_templates.h¶
↰ Return to documentation for file (src/container_templates.h)
//
// Created by Zayd Hammoudeh on 10/4/18.
//
#ifndef PROJECT02_CONTAINER_TEMPLATES_H
#define PROJECT02_CONTAINER_TEMPLATES_H
#include <string>
#include <map>
#include <set>
#include <iostream>
#include <stdexcept>
#include "keywords.h"
#include "exceptions.h"
template<typename _T>
class ObjectContainer {
private:
virtual bool exists(const std::string &obj_name) = 0;
virtual void add(_T *new_obj) = 0;
virtual _T* get(const std::string &str) = 0;
virtual unsigned long count() = 0;
virtual void clear() = 0;
public:
virtual ~ObjectContainer() = default;
bool empty() { return count() == 0; };
virtual const void print_original_src(unsigned int indent_depth) = 0;
};
template <typename _T>
class MapContainer : public ObjectContainer<_T> {
public:
MapContainer() = default;
~MapContainer() {
for (const auto &pair : objs_)
delete pair.second;
}
typename std::map<std::string, _T*>::iterator begin() { return objs_.begin(); }
typename std::map<std::string, _T*>::iterator end() { return objs_.end(); }
bool exists(const std::string &obj_name) override {
return objs_.find(obj_name) != objs_.end();
}
void add(_T *new_obj) override {
if (exists(new_obj->name_))
throw ParserException("Duplicate object: " + new_obj->name_);
objs_[new_obj->name_] = new_obj;
}
_T* get(const std::string &str) override {
auto itr = objs_.find(str);
if (itr == objs_.end())
return OBJECT_NOT_FOUND;
return itr->second;
}
unsigned long count() override { return objs_.size(); }
void clear() override {
objs_.clear();
}
const void print_original_src_(unsigned int indent_depth, const std::string &print_sep) {
bool is_first = true;
for (auto &pair : objs_) {
if (!is_first)
std::cout << print_sep;
is_first = false;
pair.second->print_original_src(indent_depth);
}
}
protected:
std::map<std::string,_T*> objs_;
};
template<typename _T>
class VectorContainer : public ObjectContainer<_T> {
public:
VectorContainer() = default;
~VectorContainer() {
for (auto const &ptr : objs_)
delete ptr;
}
typename std::vector<_T*>::const_iterator begin() const { return objs_.begin(); }
typename std::vector<_T*>::iterator begin() { return objs_.begin(); }
typename std::vector<_T*>::const_iterator end() const { return objs_.end(); }
typename std::vector<_T*>::iterator end() { return objs_.end(); }
bool exists(const std::string &name) override { return names_.find(name) != names_.end(); }
void add(_T* new_obj) override {
if (exists(new_obj->name_))
throw DuplicateParamException(new_obj->name_);
objs_.emplace_back(new_obj);
names_.emplace(new_obj->name_);
};
_T* get(const std::string &name) override {
if (!exists(name))
return OBJECT_NOT_FOUND;
for (auto &obj: objs_)
if (obj->name_ == name)
return obj;
throw std::runtime_error("Unable to get object with key: " + name);
}
void clear() override {
objs_.clear();
names_.clear();
}
unsigned long count() override { return objs_.size(); }
const void print_original_src_(unsigned int indent_depth, const std::string &print_sep) {
bool is_first = true;
for (auto &obj : objs_) {
if (!is_first)
std::cout << print_sep;
is_first = false;
obj->print_original_src(indent_depth);
}
}
_T* operator [](int i) {
return objs_[i];
}
private:
const VectorContainer<_T>* get_const() { return static_cast<const VectorContainer<_T>*>(this); }
std::vector<_T*> objs_;
std::set<std::string> names_;
};
#endif //PROJECT02_CONTAINER_TEMPLATES_H