From e02e3d57dc090c8fd333812b84e91805921e398c Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 21 Jan 2017 18:51:41 -0500 Subject: Moved some generator classes into the main namespace --- lib/role.h | 60 +++++++++++ lib/selrestr.cpp | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/selrestr.h | 90 ++++++++++++++++ 3 files changed, 459 insertions(+) create mode 100644 lib/role.h create mode 100644 lib/selrestr.cpp create mode 100644 lib/selrestr.h (limited to 'lib') diff --git a/lib/role.h b/lib/role.h new file mode 100644 index 0000000..8653710 --- /dev/null +++ b/lib/role.h @@ -0,0 +1,60 @@ +#ifndef ROLE_H_249F9A9C +#define ROLE_H_249F9A9C + +#include +#include +#include "../lib/selrestr.h" + +namespace verbly { + + class role { + public: + + // Default constructor + + role() = default; + + // Constructor + + role( + std::string name, + selrestr selrestrs = {}) : + valid_(true), + name_(name), + selrestrs_(selrestrs) + { + } + + // Accessors + + const std::string& getName() const + { + if (!valid_) + { + throw std::domain_error("Bad access to invalid role"); + } + + return name_; + } + + const selrestr& getSelrestrs() const + { + if (!valid_) + { + throw std::domain_error("Bad access to invalid role"); + } + + return selrestrs_; + } + + private: + + bool valid_ = false; + std::string name_; + selrestr selrestrs_; + + }; + +}; + +#endif /* end of include guard: ROLE_H_249F9A9C */ diff --git a/lib/selrestr.cpp b/lib/selrestr.cpp new file mode 100644 index 0000000..74ea726 --- /dev/null +++ b/lib/selrestr.cpp @@ -0,0 +1,309 @@ +#include "selrestr.h" + +namespace verbly { + + selrestr::selrestr(nlohmann::json data) + { + if (data.find("children") != data.end()) + { + type_ = type::group; + new(&group_.children) std::list(); + + for (const nlohmann::json& child : data["children"]) + { + group_.children.emplace_back(child); + } + + group_.orlogic = (data["logic"] == "or"); + } else if (data.find("type") != data.end()) + { + type_ = type::singleton; + singleton_.pos = data["pos"].get(); + new(&singleton_.restriction) std::string(data["type"].get()); + } else { + type_ = type::empty; + } + } + + selrestr::selrestr(const selrestr& other) + { + type_ = other.type_; + + switch (type_) + { + case type::singleton: + { + singleton_.pos = other.singleton_.pos; + new(&singleton_.restriction) std::string(other.singleton_.restriction); + + break; + } + + case type::group: + { + new(&group_.children) std::list(other.group_.children); + group_.orlogic = other.group_.orlogic; + + break; + } + + case type::empty: + { + break; + } + } + } + + selrestr::selrestr(selrestr&& other) : selrestr() + { + swap(*this, other); + } + + selrestr& selrestr::operator=(selrestr other) + { + swap(*this, other); + + return *this; + } + + void swap(selrestr& first, selrestr& second) + { + using type = selrestr::type; + + type tempType = first.type_; + int tempPos; + std::string tempRestriction; + std::list tempChildren; + bool tempOrlogic; + + switch (tempType) + { + case type::singleton: + { + tempPos = first.singleton_.pos; + tempRestriction = std::move(first.singleton_.restriction); + + break; + } + + case type::group: + { + tempChildren = std::move(first.group_.children); + tempOrlogic = first.group_.orlogic; + + break; + } + + case type::empty: + { + break; + } + } + + first.~selrestr(); + + first.type_ = second.type_; + + switch (first.type_) + { + case type::singleton: + { + first.singleton_.pos = second.singleton_.pos; + new(&first.singleton_.restriction) std::string(std::move(second.singleton_.restriction)); + + break; + } + + case type::group: + { + new(&first.group_.children) std::list(std::move(second.group_.children)); + first.group_.orlogic = second.group_.orlogic; + + break; + } + + case type::empty: + { + break; + } + } + + second.~selrestr(); + + second.type_ = tempType; + + switch (second.type_) + { + case type::singleton: + { + second.singleton_.pos = tempPos; + new(&second.singleton_.restriction) std::string(std::move(tempRestriction)); + + break; + } + + case type::group: + { + new(&second.group_.children) std::list(std::move(tempChildren)); + second.group_.orlogic = tempOrlogic; + + break; + } + + case type::empty: + { + break; + } + } + } + + selrestr::~selrestr() + { + switch (type_) + { + case type::singleton: + { + using string_type = std::string; + singleton_.restriction.~string_type(); + + break; + } + + case type::group: + { + using list_type = std::list; + group_.children.~list_type(); + + break; + } + + case type::empty: + { + break; + } + } + } + + selrestr::selrestr() : type_(type::empty) + { + } + + selrestr::selrestr( + std::string restriction, + bool pos) : + type_(type::singleton) + { + new(&singleton_.restriction) std::string(std::move(restriction)); + singleton_.pos = pos; + } + + std::string selrestr::getRestriction() const + { + if (type_ == type::singleton) + { + return singleton_.restriction; + } else { + throw std::domain_error("Only singleton selrestrs have restrictions"); + } + } + + bool selrestr::getPos() const + { + if (type_ == type::singleton) + { + return singleton_.pos; + } else { + throw std::domain_error("Only singleton selrestrs have positivity flags"); + } + } + + selrestr::selrestr( + std::list children, + bool orlogic) : + type_(type::group) + { + new(&group_.children) std::list(std::move(children)); + group_.orlogic = orlogic; + } + + std::list selrestr::getChildren() const + { + if (type_ == type::group) + { + return group_.children; + } else { + throw std::domain_error("Only group selrestrs have children"); + } + } + + std::list::const_iterator selrestr::begin() const + { + if (type_ == type::group) + { + return std::begin(group_.children); + } else { + throw std::domain_error("Only group selrestrs have children"); + } + } + + std::list::const_iterator selrestr::end() const + { + if (type_ == type::group) + { + return std::end(group_.children); + } else { + throw std::domain_error("Only group selrestrs have children"); + } + } + + bool selrestr::getOrlogic() const + { + if (type_ == type::group) + { + return group_.orlogic; + } else { + throw std::domain_error("Only group selrestrs have logic"); + } + } + + nlohmann::json selrestr::toJson() const + { + switch (type_) + { + case type::empty: + { + return {}; + } + + case type::singleton: + { + return { + {"type", singleton_.restriction}, + {"pos", singleton_.pos} + }; + } + + case type::group: + { + std::string logic; + if (group_.orlogic) + { + logic = "or"; + } else { + logic = "and"; + } + + std::list children; + std::transform(std::begin(group_.children), std::end(group_.children), std::back_inserter(children), [] (const selrestr& child) { + return child.toJson(); + }); + + return { + {"logic", logic}, + {"children", children} + }; + } + } + } + +}; diff --git a/lib/selrestr.h b/lib/selrestr.h new file mode 100644 index 0000000..9f82e3e --- /dev/null +++ b/lib/selrestr.h @@ -0,0 +1,90 @@ +#ifndef SELRESTR_H_50652FB7 +#define SELRESTR_H_50652FB7 + +#include +#include +#include "../vendor/json/json.hpp" + +namespace verbly { + + class selrestr { + public: + enum class type { + empty, + singleton, + group + }; + + // Construct from json + + explicit selrestr(nlohmann::json json); + + // Copy and move constructors + + selrestr(const selrestr& other); + selrestr(selrestr&& other); + + // Assignment + + selrestr& operator=(selrestr other); + + // Swap + + friend void swap(selrestr& first, selrestr& second); + + // Destructor + + ~selrestr(); + + // Generic accessors + + type getType() const + { + return type_; + } + + // Empty + + selrestr(); + + // Singleton + + selrestr(std::string restriction, bool pos); + + std::string getRestriction() const; + + bool getPos() const; + + // Group + + selrestr(std::list children, bool orlogic); + + std::list getChildren() const; + + std::list::const_iterator begin() const; + + std::list::const_iterator end() const; + + bool getOrlogic() const; + + // Helpers + + nlohmann::json toJson() const; + + private: + union { + struct { + bool pos; + std::string restriction; + } singleton_; + struct { + std::list children; + bool orlogic; + } group_; + }; + type type_; + }; + +}; + +#endif /* end of include guard: SELRESTR_H_50652FB7 */ -- cgit 1.4.1