#pragma once #include #include #include #include #include #include /// Pointers and references returned by accessors are valid as long as no non-const functions have been called. template class ItemList { public: class Iterator { private: typename std::vector::const_iterator mBackingIter; public: Iterator(typename std::vector::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 mStorage; tsl::array_map mNameLookup; public: template 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)...); } 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); };