#ifndef NTX_MAPTOR_H #define NTX_MAPTOR_H #include "ntxmapindex.h" #include #include #include #include #include #include #include namespace ntx { /** * @brief Generischer Maptor (Vector + Map), adaptiert an das NtxIPayload-Interface. * * Entfernt die STL-Container-Schnittstelle (push_back, begin, end, etc.) zugunsten * der expliziten Payload-Methodik (setProperty, getProperty, etc.). */ template class NtxMaptor { public: using NtxMapIndexPtr = std::shared_ptr; // Zugriff auf Iteratoren für Range-Based Loops (via valuesBegin/End) using iterator = typename std::vector::iterator; using const_iterator = typename std::vector::const_iterator; // --- Konstruktoren --- NtxMaptor() : m_index(std::make_shared()) { } explicit NtxMaptor(const NtxMapIndexPtr& index) { if (!index) throw std::invalid_argument("NtxMaptor: index must not be null"); m_index = index; } NtxMaptor(const NtxMaptor&) = default; NtxMaptor& operator=(const NtxMaptor&) = default; NtxMaptor(NtxMaptor&&) noexcept = default; NtxMaptor& operator=(NtxMaptor&&) noexcept = default; virtual ~NtxMaptor() = default; // ========================================================================= // NtxIPayload Interface-Adaption // ========================================================================= // --- Kapazität --- [[nodiscard]] size_t getPropertyCount() const noexcept { return m_data.size(); } void clearProperties() { m_data.clear(); m_index->clear(); } // --- Key-basierter Zugriff --- bool hasProperty(const std::string& key) const { return m_index->containsKey(key); } /** * @brief Setzt oder fügt einen Wert hinzu (Upsert). * Wenn der Key existiert, wird der Wert überschrieben. * Wenn nicht, wird er angehängt. */ void setProperty(const std::string& key, const T& value) { auto idx = m_index->indexOf(key); if (idx) { m_data[*idx] = value; } else { m_index->addKey(key, m_data.size()); m_data.push_back(value); } } // "Deducing this" für const/non-const getProperty(key) template auto&& getProperty(this Self&& self, const std::string& key) { auto idx = self.m_index->indexOf(key); if (!idx) throw std::out_of_range("NtxMaptor: Key not found: " + key); return std::forward(self).m_data[*idx]; } void removeProperty(const std::string& key) { auto idx = m_index->indexOf(key); if (!idx) return; size_t index = *idx; // Index entfernen und nachfolgende Indizes im Index-Objekt korrigieren m_index->removeAt(index); // Daten aus Vektor entfernen m_data.erase(m_data.begin() + static_cast(index)); } // --- Index-basierter Zugriff --- bool hasProperty(size_t index) const { return index < m_data.size(); } void setProperty(size_t index, const T& value) { if (index >= m_data.size()) { throw std::out_of_range("NtxMaptor: Index out of range"); } m_data[index] = value; } // "Deducing this" für const/non-const getProperty(index) template auto&& getProperty(this Self&& self, size_t index) { return std::forward(self).m_data.at(index); } // --- Iteratoren (NtxIPayload Style) --- // Erlaubt das Iterieren über die internen Werte template auto begin(this Self&& self) { return std::forward(self).m_data.begin(); } template auto end(this Self&& self) { return std::forward(self).m_data.end(); } // ========================================================================= // Erweiterte Index-Funktionen (Alias, Replace) // Diese bleiben erhalten, da sie spezifische NtxMapIndex Features sind // ========================================================================= bool replaceKey(const std::string& oldKey, const std::string& newKey) { return m_index->replaceKey(oldKey, newKey); } bool addAlias(const std::string& key, const std::string& alias) { return m_index->addAlias(key, alias); } private: std::vector m_data; NtxMapIndexPtr m_index; }; } // namespace ntx #endif // NTX_MAPTOR_H