diff options
Diffstat (limited to 'core/src/Model/Items.hpp')
-rw-r--r-- | core/src/Model/Items.hpp | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/core/src/Model/Items.hpp b/core/src/Model/Items.hpp new file mode 100644 index 0000000..0c7be41 --- /dev/null +++ b/core/src/Model/Items.hpp @@ -0,0 +1,146 @@ +#pragma once + +#include <tsl/array_map.h> +#include <cstddef> +#include <stdexcept> +#include <string> +#include <string_view> +#include <vector> + +/// Pointers and references returned by accessors are valid as long as no non-const functions have been called. +template <class T> +class ItemList { +public: + class Iterator { + private: + typename std::vector<T>::const_iterator mBackingIter; + + public: + Iterator(typename std::vector<T>::const_iterator it) + : mBackingIter{ it } { + } + + Iterator& operator++() { + ++mBackingIter; + return *this; + } + + Iterator& operator++(int) { + auto tmp = *this; + ++mBackingIter; + return tmp; + } + + Iterator& operator--() { + --mBackingIter; + return *this; + } + + Iterator& operator--(int) { + auto tmp = *this; + --mBackingIter; + return tmp; + } + + const T& operator*() const { + return *mBackingIter; + } + + friend bool operator==(const Iterator&, const Iterator&) = default; + }; + +private: + std::vector<T> mStorage; + tsl::array_map<char, size_t> mNameLookup; + +public: + template <class... Args> + T& Insert(std::string name, Args... args) { + auto iter = mNameLookup.find(name); + if (iter != mNameLookup.end()) { + throw std::runtime_error("Duplicate key."); + } + + size_t id = mStorage.size(); + mNameLookup.insert(name, id); + return mStorage.emplace_back(id, std::move(name), std::forward<Args>(args)...); + } + + const T* Find(size_t id) const { + return &mStorage[id]; + } + + const T* Find(std::string_view name) const { + auto iter = mNameLookup.find(name); + if (iter != mNameLookup.end()) { + return &mStorage[iter.value()]; + } else { + return nullptr; + } + } + + Iterator begin() const { + return Iterator(mStorage.begin()); + } + + Iterator end() const { + return Iterator(mStorage.end()); + } +}; + +class ItemBase { +private: + size_t mId; + +public: + ItemBase(); + ItemBase(size_t id); + + bool IsInvalid() const; + size_t GetId() const; +}; + +class ProductItem : public ItemBase { +private: + std::string mName; + std::string mDescription; + +public: + ProductItem() {} + ProductItem(size_t id, std::string name); + + const std::string& GetName() const; + void SetName(std::string mName); + const std::string& GetDescription() const; + void SetDescription(std::string description); +}; + +class FactoryItem : public ItemBase { +private: + std::string mName; + std::string mDescription; + +public: + FactoryItem() {} + FactoryItem(size_t id, std::string name); + + const std::string& GetName() const; + void SetName(std::string name); + const std::string& GetDescription() const; + void SetDescription(std::string description); +}; + +class CustomerItem : public ItemBase { +private: + std::string mName; + std::string mDescription; + +public: + CustomerItem() {} + CustomerItem(size_t id, std::string name); + + const std::string& GetName() const; + void SetName(std::string name); + const std::string& GetDescription() const; + void SetDescription(std::string description); +}; |