diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2020-04-27 10:23:58 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2020-04-27 10:23:58 (GMT) |
commit | 2b67e2815cf43f9425a7af5e9224e39a77692bdf (patch) | |
tree | 540dc66784d322a0545b8b061a73c6588565ef60 /src/linkedmap.h | |
parent | 6f7443e86a2b6633fafeba5e8baa0941c22c757d (diff) | |
download | Doxygen-2b67e2815cf43f9425a7af5e9224e39a77692bdf.zip Doxygen-2b67e2815cf43f9425a7af5e9224e39a77692bdf.tar.gz Doxygen-2b67e2815cf43f9425a7af5e9224e39a77692bdf.tar.bz2 |
Refactoring: migrate MemberNameInfoSDict to MemberNameInfoLinkedMap
Diffstat (limited to 'src/linkedmap.h')
-rw-r--r-- | src/linkedmap.h | 110 |
1 files changed, 99 insertions, 11 deletions
diff --git a/src/linkedmap.h b/src/linkedmap.h index c724a39..84c4a91 100644 --- a/src/linkedmap.h +++ b/src/linkedmap.h @@ -20,9 +20,11 @@ #include <vector> #include <memory> #include <string> +#include <algorithm> //! @brief Container class representing a vector of objects with unique keys. -//! @details Elements can be quickly looked up given the key. +//! @details Objects can efficiently be looked up given the key. +//! Objects are owned by the container. //! When adding objects the order of addition is kept, and used while iterating. template<class T> class LinkedMap @@ -34,7 +36,7 @@ class LinkedMap using iterator = typename Vec::iterator; using const_iterator = typename Vec::const_iterator; - //! find an element given the key. + //! Find an object given the key. //! Returns a pointer to the element if found or nullptr if it is not found. const T *find(const char *k) const { @@ -43,15 +45,15 @@ class LinkedMap return it!=m_lookup.end() ? it->second : nullptr; } - //! non-const wrapper for find() const + //! A non-const wrapper for find() const T* find(const char *key) { return const_cast<T*>(static_cast<const LinkedMap&>(*this).find(key)); } - //! Adds a new element to the ordered set if it was not added already. - //! Return a non-owning pointer to the newly added item, or to the existing item if it was - //! already inserted before. + //! Adds a new object to the ordered set if it was not added already. + //! Return a non-owning pointer to the newly added object, or to the existing object if + //! it was already inserted before under the given key. template<class...Args> T *add(const char *k, Args&&... args) { @@ -67,12 +69,97 @@ class LinkedMap return result; } - iterator begin() { return m_entries.begin(); } - iterator end() { return m_entries.end(); } - const_iterator begin() const { return m_entries.cbegin(); } + //! Removes an object from the container and deletes it. + //! Returns true if the object was delete or false it is was not found. + bool del(const char *k) + { + std::string key = k ? std::string(k) : std::string(); + auto it = m_lookup.find(key); + if (it!=m_lookup.end()) + { + auto vecit = std::find_if(m_entries.begin(),m_entries.end(),[obj=it->second](auto &el) { return el.get()==obj; }); + if (vecit!=m_entries.end()) // should always be true + { + m_entries.erase(vecit); + m_lookup.erase(it); + return true; + } + } + return false; + } + + iterator begin() { return m_entries.begin(); } + iterator end() { return m_entries.end(); } + const_iterator begin() const { return m_entries.cbegin(); } + const_iterator end() const { return m_entries.cend(); } + bool empty() const { return m_entries.empty(); } + int size() const { return m_entries.size(); } + + void clear() + { + m_entries.clear(); + m_lookup.clear(); + } + + private: + Map m_lookup; + Vec m_entries; +}; + +#if 0 // not yet used +//! @brief Container class representing a vector of objects with unique keys. +//! @details Objects can be efficiently be looked up given the key. +//! Objects are \e not owned by the container, the container will only hold references. +//! When adding objects the order of addition is kept, and used while iterating. +template<class T> +class LinkedRefMap +{ + public: + using Ptr = T*; + using Vec = std::vector<Ptr>; + using Map = std::unordered_map<std::string,T*>; + using iterator = typename Vec::iterator; + using const_iterator = typename Vec::const_iterator; + + //! find an object given the key. + //! Returns a pointer to the object if found or nullptr if it is not found. + const T *find(const char *k) const + { + std::string key = k ? std::string(k) : std::string(); + auto it = m_lookup.find(key); + return it!=m_lookup.end() ? it->second : nullptr; + } + + //! non-const wrapper for find() const + T* find(const char *key) + { + return const_cast<T*>(static_cast<const LinkedRefMap&>(*this).find(key)); + } + + //! Adds a new object to the ordered set if it was not added already. + //! Return true if the object was added, and false if an object with the same key + //! was already added before + bool add(const char *k, T* obj) + { + if (find(k)==nullptr) // new element + { + std::string key = k ? std::string(k) : std::string(); + m_lookup.insert({key,obj}); + m_entries.push_back(obj); + return true; + } + else // already existing, don't add + { + return false; + } + } + + iterator begin() { return m_entries.begin(); } + iterator end() { return m_entries.end(); } + const_iterator begin() const { return m_entries.cbegin(); } const_iterator end() const { return m_entries.cend(); } - bool empty() const { return m_entries.empty(); } - int size() const { return m_entries.size(); } + bool empty() const { return m_entries.empty(); } + int size() const { return m_entries.size(); } void clear() { @@ -84,6 +171,7 @@ class LinkedMap Map m_lookup; Vec m_entries; }; +#endif #endif |