summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-10-31 15:02:26 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2020-10-31 15:02:26 (GMT)
commit2b5a4541fb6f806c02a1f6e65a1ff2610f29751f (patch)
treee0e91912e2c8c57873fe267a640c870381de87e5
parent7bd4455f4fb17075eb23f5f24a5735913cde3e16 (diff)
downloadDoxygen-2b5a4541fb6f806c02a1f6e65a1ff2610f29751f.zip
Doxygen-2b5a4541fb6f806c02a1f6e65a1ff2610f29751f.tar.gz
Doxygen-2b5a4541fb6f806c02a1f6e65a1ff2610f29751f.tar.bz2
issue #8129: Image path is now case sensitive (take 2)
-rw-r--r--src/filename.h33
-rw-r--r--src/linkedmap.h59
2 files changed, 58 insertions, 34 deletions
diff --git a/src/filename.h b/src/filename.h
index f8ea2e1..d236046 100644
--- a/src/filename.h
+++ b/src/filename.h
@@ -20,6 +20,7 @@
#include <vector>
#include "linkedmap.h"
+#include "config.h"
class FileDef;
@@ -38,8 +39,38 @@ class FileName : public std::vector< std::unique_ptr<FileDef> >
QCString m_pathName;
};
+//! Custom combined key compare and hash functor that uses a lower case string in
+//! case CASE_SENSE_NAMES is set to NO.
+class FileNameFn
+{
+ public:
+ //! used as hash function
+ std::size_t operator()(const std::string& input) const noexcept
+ {
+ return std::hash<std::string>()(searchKey(input));
+ }
+ //! used as equal operator
+ bool operator() (const std::string &t1, const std::string &t2) const
+ {
+ return searchKey(t1) == searchKey(t2);
+ }
+ private:
+ std::string searchKey(std::string input) const
+ {
+ std::string key = input;
+ if (!Config_getBool(CASE_SENSE_NAMES))
+ {
+ // convert key to lower case
+ std::transform(key.begin(),key.end(),key.begin(),
+ [](char c){ return (char)std::tolower(c); });
+ }
+ return key;
+ }
+};
+
/** Ordered dictionary of FileName objects. */
-class FileNameLinkedMap : public LinkedMap<FileName,true>
+class FileNameLinkedMap : public LinkedMap<FileName,FileNameFn,FileNameFn,
+ std::unordered_multimap<std::string,FileName*,FileNameFn,FileNameFn> >
{
};
diff --git a/src/linkedmap.h b/src/linkedmap.h
index e61f99b..9ca0fa2 100644
--- a/src/linkedmap.h
+++ b/src/linkedmap.h
@@ -23,30 +23,18 @@
#include <algorithm>
#include <cctype>
-#include "config.h"
-
-inline std::string LinkedMap_make_key(const char *k,bool case_sensitivity_support)
-{
- std::string key(k ? k : "");
- if (case_sensitivity_support && !Config_getBool(CASE_SENSE_NAMES))
- {
- // convert key to lower case
- std::transform(key.begin(),key.end(),key.begin(),[](char c){ return std::tolower(c); });
- }
- return key;
-}
-
-//! @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, bool case_sensitivity_support=false>
+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;
@@ -54,9 +42,10 @@ class LinkedMap
//! 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 *key) const
+ const T *find(const char *key_) const
{
- auto it = m_lookup.find(LinkedMap_make_key(key,case_sensitivity_support));
+ std::string key(key_ ? key_ : "");
+ auto it = m_lookup.find(key);
return it!=m_lookup.end() ? it->second : nullptr;
}
@@ -75,7 +64,7 @@ class LinkedMap
T *result = find(k);
if (result==nullptr)
{
- std::string key = LinkedMap_make_key(k,case_sensitivity_support);
+ 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});
@@ -93,7 +82,7 @@ class LinkedMap
T *result = find(k);
if (result==nullptr)
{
- std::string key = LinkedMap_make_key(k,case_sensitivity_support);
+ 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});
@@ -103,10 +92,11 @@ class LinkedMap
}
//! 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 *key)
+ //! Returns true if the object was deleted or false it is was not found.
+ bool del(const char *key_)
{
- auto it = m_lookup.find(LinkedMap_make_key(key,case_sensitivity_support));
+ 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; });
@@ -143,17 +133,18 @@ class LinkedMap
Vec m_entries;
};
-//! @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, bool case_sensitivity_support=false>
+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;
@@ -161,9 +152,10 @@ class LinkedRefMap
//! 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 *key) const
+ const T *find(const char *key_) const
{
- auto it = m_lookup.find(LinkedMap_make_key(key,case_sensitivity_support));
+ std::string key(key_ ? key_ : "");
+ auto it = m_lookup.find(key);
return it!=m_lookup.end() ? it->second : nullptr;
}
@@ -180,7 +172,7 @@ class LinkedRefMap
{
if (find(k)==nullptr) // new element
{
- std::string key = LinkedMap_make_key(k,case_sensitivity_support);
+ std::string key(k ? k : "");
m_lookup.insert({key,obj});
m_entries.push_back(obj);
return true;
@@ -198,7 +190,7 @@ class LinkedRefMap
{
if (find(k)==nullptr) // new element
{
- std::string key = LinkedMap_make_key(k,case_sensitivity_support);
+ std::string key(k ? k : "");
m_lookup.insert({key,obj});
m_entries.insert(m_entries.begin(),obj);
return true;
@@ -210,10 +202,11 @@ class LinkedRefMap
}
//! 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 *key)
+ //! Returns true if the object was deleted or false it is was not found.
+ bool del(const char *key_)
{
- auto it = m_lookup.find(LinkedMap_make_key(key,case_sensitivity_support));
+ 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; });