added nodes.
This commit is contained in:
88
nodes/util/ntxmapindex.cpp
Normal file
88
nodes/util/ntxmapindex.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <ntxmapindex.h>
|
||||
#include <ranges> // Zwingend erforderlich für std::views und std::ranges::to
|
||||
|
||||
namespace ntx
|
||||
{
|
||||
|
||||
// --- Lookup ---
|
||||
|
||||
std::optional<size_t> NtxMapIndex::indexOf(const std::string& key) const noexcept
|
||||
{
|
||||
auto it = m_keyToIndex.find(key);
|
||||
if (it != m_keyToIndex.end())
|
||||
return it->second;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool NtxMapIndex::containsKey(const std::string& key) const noexcept
|
||||
{
|
||||
return m_keyToIndex.contains(key);
|
||||
}
|
||||
|
||||
// --- Modification ---
|
||||
|
||||
void NtxMapIndex::addKey(const std::string& key, size_t index)
|
||||
{
|
||||
m_keyToIndex[key] = index;
|
||||
}
|
||||
|
||||
void NtxMapIndex::removeAt(size_t index)
|
||||
{
|
||||
auto it = m_keyToIndex.begin();
|
||||
while (it != m_keyToIndex.end())
|
||||
{
|
||||
if (it->second == index)
|
||||
it = m_keyToIndex.erase(it);
|
||||
else
|
||||
{
|
||||
if (it->second > index)
|
||||
it->second--;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool NtxMapIndex::removeKey(const std::string& key)
|
||||
{
|
||||
return m_keyToIndex.erase(key) > 0;
|
||||
}
|
||||
|
||||
bool NtxMapIndex::replaceKey(const std::string& oldKey, const std::string& newKey)
|
||||
{
|
||||
auto it = m_keyToIndex.find(oldKey);
|
||||
if (it == m_keyToIndex.end() || oldKey == newKey)
|
||||
return false;
|
||||
if (m_keyToIndex.contains(newKey))
|
||||
return false;
|
||||
|
||||
size_t idx = it->second;
|
||||
m_keyToIndex.erase(it);
|
||||
m_keyToIndex[newKey] = idx;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NtxMapIndex::addAlias(const std::string& existingKey, const std::string& alias)
|
||||
{
|
||||
auto idx = indexOf(existingKey);
|
||||
if (!idx || containsKey(alias))
|
||||
return false;
|
||||
m_keyToIndex[alias] = *idx;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t NtxMapIndex::size() const noexcept
|
||||
{
|
||||
return m_keyToIndex.size();
|
||||
}
|
||||
|
||||
bool NtxMapIndex::empty() const noexcept
|
||||
{
|
||||
return m_keyToIndex.empty();
|
||||
}
|
||||
|
||||
void NtxMapIndex::clear() noexcept
|
||||
{
|
||||
m_keyToIndex.clear();
|
||||
}
|
||||
|
||||
} // namespace ntx
|
||||
61
nodes/util/ntxmapindex.h
Normal file
61
nodes/util/ntxmapindex.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef NTX_MAPINDEX_H
|
||||
#define NTX_MAPINDEX_H
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace ntx
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Bidirektionaler Index: String-Key → size_t Position.
|
||||
*
|
||||
* Verwendet Komposition statt Vererbung.
|
||||
* Key → Index: O(1) via unordered_map.
|
||||
*/
|
||||
class NtxMapIndex
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
NtxMapIndex() = default;
|
||||
|
||||
// --- Lookup ---
|
||||
std::optional<size_t> indexOf(const std::string& key) const noexcept;
|
||||
bool containsKey(const std::string& key) const noexcept;
|
||||
|
||||
// --- Iteration ---
|
||||
|
||||
/// Iteriert über alle Key→Index Paare.
|
||||
/// Template muss im Header bleiben.
|
||||
template <typename Fn>
|
||||
void forEachKey(Fn&& fn) const
|
||||
{
|
||||
for (const auto& [key, idx] : m_keyToIndex)
|
||||
fn(key, idx);
|
||||
}
|
||||
|
||||
// --- Modification ---
|
||||
void addKey(const std::string& key, size_t index);
|
||||
void removeAt(size_t index);
|
||||
bool removeKey(const std::string& key);
|
||||
bool replaceKey(const std::string& oldKey, const std::string& newKey);
|
||||
bool addAlias(const std::string& existingKey, const std::string& alias);
|
||||
|
||||
size_t size() const noexcept;
|
||||
bool empty() const noexcept;
|
||||
void clear() noexcept;
|
||||
|
||||
private:
|
||||
|
||||
std::unordered_map<std::string, size_t> m_keyToIndex;
|
||||
};
|
||||
|
||||
using NtxMapIndexPtr = std::shared_ptr<NtxMapIndex>;
|
||||
|
||||
} // namespace ntx
|
||||
|
||||
#endif // NTX_MAPINDEX_H
|
||||
177
nodes/util/ntxmaptor.h
Normal file
177
nodes/util/ntxmaptor.h
Normal file
@@ -0,0 +1,177 @@
|
||||
#ifndef NTX_MAPTOR_H
|
||||
#define NTX_MAPTOR_H
|
||||
|
||||
#include "ntxmapindex.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
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 <typename T>
|
||||
class NtxMaptor
|
||||
{
|
||||
public:
|
||||
|
||||
using NtxMapIndexPtr = std::shared_ptr<NtxMapIndex>;
|
||||
|
||||
// Zugriff auf Iteratoren für Range-Based Loops (via valuesBegin/End)
|
||||
using iterator = typename std::vector<T>::iterator;
|
||||
using const_iterator = typename std::vector<T>::const_iterator;
|
||||
|
||||
// --- Konstruktoren ---
|
||||
|
||||
NtxMaptor()
|
||||
: m_index(std::make_shared<NtxMapIndex>())
|
||||
{
|
||||
}
|
||||
|
||||
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 <typename Self>
|
||||
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>(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<std::ptrdiff_t>(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 <typename Self>
|
||||
auto&& getProperty(this Self&& self, size_t index)
|
||||
{
|
||||
return std::forward<Self>(self).m_data.at(index);
|
||||
}
|
||||
|
||||
// --- Iteratoren (NtxIPayload Style) ---
|
||||
|
||||
// Erlaubt das Iterieren über die internen Werte
|
||||
template <typename Self>
|
||||
auto begin(this Self&& self) { return std::forward<Self>(self).m_data.begin(); }
|
||||
|
||||
template <typename Self>
|
||||
auto end(this Self&& self) { return std::forward<Self>(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<T> m_data;
|
||||
NtxMapIndexPtr m_index;
|
||||
};
|
||||
|
||||
} // namespace ntx
|
||||
|
||||
#endif // NTX_MAPTOR_H
|
||||
Reference in New Issue
Block a user