summaryrefslogtreecommitdiffstats
path: root/src/linkedmap.h
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-04-27 10:23:58 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-04-27 10:23:58 (GMT)
commit2b67e2815cf43f9425a7af5e9224e39a77692bdf (patch)
tree540dc66784d322a0545b8b061a73c6588565ef60 /src/linkedmap.h
parent6f7443e86a2b6633fafeba5e8baa0941c22c757d (diff)
downloadDoxygen-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.h110
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