diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-15 11:15:28 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2021-10-15 11:15:28 +0900 |
commit | 4aa4e498d10e343b3b2a49e06195f62a49120002 (patch) | |
tree | ff9645788017052b9d83d196cc25bddcfcf1708b /src/linkedmap.h | |
parent | fd5021ef77ddac91004a2b9c549e08ea952bce89 (diff) | |
download | doxygen-4aa4e498d10e343b3b2a49e06195f62a49120002.tar.gz doxygen-4aa4e498d10e343b3b2a49e06195f62a49120002.tar.bz2 doxygen-4aa4e498d10e343b3b2a49e06195f62a49120002.zip |
Imported Upstream version 1.9.0upstream/1.9.0
Diffstat (limited to 'src/linkedmap.h')
-rw-r--r-- | src/linkedmap.h | 156 |
1 files changed, 123 insertions, 33 deletions
diff --git a/src/linkedmap.h b/src/linkedmap.h index 84dcf26..f09b6d8 100644 --- a/src/linkedmap.h +++ b/src/linkedmap.h @@ -21,26 +21,30 @@ #include <memory> #include <string> #include <algorithm> +#include <cctype> -//! @brief Container class representing a vector of objects with unique keys. +//! @brief Container class representing a vector of objects with keys. //! @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> +template<class T, class Hash = std::hash<std::string>, + class KeyEqual = std::equal_to<std::string>, + class Map = std::unordered_map<std::string,T*,Hash,KeyEqual > > class LinkedMap { public: using Ptr = std::unique_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; + using reverse_iterator = typename Vec::reverse_iterator; + using const_reverse_iterator = typename Vec::const_reverse_iterator; //! 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 + const T *find(const char *key_) const { - std::string key = k ? std::string(k) : std::string(); + std::string key(key_ ? key_ : ""); auto it = m_lookup.find(key); return it!=m_lookup.end() ? it->second : nullptr; } @@ -51,7 +55,7 @@ class LinkedMap return const_cast<T*>(static_cast<const LinkedMap&>(*this).find(key)); } - //! Adds a new object to the ordered set if it was not added already. + //! Adds a new object to the ordered vector 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> @@ -60,8 +64,8 @@ class LinkedMap T *result = find(k); if (result==nullptr) { - std::string key = k ? std::string(k) : std::string(); - Ptr ptr = std::make_unique<T>(k,std::forward<Args>(args)...); + std::string key(k ? k : ""); + Ptr ptr = std::make_unique<T>(key.c_str(),std::forward<Args>(args)...); result = ptr.get(); m_lookup.insert({key,result}); m_entries.push_back(std::move(ptr)); @@ -69,11 +73,46 @@ class LinkedMap return result; } + //! Adds an existing object to the ordered vector (unless another object was already + //! added under the same key). Ownership is transferred. + //! 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. + T *add(const char *k, Ptr &&ptr) + { + T *result = find(k); + if (result==nullptr) + { + std::string key(k ? k : ""); + result = ptr.get(); + m_lookup.insert({key,result}); + m_entries.push_back(std::move(ptr)); + } + return result; + } + + //! Prepends a new object to the ordered vector 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 *prepend(const char *k, Args&&... args) + { + T *result = find(k); + if (result==nullptr) + { + std::string key(k ? k : ""); + Ptr ptr = std::make_unique<T>(key.c_str(),std::forward<Args>(args)...); + result = ptr.get(); + m_lookup.insert({key,result}); + m_entries.push_front(std::move(ptr)); + } + return result; + } + //! 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) + //! Returns true if the object was deleted or false it is was not found. + bool del(const char *key_) { - std::string key = k ? std::string(k) : std::string(); + std::string key(key_ ? key_ : ""); auto it = m_lookup.find(key); if (it!=m_lookup.end()) { @@ -88,12 +127,18 @@ class LinkedMap 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(); } - size_t size() const { return m_entries.size(); } + Ptr &operator[](size_t pos) { return m_entries[pos]; } + const Ptr &operator[](size_t pos) const { return m_entries[pos]; } + 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(); } + reverse_iterator rbegin() { return m_entries.rbegin(); } + reverse_iterator rend() { return m_entries.rend(); } + const_reverse_iterator rbegin() const { return m_entries.crbegin(); } + const_reverse_iterator rend() const { return m_entries.crend(); } + bool empty() const { return m_entries.empty(); } + size_t size() const { return m_entries.size(); } void clear() { @@ -102,30 +147,33 @@ class LinkedMap } private: + Map m_lookup; Vec m_entries; }; -#if 0 // not yet used -//! @brief Container class representing a vector of objects with unique keys. +//! @brief Container class representing a vector of objects with 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> +template<class T, class Hash = std::hash<std::string>, + class KeyEqual = std::equal_to<std::string>, + class Map = std::unordered_map<std::string,T*,Hash,KeyEqual > > 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; + using reverse_iterator = typename Vec::reverse_iterator; + using const_reverse_iterator = typename Vec::const_reverse_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 + const T *find(const char *key_) const { - std::string key = k ? std::string(k) : std::string(); + std::string key(key_ ? key_ : ""); auto it = m_lookup.find(key); return it!=m_lookup.end() ? it->second : nullptr; } @@ -136,14 +184,14 @@ class LinkedRefMap 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 + //! Adds an object reference to the ordered vector if it was not added already. + //! Return true if the reference 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(); + std::string key(k ? k : ""); m_lookup.insert({key,obj}); m_entries.push_back(obj); return true; @@ -154,12 +202,55 @@ class LinkedRefMap } } - 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(); } - size_t size() const { return m_entries.size(); } + //! Prepends an object reference to the ordered vector if it was not added already. + //! Return true if the reference was added, and false if an object with the same key + //! was already added before + bool prepend(const char *k, T* obj) + { + if (find(k)==nullptr) // new element + { + std::string key(k ? k : ""); + m_lookup.insert({key,obj}); + m_entries.insert(m_entries.begin(),obj); + return true; + } + else // already existing, don't add + { + return false; + } + } + + //! Removes an object from the container and deletes it. + //! Returns true if the object was deleted or false it is was not found. + bool del(const char *key_) + { + std::string key(key_ ? key_ : ""); + 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; + } + + Ptr &operator[](size_t pos) { return m_entries[pos]; } + const Ptr &operator[](size_t pos) const { return m_entries[pos]; } + 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(); } + reverse_iterator rbegin() { return m_entries.rbegin(); } + reverse_iterator rend() { return m_entries.rend(); } + const_reverse_iterator rbegin() const { return m_entries.crbegin(); } + const_reverse_iterator rend() const { return m_entries.crend(); } + bool empty() const { return m_entries.empty(); } + size_t size() const { return m_entries.size(); } void clear() { @@ -171,7 +262,6 @@ class LinkedRefMap Map m_lookup; Vec m_entries; }; -#endif #endif |