Imported Upstream version 1.9.1 upstream/1.9.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 15 Oct 2021 02:15:55 +0000 (11:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 15 Oct 2021 02:15:55 +0000 (11:15 +0900)
122 files changed:
.github/workflows/build_cmake.yml
VERSION
addon/doxyapp/CMakeLists.txt
addon/doxyapp/doxyapp.cpp
addon/doxyparse/doxyparse.cpp
addon/doxywizard/config_doxyw.l
addon/doxywizard/doxywizard.cpp
addon/doxywizard/inputstrlist.cpp
doc/changelog.doc
doc/htmlcmds.doc
src/clangparser.cpp
src/clangparser.h
src/classdef.cpp
src/classdef.h
src/classlist.cpp
src/classlist.h
src/code.l
src/commentcnv.l
src/config.xml
src/configimpl.l
src/context.cpp
src/context.h
src/defgen.cpp
src/definition.cpp
src/definition.h
src/definitionimpl.h
src/diagram.cpp
src/dirdef.cpp
src/dirdef.h
src/docbookgen.cpp
src/docgroup.cpp
src/docparser.cpp
src/doctokenizer.l
src/dotdirdeps.cpp
src/dotgroupcollaboration.cpp
src/dotnode.cpp
src/doxygen.cpp
src/doxygen.h
src/example.h
src/filedef.cpp
src/filedef.h
src/fortrancode.l
src/groupdef.cpp
src/groupdef.h
src/htmlgen.cpp
src/htmlhelp.cpp
src/index.cpp
src/index.h
src/latexdocvisitor.cpp
src/latexgen.cpp
src/markdown.cpp
src/memberdef.cpp
src/memberdef.h
src/membergroup.h
src/memberlist.cpp
src/memberlist.h
src/namespacedef.cpp
src/namespacedef.h
src/pagedef.cpp
src/pagedef.h
src/perlmodgen.cpp
src/pycode.l
src/rtfgen.cpp
src/searchindex.cpp
src/searchindex.h
src/sortdict.h
src/sqlite3gen.cpp
src/template.cpp
src/util.cpp
src/util.h
src/vhdlcode.l
src/vhdldocgen.cpp
src/xmlcode.l
src/xmldocvisitor.cpp
src/xmlgen.cpp
templates/html/search.css
templates/xml/compound.xsd
testing/001/indexpage.xml
testing/002/indexpage.xml
testing/003/indexpage.xml
testing/004/indexpage.xml
testing/005/indexpage.xml
testing/006/indexpage.xml
testing/007/indexpage.xml
testing/009/bug.xml
testing/009/deprecated.xml
testing/009/reminders.xml
testing/009/test.xml
testing/009/todo.xml
testing/010/indexpage.xml
testing/012/citelist.xml
testing/012/indexpage.xml
testing/014/indexpage.xml
testing/017/indexpage.xml
testing/020/indexpage.xml
testing/021/indexpage.xml
testing/022/indexpage.xml
testing/023/indexpage.xml
testing/024/indexpage.xml
testing/025/example_test_8cpp-example.xml
testing/028/indexpage.xml
testing/030/indexpage.xml
testing/031/indexpage.xml
testing/032/indexpage.xml
testing/033/indexpage.xml
testing/034/indexpage.xml
testing/038/indexpage.xml
testing/043/another.xml
testing/043/mypage.xml
testing/045/indexpage.xml
testing/049/indexpage.xml
testing/050/indexpage.xml
testing/051/indexpage.xml
testing/052/indexpage.xml
testing/053/indexpage.xml
testing/055/md_055_markdown.xml
testing/056/indexpage.xml
testing/065/indexpage.xml
testing/076/indexpage.xml
testing/079/empty.xml
testing/079/levels.xml
testing/runtests.py

index 3d1f7f3..555319e 100644 (file)
@@ -12,27 +12,31 @@ jobs:
         config:
         - {
             name: "Ubuntu Latest GCC Release",
-            os: ubuntu-latest,
+            os: ubuntu-18.04,
             build_type: "Release", cc: "gcc", cxx: "g++",
-            build_gen: "Unix Makefiles"
+            build_gen: "Unix Makefiles",
+            cmake_extra_opts: "-Dbuild_search=YES -Dbuild_app=YES -Dbuild_parse=YES -Dbuild_xmlparser=YES"
           }
         - {
             name: "Ubuntu Latest GCC Debug",
-            os: ubuntu-latest,
+            os: ubuntu-18.04,
             build_type: "Debug", cc: "gcc", cxx: "g++",
-            build_gen: "Unix Makefiles"
+            build_gen: "Unix Makefiles",
+            cmake_extra_opts: "-Dbuild_search=YES -Dbuild_app=YES -Dbuild_parse=YES -Dbuild_xmlparser=YES"
           }
         - {
             name: "Ubuntu Latest Clang Release",
-            os: ubuntu-latest,
+            os: ubuntu-20.04,
             build_type: "Release", cc: "clang", cxx: "clang++",
-            build_gen: "Unix Makefiles"
+            build_gen: "Unix Makefiles",
+            cmake_extra_opts: "-Duse_libclang=YES -Dstatic_libclang=YES -Duse_libc++=NO"
           }
         - {
             name: "Ubuntu Latest Clang Debug",
-            os: ubuntu-latest,
+            os: ubuntu-20.04,
             build_type: "Debug", cc: "clang", cxx: "clang++",
-            build_gen: "Unix Makefiles"
+            build_gen: "Unix Makefiles",
+            cmake_extra_opts: "-Duse_libclang=YES -Dstatic_libclang=YES -Duse_libc++=NO"
           }
         - {
             name: "macOS Latest Release",
@@ -84,8 +88,8 @@ jobs:
       if: matrix.config.os == 'windows-latest'
 
     - name: Install LaTeX (Linux)
-      run: sudo apt-get install texlive texlive-generic-recommended texlive-extra-utils texlive-latex-extra texlive-font-utils
-      if: matrix.config.os == 'ubuntu-latest'
+      run: sudo apt-get install texlive texlive-latex-recommended texlive-extra-utils texlive-latex-extra texlive-font-utils
+      if: startsWith(matrix.config.os,'ubuntu-')
 
     - name: Install LaTeX (MacOS)
       run: |
@@ -93,6 +97,24 @@ jobs:
         echo "/Library/TeX/texbin/" >> $GITHUB_PATH
       if: matrix.config.os == 'macos-latest'
     
+    - name: Install libclang (Ubuntu 20.04)
+      run: |
+        sudo apt remove llvm-8 clang-8 libclang-common-8-dev clang-format-8 libllvm8
+        #sudo apt remove llvm-10 llvm-10-dev llvm-10-tools llvm-10-runtime clang-10 clang-format-10 libclang-common-10-dev libclang-cpp10 libclang1-10 libllvm10  
+        sudo apt-get autoremove
+        sudo apt-get clean
+        #sudo apt install libclang-9-dev libclang-common-9-dev
+        sudo apt install libclang-10-dev libclang-common-10-dev
+        apt list --installed | egrep '(clang|llvm)'
+        ls -d /usr/lib/llvm-*/include/
+        clang++ -v
+      if: matrix.config.os == 'ubuntu-20.04'
+    
+    - name: Install libxapian (Ubuntu 18.04)
+      run: |
+        sudo apt install libxapian-dev
+      if: matrix.config.os == 'ubuntu-18.04'
+          
     - name: Extract MikTex zip (Windows)
       shell: bash
       run: |
@@ -130,7 +152,7 @@ jobs:
 
     - name: Install Ghostscript (Linux)
       run: sudo apt-get install ghostscript
-      if: matrix.config.os == 'ubuntu-latest'
+      if: startsWith(matrix.config.os,'ubuntu-')
     
     - name: Install Ghostscript (Windows)
       run:
@@ -148,7 +170,7 @@ jobs:
       
     - name: Install xmllint (Linux)
       run: sudo apt-get install libxml2-utils
-      if: matrix.config.os == 'ubuntu-latest'
+      if: startsWith(matrix.config.os,'ubuntu-')
 
     - name: Install xmllint (MacOS)
       run: brew install libxml2
@@ -167,7 +189,7 @@ jobs:
 
     - name: Install Graphviz (Linux)
       run: sudo apt-get install graphviz
-      if: matrix.config.os == 'ubuntu-latest'
+      if: startsWith(matrix.config.os,'ubuntu-')
 
     - name: Install Graphviz (MacOS)
       run: brew install graphviz
@@ -192,6 +214,9 @@ jobs:
         refreshenv
       if: matrix.config.os == 'windows-latest'
     
+    - name: Install Qt
+      uses: jurplel/install-qt-action@v2
+    
     - name: Check tool versions (Linux / MacOS)
       shell: bash
       run: |
@@ -255,9 +280,8 @@ jobs:
             -D CMAKE_BUILD_TYPE=${{ matrix.config.build_type }}
             -G "${{ matrix.config.build_gen }}"
             -Dbuild_doc=YES
-            -Dbuild_app=YES
-            -Dbuild_parse=YES
-            -Dbuild_xmlparser=YES            
+            -Dbuild_wizard=YES
+            ${{ matrix.config.cmake_extra_opts }}            
           RESULT_VARIABLE result
         )
         if (NOT result EQUAL 0)
@@ -283,6 +307,12 @@ jobs:
           message(FATAL_ERROR "Build failed")
         endif()
 
+    - name: Archive build artifacts
+      uses: actions/upload-artifact@v2
+      with:
+        name: "${{ matrix.config.name }} build artifacts"
+        path: build/bin/
+
     - name: Run tests (Linux / MacOS)
       shell: cmake -P {0}
       run: |
diff --git a/VERSION b/VERSION
index f8e233b..9ab8337 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.9.0
+1.9.1
index 3e58d32..707fded 100644 (file)
@@ -15,11 +15,23 @@ doxyapp.cpp
 add_sanitizers(doxyapp)
 
 if (use_libclang)
+    find_package(LLVM REQUIRED CONFIG)
+    find_package(Clang REQUIRED CONFIG)
+    if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+        target_compile_features(doxyapp PRIVATE cxx_alignof)
+        if (use_libc++)
+            target_compile_options(doxyapp PRIVATE -stdlib=libc++)
+        endif()
+    endif()
+    include_directories(${LLVM_INCLUDE_DIRS})
+    add_definitions(${LLVM_DEFINITIONS})
     if (static_libclang)
-        set(CLANG_LIBS libclang clangTooling ${llvm_libs})
-    else()
-        set(CLANG_LIBS libclang clang-cpp ${llvm_libs})
+        set(CLANG_LIBS libclang clangTooling)
+    else() # dynamically linked version of clang
+        llvm_config(doxymain USE_SHARED support)
+        set(CLANG_LIBS libclang clang-cpp)
     endif()
+    target_compile_definitions(doxyapp PRIVATE ${LLVM_DEFINITIONS})
 endif()
 
 target_link_libraries(doxyapp
index b89c5d9..5fc07be 100644 (file)
@@ -296,9 +296,6 @@ int main(int argc,char **argv)
     }
   }
 
-  // remove temporary files
-  if (!Doxygen::objDBFileName.isEmpty()) QFile::remove(Doxygen::objDBFileName);
-  if (!Doxygen::entryDBFileName.isEmpty()) QFile::remove(Doxygen::entryDBFileName);
   // clean up after us
   QDir().rmdir("/tmp/doxygen");
 
index df9069b..1181231 100644 (file)
@@ -528,8 +528,6 @@ int main(int argc,char **argv) {
 
   QDir thisDir;
   // remove temporary files
-  if (!Doxygen::objDBFileName.isEmpty())    thisDir.remove(Doxygen::objDBFileName);
-  if (!Doxygen::entryDBFileName.isEmpty())  thisDir.remove(Doxygen::entryDBFileName);
   if (!Doxygen::filterDBFileName.isEmpty()) thisDir.remove(Doxygen::filterDBFileName);
 
   // clean up after us
index 6b487ee..b93a79d 100644 (file)
@@ -729,6 +729,7 @@ void writeStringValue(QTextStream &t,QTextCodec *codec,const QString &s)
       while (!(c=*p++).isNull() && !needsEscaping)
       {
         needsEscaping = (c==QChar::fromLatin1(' ')  ||
+                        c==QChar::fromLatin1(',') ||
                         c==QChar::fromLatin1('\n') ||
                         c==QChar::fromLatin1('\t') ||
                         c==QChar::fromLatin1('"'));
index c75279b..f713025 100755 (executable)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright (C) 1997-2019 by Dimitri van Heesch.
+ * Copyright (C) 1997-2021 by Dimitri van Heesch.
  *
  * Permission to use, copy, modify, and distribute this software and its
  * documentation under the terms of the GNU General Public License is hereby
@@ -275,7 +275,7 @@ void MainWindow::about()
               QString::fromLatin1(qVersion());
        }
   t << QString::fromLatin1(")</center><p><br>"
-       "<center>Written by<br> Dimitri van Heesch<br>&copy; 2000-2019</center><p>"
+       "<center>Written by<br> Dimitri van Heesch<br>&copy; 2000-2021</center><p>"
        "</qt>");
   QMessageBox::about(this,tr("Doxygen GUI"),msg);
 }
index fae45b5..cdc7d14 100644 (file)
@@ -258,48 +258,57 @@ void InputStrList::writeValue(QTextStream &t,QTextCodec *codec)
   }
 }
 
-#include <QMessageBox>
 bool InputStrList::isDefault()
 {
-  bool isEq = m_strList==m_default;
+  if (m_strList==m_default) return true;
 
-  if (!isEq)
+  auto it1 = m_strList.begin();
+  auto it2 = m_default.begin();
+  while (it1!=m_strList.end() && (*it1).isEmpty())
   {
-    isEq = true;
+    ++it1;
+  }
+  while (it2!=m_default.end() && (*it2).isEmpty())
+  {
+    ++it2;
+  }
+  // both lists are empty
+  if (it1==m_strList.end() && it2==m_default.end()) return true;
 
-    auto it1 = m_strList.begin();
-    auto it2 = m_default.begin();
-    while (it1!=m_strList.end() && it2!=m_default.end())
+  // one list is empty but the other is not
+  if (it1==m_default.end()) return false;
+  if (it2==m_strList.end()) return false;
+
+  it1 = m_strList.begin();
+  it2 = m_default.begin();
+  while (it1!=m_strList.end() && it2!=m_default.end())
+  {
+    // skip over empty values
+    while (it1!=m_strList.end() && (*it1).isEmpty())
     {
-      // skip over empty values
-      while (it1!=m_strList.end() && (*it1).isEmpty())
-      {
       ++it1;
-      }
-      while (it2!=m_default.end() && (*it2).isEmpty())
-      {
-        ++it2;
-      }
-      if ((it1!=m_strList.end()) && (it2!=m_default.end()))
-      {
-        if ((*it1).trimmed()!= (*it2).trimmed()) // difference so not the default
-        {
-          isEq=false;
-          break;
-        }
-        ++it1;
-        ++it2;
-      }
-      else if ((it1!=m_strList.end()) || (it2!=m_default.end()))
+    }
+    while (it2!=m_default.end() && (*it2).isEmpty())
+    {
+      ++it2;
+    }
+    if ((it1!=m_strList.end()) && (it2!=m_default.end()))
+    {
+      if ((*it1).trimmed()!= (*it2).trimmed()) // difference so not the default
       {
-        // one list empty so cannot be the default
-        isEq=false;
-        break;
+        return false;
       }
+      ++it1;
+      ++it2;
+    }
+    else if ((it1!=m_strList.end()) || (it2!=m_default.end()))
+    {
+      // one list empty so cannot be the default
+      return false;
     }
   }
 
-  return isEq;
+  return true;
 }
 
 bool InputStrList::isEmpty()
index 0af6fd7..df4293b 100644 (file)
@@ -1,6 +1,86 @@
 /** \page changelog Changelog
 \tableofcontents{html,latex}
 \section log_1_9 1.9 Series
+\subsection log_1_9_1 Release 1.9.1
+\htmlonly
+<b>(release date 08-01-2021)</b>
+</p>
+<h3>Bug fixes</h3>
+<ul>
+<li>issue #8282: Error on ALIAS declaration without quotes [<a href="https://github.com/doxygen/doxygen/commit/c03dd8a0105a6d020983981d17b1429dd4835103">view</a>]</li>
+<li>issue #8286: Incorrect processing of VHDL strings [<a href="https://github.com/doxygen/doxygen/commit/05fc04d307bc52ac7077c788de751b536032963d">view</a>], [<a href="http://github.com/doxygen/doxygen/commit/175839272b098316a7ec434a85154fbf27669c3e">view</a>]</li>
+<li>issue #8291: Doxygen crash on Windows when INLINE_SIMPLE_STRUCTS=YES [<a href="https://github.com/doxygen/doxygen/commit/4008be91ff3a2b5defb8a54af5edf15b4ca99c0e">view</a>]</li>
+<li>issue #8294: Draw sibling dependee directories within same parent directoy in directory dependency graph.
+[<a href="https://github.com/doxygen/doxygen/commit/f80b03899246f9b2e0d52bafafffaca01ad08f0f">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/a61f19c0bc756482d7e7b4314d84f44d387eeea1">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/95ba6002eb7d5e8c43a64a239d39ca99015caa09">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/6e52be862cdbd5989c31402a3ef1dad5d9a98062">view</a>], and
+[<a href="https://github.com/doxygen/doxygen/commit/9433c13f61452b3f9b3978e8c630d7754d36108c">view</a>]</li>
+<li>issue #8295: segmentation fault [<a href="https://github.com/doxygen/doxygen/commit/1b54e3272da36f17c8d82fda9ee6e8223c9fb201">view</a>]</li>
+<li>issue #8296: LaTeX Error: File ... not found. [<a href="https://github.com/doxygen/doxygen/commit/f3dfa40be43c0a835445e74dcf7b5fb03a9d843c">view</a>], and [<a href="https://github.com/doxygen/doxygen/commit/c5b4375d22dc3b0f97c63df3fdecae7f79a96e62">view</a>]</li>
+<li>issue #8297: fails to parse list of INPUT files [<a href="https://github.com/doxygen/doxygen/commit/4a97d104a07a1796f222bc0763b89396b35e7b7d">view</a>]</li>
+<li>issue #8300: File naming changed in Doxygen 1.9.0 [<a href="https://github.com/doxygen/doxygen/commit/e9ca9dcd2b4606dedfde0e6f9084c654f09becc8">view</a>]</li>
+<li>issue #8304: compilation failure [<a href="https://github.com/doxygen/doxygen/commit/19713dcc51ceb3930770cb25ec85590b86316cf7">view</a>]</li>
+<li>issue #8311: Markdown table: double-quote ruins the output [<a href="https://github.com/doxygen/doxygen/commit/a402beb8e0c0c2fcaaf4b6317d31d52a767e930d">view</a>]</li>
+<li>Fix cases where classes inside inline namespaces could lead to crashes [<a href="https://github.com/doxygen/doxygen/commit/da8c801a4d08baeee8007276c1f73f11c4a890ce">view</a>]</li>
+<li>Fix coverity dead-code warning [<a href="https://github.com/doxygen/doxygen/commit/dabed1c3e46157c6690179c2aadbea5055bfef54">view</a>]</li>
+<li>Fix potential crash with inline namespace [<a href="https://github.com/doxygen/doxygen/commit/4a070f8b60eefa7997c9fdd59553970de3645207">view</a>]</li>
+<li>Incorrect entries on treeview [<a href="https://github.com/doxygen/doxygen/commit/d557c9cc9aed41c305af5c10524e3dad1a902539">view</a>]</li>
+<li>Layout in doxywizard documentation [<a href="https://github.com/doxygen/doxygen/commit/4974050bdc19974a22641f856c9ece95ec973999">view</a>]</li>
+<li>Various fixes based on coverity scan results [<a href="https://github.com/doxygen/doxygen/commit/3f4717ec5583dde8116205e1045095158ab56c15">view</a>]</li>
+<li>bug_549093 Regular HTML comments are removed. [<a href="https://github.com/doxygen/doxygen/commit/7598b054b3bad6a7bf0cd3e3b4dd568d695b4510">view</a>]</li>
+</ul>
+<h3>Features</h3>
+<ul>
+<li>Add a CLANG_ADD_INC_PATHS option which can be used to control whether the directory of every input file is added as an include when using Clang assisted parsing.
+[<a href="https://github.com/doxygen/doxygen/commit/ff3f889eb1d593e89b8b7f1b613658de0fc1d95f">view</a>], and
+[<a href="https://github.com/doxygen/doxygen/commit/3fa5accc93b0ee68ec6bd354cbd0127ae827630f">view</a>]</li>
+<li>Add some missing info to the XML output
+[<a href="https://github.com/doxygen/doxygen/commit/db1d1fa78e53248ea96a26700b52c393f54c521f">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/8e2d091818580e25a133257909c19cddc2f80054">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/8e0f3b40fc36f38cf3b5d78d859b1e8678de0069">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/0db750805f7028a32a30330a1558405dd3eea92e">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/04c8d255bdf00e3e470896965ed37d1f15f8f81b">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/c37fe44163a254835aef8cf05e59979b18552ab0">view</a>],
+[<a href="https://github.com/doxygen/doxygen/commit/352ab16413d51c655741cff927911f6126471198">view</a>],
+and
+[<a href="http://github.com/doxygen/doxygen/commit/7527114a304dbb9e21236a453ed0f2e1bd51b884">view</a>]</li>
+</li>
+</ul>
+<h3>Refactoring and cleanup</h3>
+<ul>
+<li>Embed MemberGroup objects directly in their container [<a href="https://github.com/doxygen/doxygen/commit/d37c654efbd5bb4ea19e1997d1daccb0b01de8b3">view</a>]</li>
+<li>Modernise client side part of searchindex [<a href="https://github.com/doxygen/doxygen/commit/03cfc3d6eb95d2454c6d155c1ce8cb3d3bad3621">view</a>]</li>
+<li>avoid copying MemberLists by not embedding them directly [<a href="https://github.com/doxygen/doxygen/commit/5d980fa30b6524d3d53867e6fd8d6edb67a37eeb">view</a>]</li>
+<li>change MemberGroupSDict to MemberGroupList [<a href="https://github.com/doxygen/doxygen/commit/2bb3a8790770f0aa05cf0b7c2d13e2b5e7e27afe">view</a>]</li>
+<li>change type of m_cache [<a href="https://github.com/doxygen/doxygen/commit/6f6460a6b84c5ab6bced3aea842afd5b28f4bca3">view</a>]</li>
+<li>change type of vhdlSummaryTitles from SDict&lt;QCString&gt; to StringSet [<a href="https://github.com/doxygen/doxygen/commit/3f19ac46f74dca80c3c18afb83675c0fc8e096c4">view</a>]</li>
+<li>moderize Doxygen::dirRelations [<a href="https://github.com/doxygen/doxygen/commit/73127b5d8d36b3cec8df662d4e84d2109bb195d9">view</a>]</li>
+<li>modernise Doxygen::clangUsrMap [<a href="https://github.com/doxygen/doxygen/commit/3867926d7162704c8232af95316dbc14e313f9c3">view</a>]</li>
+<li>modernise MemberGroupList [<a href="https://github.com/doxygen/doxygen/commit/efa76fb818ff37ed2bde1675a11d36dc852727e5">view</a>]</li>
+<li>modernise member indices [<a href="https://github.com/doxygen/doxygen/commit/9c9958f5faac018b4e2f117e9ae5fd7f79a9cc02">view</a>]</li>
+<li>modernize getMemberLists() [<a href="https://github.com/doxygen/doxygen/commit/ef5be2c99caa8e5fbc1cec3ec53e91b2c929f613">view</a>]</li>
+<li>remove SIntDict and SIntList (no longer used) [<a href="https://github.com/doxygen/doxygen/commit/4ea5a30e94f6f8ca089380c19b36a9a98265360a">view</a>]</li>
+<li>remove unused ClassList [<a href="https://github.com/doxygen/doxygen/commit/359ff95956304ea7727ccc82864862622a9a3cf7">view</a>]</li>
+<li>remove unused DirSDict class [<a href="https://github.com/doxygen/doxygen/commit/90be949366f217c3880b46bef08614357551a178">view</a>]</li>
+<li>remove unused Doxygen::entryDBFileName and Doxygen::objDBFileName [<a href="https://github.com/doxygen/doxygen/commit/7f79d52ff6da7bcabc6b0250ca93b4307358e8e3">view</a>]</li>
+<li>remove unused Doxygen::htmlDirMap [<a href="https://github.com/doxygen/doxygen/commit/eec3c9ab5eb881d596b489f1f6024e4ac29f23ce">view</a>]</li>
+<li>remove unused GenericsSDict class [<a href="https://github.com/doxygen/doxygen/commit/941bcb4a363771c85d4c1d748db2cba0df1bcaf4">view</a>]</li>
+<li>remove unused IndexFieldSDict class [<a href="https://github.com/doxygen/doxygen/commit/c24c84b770e7593b3920fe28b83847eb3deff46b">view</a>]</li>
+<li>replace Doxygen::directories by Doxygen::dirLinkedMap [<a href="https://github.com/doxygen/doxygen/commit/54d939984cd99ee3414f6b8aee3a90a134ba8677">view</a>]</li>
+<li>replace Doxygen::groupSDict by Doxygen::groupLinkedMap [<a href="https://github.com/doxygen/doxygen/commit/b6bf2aa567a12a0c4011470e53b0a1740b6eb796">view</a>]</li>
+<li>replace Doxygen::memGrpInfoDict by Doxygen::memberGroupInfoMap [<a href="https://github.com/doxygen/doxygen/commit/34ac30b4e46023e0c86247dac4d47fce0ae1d4f8">view</a>]</li>
+<li>replace ExampleSDict by ExampleList [<a href="https://github.com/doxygen/doxygen/commit/75e96744145e9e21f28691e6d0c9b16523050356">view</a>]</li>
+<li>replace MemberSDict by MemberLinkedRefMap [<a href="https://github.com/doxygen/doxygen/commit/0252f61004cada8f9e10644b850dd6ba47d61438">view</a>]</li>
+<li>replace QMap by std::map in vhdldocgen [<a href="https://github.com/doxygen/doxygen/commit/86a75ee26cee5ea3e40dea57665f534f319cfc5d">view</a>]</li>
+<li>replace type of pack variable from SDict&lt;QCString&gt; to StringSet [<a href="https://github.com/doxygen/doxygen/commit/1c9096bc72f1b21d3090650d81c4ce3f78279a82">view</a>]</li>
+<li>replaced PageSDict by PageLinked*Map [<a href="https://github.com/doxygen/doxygen/commit/6675be21d5085d97b2167959573bc71e42dd93b8">view</a>]</li>
+<li>Optimize: usedDir can not be parent of dd if they have the same parent. [<a href="https://github.com/doxygen/doxygen/commit/6916b03899f9980b536c5735c8069a15eff4e5ce">view</a>]</li>
+<li>Replaced UsedDirsContainer with UsedDirLinkedMap [<a href="https://github.com/doxygen/doxygen/commit/0c1bc5557d811d662b4144f14ef716d9e950d60d">view</a>]</li>
+<li>Substitute `QDict&lt;UsedDir&gt;` with `std::map&lt;QCString, UsedDir * &gt;`. [<a href="https://github.com/doxygen/doxygen/commit/3e1fa4563ba16e413355601fec55072dde89fa35">view</a>]</li>
+</ul>
+<p>
+\endhtmlonly
 
 \subsection log_1_9_0 Release 1.9.0
 \htmlonly
index edc14d9..524233c 100644 (file)
@@ -390,6 +390,7 @@ comments can be used:
 \verbatim
 /*! <!-- This is a comment with a comment block --> Visible text */
 \endverbatim
+The part `<!-- ... -->` will not be shown in the main documentation.
 
 
 \htmlonly
index 934da31..4129d55 100644 (file)
@@ -137,7 +137,7 @@ class ClangTUParser::Private
     StringVector filesInSameTU;
 
     // state while parsing sources
-    MemberDef  *currentMemberDef=0;
+    const MemberDef  *currentMemberDef=0;
     uint        currentLine=0;
     bool        searchForBody=FALSE;
     bool        insideBody=FALSE;
@@ -163,6 +163,7 @@ void ClangTUParser::parse()
   //printf("ClangTUParser::ClangTUParser(fileName=%s,#filesInSameTU=%d)\n",
   //    qPrint(fileName),(int)p->filesInSameTU.size());
   bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
+  bool clangIncludeInputPaths = Config_getBool(CLANG_ADD_INC_PATHS);
   bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
   const StringVector &includePath = Config_getList(INCLUDE_PATH);
   const StringVector &clangOptions = Config_getList(CLANG_OPTIONS);
@@ -211,11 +212,14 @@ void ClangTUParser::parse()
   else
   {
     // add include paths for input files
-    for (const std::string &path : Doxygen::inputPaths)
+    if (clangIncludeInputPaths)
     {
-      QCString inc = QCString("-I")+path.data();
-      argv[argc++]=qstrdup(inc.data());
-      //printf("argv[%d]=%s\n",argc,argv[argc]);
+      for (const std::string &path : Doxygen::inputPaths)
+      {
+        QCString inc = QCString("-I")+path.data();
+        argv[argc++]=qstrdup(inc.data());
+        //printf("argv[%d]=%s\n",argc,argv[argc]);
+      }
     }
     // add external include paths
     for (size_t i=0;i<includePath.size();i++)
@@ -346,7 +350,7 @@ ClangTUParser::~ClangTUParser()
   p->tu        = 0;
 }
 
-void ClangTUParser::switchToFile(FileDef *fd)
+void ClangTUParser::switchToFile(const FileDef *fd)
 {
   //printf("ClangTUParser::switchToFile(%s) this=%p\n",qPrint(fd->absFilePath()),this);
   if (p->tu)
@@ -486,13 +490,13 @@ QCString ClangTUParser::lookup(uint line,const char *symbol)
 }
 
 
-void ClangTUParser::writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line)
+void ClangTUParser::writeLineNumber(CodeOutputInterface &ol,const FileDef *fd,uint line)
 {
-  Definition *d = fd ? fd->getSourceDefinition(line) : 0;
+  const Definition *d = fd ? fd->getSourceDefinition(line) : 0;
   if (d && d->isLinkable())
   {
     p->currentLine=line;
-    MemberDef *md = fd->getSourceMember(line);
+    const MemberDef *md = fd->getSourceMember(line);
     if (md && md->isLinkable())  // link to member
     {
       if (p->currentMemberDef!=md) // new member, start search for body
@@ -532,7 +536,7 @@ void ClangTUParser::writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint lin
   //printf("writeLineNumber(%d) g_searchForBody=%d\n",line,g_searchForBody);
 }
 
-void ClangTUParser::codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text,
+void ClangTUParser::codifyLines(CodeOutputInterface &ol,const FileDef *fd,const char *text,
                         uint &line,uint &column,const char *fontClass)
 {
   if (fontClass) ol.startFontClass(fontClass);
@@ -569,8 +573,8 @@ void ClangTUParser::codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *
 }
 
 void ClangTUParser::writeMultiLineCodeLink(CodeOutputInterface &ol,
-                  FileDef *fd,uint &line,uint &column,
-                  Definition *d,
+                  const FileDef *fd,uint &line,uint &column,
+                  const Definition *d,
                   const char *text)
 {
   static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
@@ -609,7 +613,7 @@ void ClangTUParser::writeMultiLineCodeLink(CodeOutputInterface &ol,
   }
 }
 
-void ClangTUParser::linkInclude(CodeOutputInterface &ol,FileDef *fd,
+void ClangTUParser::linkInclude(CodeOutputInterface &ol,const FileDef *fd,
     uint &line,uint &column,const char *text)
 {
   QCString incName = text;
@@ -643,7 +647,7 @@ void ClangTUParser::linkInclude(CodeOutputInterface &ol,FileDef *fd,
   }
 }
 
-void ClangTUParser::linkMacro(CodeOutputInterface &ol,FileDef *fd,
+void ClangTUParser::linkMacro(CodeOutputInterface &ol,const FileDef *fd,
     uint &line,uint &column,const char *text)
 {
   MemberName *mn=Doxygen::functionNameLinkedMap->find(text);
@@ -662,7 +666,7 @@ void ClangTUParser::linkMacro(CodeOutputInterface &ol,FileDef *fd,
 }
 
 
-void ClangTUParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
+void ClangTUParser::linkIdentifier(CodeOutputInterface &ol,const FileDef *fd,
     uint &line,uint &column,const char *text,int tokenIndex)
 {
   CXCursor c = p->cursors[tokenIndex];
@@ -679,7 +683,12 @@ void ClangTUParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
   CXString usr = clang_getCursorUSR(c);
   const char *usrStr = clang_getCString(usr);
 
-  Definition *d = usrStr ? Doxygen::clangUsrMap->find(usrStr) : 0;
+  const Definition *d = 0;
+  auto kv = Doxygen::clangUsrMap->find(usrStr);
+  if (kv!=Doxygen::clangUsrMap->end())
+  {
+    d = kv->second;
+  }
   //CXCursorKind kind = clang_getCursorKind(c);
   //if (d==0)
   //{
@@ -739,7 +748,7 @@ void ClangTUParser::detectFunctionBody(const char *s)
   }
 }
 
-void ClangTUParser::writeSources(CodeOutputInterface &ol,FileDef *fd)
+void ClangTUParser::writeSources(CodeOutputInterface &ol,const FileDef *fd)
 {
   // (re)set global parser state
   p->currentMemberDef=0;
@@ -895,7 +904,7 @@ std::unique_ptr<ClangTUParser> ClangParser::createTUParser(const FileDef *fd) co
 //--------------------------------------------------------------------------
 #else // use stubbed functionality in case libclang support is disabled.
 
-void ClangTUParser::switchToFile(FileDef *fd)
+void ClangTUParser::switchToFile(const FileDef *fd)
 {
 }
 
index f948c33..83aafdd 100644 (file)
@@ -32,7 +32,7 @@ class ClangTUParser
     /** Switches to another file within the translation unit started with start().
      *  @param[in] fd The file definition with the name of the file to switch to.
      */
-    void switchToFile(FileDef *fd);
+    void switchToFile(const FileDef *fd);
 
     /** Returns the list of files for this translation unit */
     StringVector filesInSameTU() const;
@@ -46,23 +46,23 @@ class ClangTUParser
      *  @param[out] ol The output generator list to write to.
      *  @param[in]  fd The file to write sources for.
      */
-    void writeSources(CodeOutputInterface &ol,FileDef *fd);
+    void writeSources(CodeOutputInterface &ol,const FileDef *fd);
 
   private:
     void detectFunctionBody(const char *s);
-    void writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line);
-    void codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text,
+    void writeLineNumber(CodeOutputInterface &ol,const FileDef *fd,uint line);
+    void codifyLines(CodeOutputInterface &ol,const FileDef *fd,const char *text,
                      uint &line,uint &column,const char *fontClass=0);
     void writeMultiLineCodeLink(CodeOutputInterface &ol,
-                                FileDef *fd,uint &line,uint &column,
-                                Definition *d, const char *text);
-    void linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
+                                const FileDef *fd,uint &line,uint &column,
+                                const Definition *d, const char *text);
+    void linkIdentifier(CodeOutputInterface &ol,const FileDef *fd,
                         uint &line,uint &column,
                         const char *text,int tokenIndex);
-    void linkMacro(CodeOutputInterface &ol,FileDef *fd,
+    void linkMacro(CodeOutputInterface &ol,const FileDef *fd,
                    uint &line,uint &column,
                    const char *text);
-    void linkInclude(CodeOutputInterface &ol,FileDef *fd,
+    void linkInclude(CodeOutputInterface &ol,const FileDef *fd,
                    uint &line,uint &column,
                    const char *text);
     ClangTUParser(const ClangTUParser &) = delete;
index b3eb353..88bc44c 100644 (file)
@@ -222,8 +222,8 @@ class ClassDefImpl : public DefinitionMixin<ClassDefMutable>
     virtual ClassDef *categoryOf() const;
     virtual QCString className() const;
     virtual MemberList *getMemberList(MemberListType lt) const;
-    virtual const QList<MemberList> &getMemberLists() const;
-    virtual MemberGroupSDict *getMemberGroupSDict() const;
+    virtual const MemberLists &getMemberLists() const;
+    virtual const MemberGroupList &getMemberGroups() const;
     virtual QDict<int> *getTemplateBaseClassNames() const;
     virtual ClassDef *getVariableInstance(const char *templSpec) const;
     virtual bool isUsedOnly() const;
@@ -237,7 +237,7 @@ class ClassDefImpl : public DefinitionMixin<ClassDefMutable>
     virtual QCString generatedFromFiles() const;
     virtual const FileList &usedFiles() const;
     virtual const ArgumentList &typeConstraints() const;
-    virtual const ExampleSDict *exampleList() const;
+    virtual const ExampleList &getExamples() const;
     virtual bool hasExamples() const;
     virtual QCString getMemberListFileName() const;
     virtual bool subGrouping() const;
@@ -321,7 +321,6 @@ class ClassDefImpl : public DefinitionMixin<ClassDefMutable>
     void writeDocumentationContents(OutputList &ol,const QCString &pageTitle) const;
     void internalInsertMember(MemberDef *md,Protection prot,bool addToAllList);
     void addMemberToList(MemberListType lt,MemberDef *md,bool isBrief);
-    MemberList *createMemberList(MemberListType lt);
     void writeInheritedMemberDeclarations(OutputList &ol,MemberListType lt,int lt2,const QCString &title,
                                           const ClassDef *inheritedFrom,bool invert,
                                           bool showAlways,QPtrDict<void> *visitedClasses) const;
@@ -493,10 +492,10 @@ class ClassDefAliasImpl : public DefinitionAliasMixin<ClassDef>
     { return getCdAlias()->className(); }
     virtual MemberList *getMemberList(MemberListType lt) const
     { return getCdAlias()->getMemberList(lt); }
-    virtual const QList<MemberList> &getMemberLists() const
+    virtual const MemberLists &getMemberLists() const
     { return getCdAlias()->getMemberLists(); }
-    virtual MemberGroupSDict *getMemberGroupSDict() const
-    { return getCdAlias()->getMemberGroupSDict(); }
+    virtual const MemberGroupList &getMemberGroups() const
+    { return getCdAlias()->getMemberGroups(); }
     virtual QDict<int> *getTemplateBaseClassNames() const
     { return getCdAlias()->getTemplateBaseClassNames(); }
     virtual ClassDef *getVariableInstance(const char *templSpec) const
@@ -523,8 +522,8 @@ class ClassDefAliasImpl : public DefinitionAliasMixin<ClassDef>
     { return getCdAlias()->usedFiles(); }
     virtual const ArgumentList &typeConstraints() const
     { return getCdAlias()->typeConstraints(); }
-    virtual const ExampleSDict *exampleList() const
-    { return getCdAlias()->exampleList(); }
+    virtual const ExampleList &getExamples() const
+    { return getCdAlias()->getExamples(); }
     virtual bool hasExamples() const
     { return getCdAlias()->hasExamples(); }
     virtual QCString getMemberListFileName() const
@@ -627,7 +626,7 @@ class ClassDefImpl::IMPL
     FileList files;
 
     /*! Examples that use this class */
-    ExampleSDict *exampleSDict = 0;
+    ExampleList examples;
 
     /*! Holds the kind of "class" this is. */
     ClassDef::CompoundType compType;
@@ -674,10 +673,10 @@ class ClassDefImpl::IMPL
      */
     ClassDef *categoryOf = 0;
 
-    QList<MemberList> memberLists;
+    MemberLists memberLists;
 
     /* user defined member groups */
-    MemberGroupSDict *memberGroupSDict = 0;
+    MemberGroupList memberGroups;
 
     /*! Is this an abstract class? */
     bool isAbstract = false;
@@ -703,7 +702,7 @@ class ClassDefImpl::IMPL
     bool usedOnly = false;
 
     /** List of titles to use for the summary */
-    SDict<QCString> vhdlSummaryTitles;
+    StringSet vhdlSummaryTitles;
 
     /** Is this a simple (non-nested) C structure? */
     bool isSimple = false;
@@ -732,7 +731,6 @@ void ClassDefImpl::IMPL::init(const char *defFileName, const char *name,
   {
     fileName=ctStr+name;
   }
-  exampleSDict = 0;
   incInfo=0;
   prot=Public;
   nspace=0;
@@ -741,7 +739,6 @@ void ClassDefImpl::IMPL::init(const char *defFileName, const char *name,
   usedByImplClassDict=0;
   usesIntfClassDict=0;
   constraintClassDict=0;
-  memberGroupSDict = 0;
   subGrouping=Config_getBool(SUBGROUPING);
   templateInstances = 0;
   variableInstances = 0;
@@ -774,20 +771,17 @@ void ClassDefImpl::IMPL::init(const char *defFileName, const char *name,
   }
 }
 
-ClassDefImpl::IMPL::IMPL() : vhdlSummaryTitles(17)
+ClassDefImpl::IMPL::IMPL()
 {
-  vhdlSummaryTitles.setAutoDelete(TRUE);
 }
 
 ClassDefImpl::IMPL::~IMPL()
 {
-  delete exampleSDict;
   delete usesImplClassDict;
   delete usedByImplClassDict;
   delete usesIntfClassDict;
   delete constraintClassDict;
   delete incInfo;
-  delete memberGroupSDict;
   delete templateInstances;
   delete variableInstances;
   delete templBaseClassNames;
@@ -855,28 +849,21 @@ void ClassDefImpl::insertSubClass(ClassDef *cd,Protection p,
 
 void ClassDefImpl::addMembersToMemberGroup()
 {
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     if ((ml->listType()&MemberListType_detailedLists)==0)
     {
-      ::addMembersToMemberGroup(ml,&m_impl->memberGroupSDict,this);
+      ::addMembersToMemberGroup(ml.get(),&m_impl->memberGroups,this);
     }
   }
 
   // add members inside sections to their groups
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    if (mg->allMembersInSameSection() && m_impl->subGrouping)
     {
-      if (mg->allMembersInSameSection() && m_impl->subGrouping)
-      {
-        //printf("addToDeclarationSection(%s)\n",mg->header().data());
-        mg->addToDeclarationSection();
-      }
+      //printf("addToDeclarationSection(%s)\n",mg->header().data());
+      mg->addToDeclarationSection();
     }
   }
 }
@@ -893,10 +880,7 @@ void ClassDefImpl::internalInsertMember(MemberDef *md,
   if (getLanguage()==SrcLangExt_VHDL)
   {
     QCString title=theTranslator->trVhdlType(md->getMemberSpecifiers(),FALSE);
-    if (!m_impl->vhdlSummaryTitles.find(title))
-    {
-      m_impl->vhdlSummaryTitles.append(title,new QCString(title));
-    }
+    m_impl->vhdlSummaryTitles.insert(title.str());
   }
 
   if (1 /*!isReference()*/) // changed to 1 for showing members of external
@@ -1116,8 +1100,7 @@ void ClassDefImpl::internalInsertMember(MemberDef *md,
               case MemberType_Function:
                 if (md->isConstructor() || md->isDestructor())
                 {
-                  MemberList *ml = createMemberList(MemberListType_constructors);
-                  ml->append(md);
+                  m_impl->memberLists.get(MemberListType_constructors)->append(md);
                 }
                 else
                 {
@@ -1181,12 +1164,7 @@ void ClassDefImpl::insertMember(MemberDef *md)
 // compute the anchors for all members
 void ClassDefImpl::computeAnchors()
 {
-  //ClassDef *context = Config_getBool(INLINE_INHERITED_MEMB) ? this : 0;
-  //const char *letters = "abcdefghijklmnopqrstuvwxyz0123456789";
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  //int index = 0;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     if ((ml->listType()&MemberListType_detailedLists)==0)
     {
@@ -1194,27 +1172,17 @@ void ClassDefImpl::computeAnchors()
     }
   }
 
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->setAnchors();
-    }
+    mg->setAnchors();
   }
 }
 
 void ClassDefImpl::distributeMemberGroupDocumentation()
 {
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->distributeMemberGroupDocumentation();
-    }
+    mg->distributeMemberGroupDocumentation();
   }
 }
 
@@ -1222,18 +1190,11 @@ void ClassDefImpl::findSectionsInDocumentation()
 {
   docFindSections(briefDescription(),this,docFile());
   docFindSections(documentation(),this,docFile());
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->findSectionsInDocumentation(this);
-    }
+    mg->findSectionsInDocumentation(this);
   }
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     if ((ml->listType()&MemberListType_detailedLists)==0)
     {
@@ -1461,12 +1422,12 @@ void ClassDefImpl::writeDetailedDocumentationBody(OutputList &ol) const
   writeTypeConstraints(ol,this,m_impl->typeConstraints);
 
   // write examples
-  if (hasExamples() && m_impl->exampleSDict)
+  if (hasExamples())
   {
     ol.startExamples();
     ol.startDescForItem();
     //ol.startParagraph();
-    writeExample(ol,m_impl->exampleSDict);
+    writeExamples(ol,m_impl->examples);
     //ol.endParagraph();
     ol.endDescForItem();
     ol.endExamples();
@@ -2004,22 +1965,16 @@ void ClassDefImpl::writeIncludeFiles(OutputList &ol) const
 void ClassDefImpl::writeMemberGroups(OutputList &ol,bool showInline) const
 {
   // write user defined member groups
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    m_impl->memberGroupSDict->sort();
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
     {
-      if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
-      {
-        mg->writeDeclarations(ol,this,0,0,0,showInline);
-      }
-      else // add this group to the corresponding member section
-      {
-        //printf("addToDeclarationSection(%s)\n",mg->header().data());
-        //mg->addToDeclarationSection();
-      }
+      mg->writeDeclarations(ol,this,0,0,0,showInline);
+    }
+    else // add this group to the corresponding member section
+    {
+      //printf("addToDeclarationSection(%s)\n",mg->header().data());
+      //mg->addToDeclarationSection();
     }
   }
 }
@@ -2132,10 +2087,9 @@ void ClassDefImpl::writeSummaryLinks(OutputList &ol) const
   }
   else // VDHL only
   {
-    SDict<QCString>::Iterator li(m_impl->vhdlSummaryTitles);
-    for (li.toFirst();li.current();++li)
+    for (const auto &s : m_impl->vhdlSummaryTitles)
     {
-      ol.writeSummaryLink(0,convertToId(li.current()->data()),li.current()->data(),first);
+      ol.writeSummaryLink(0,convertToId(s.c_str()),s.c_str(),first);
       first=FALSE;
     }
   }
@@ -2230,14 +2184,9 @@ void ClassDefImpl::writeTagFile(FTextStream &tagFile)
         break;
       case LayoutDocEntry::MemberGroups:
         {
-          if (m_impl->memberGroupSDict)
+          for (const auto &mg : m_impl->memberGroups)
           {
-            MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-            MemberGroup *mg;
-            for (;(mg=mgli.current());++mgli)
-            {
-              mg->writeTagFile(tagFile);
-            }
+            mg->writeTagFile(tagFile);
           }
         }
         break;
@@ -2810,9 +2759,7 @@ void ClassDefImpl::writeMemberPages(OutputList &ol) const
   ol.pushGeneratorState();
   ol.disableAllBut(OutputGenerator::Html);
 
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : m_impl->memberLists)
   {
     if (ml->numDocMembers()>ml->numDocEnumValues() && (ml->listType()&MemberListType_detailedLists))
     {
@@ -3170,35 +3117,15 @@ void ClassDefImpl::writeMemberList(OutputList &ol) const
 }
 
 // add a reference to an example
-bool ClassDefImpl::addExample(const char *anchor,const char *nameStr,
-    const char *file)
+bool ClassDefImpl::addExample(const char *anchor,const char *nameStr, const char *file)
 {
-  if (m_impl->exampleSDict==0)
-  {
-    m_impl->exampleSDict = new ExampleSDict;
-    m_impl->exampleSDict->setAutoDelete(TRUE);
-  }
-  if (!m_impl->exampleSDict->find(nameStr))
-  {
-    Example *e=new Example;
-    e->anchor=anchor;
-    e->name=nameStr;
-    e->file=file;
-    m_impl->exampleSDict->inSort(nameStr,e);
-    return TRUE;
-  }
-  return FALSE;
+  return m_impl->examples.inSort(Example(anchor,nameStr,file));
 }
 
 // returns TRUE if this class is used in an example
 bool ClassDefImpl::hasExamples() const
 {
-  bool result=FALSE;
-  if (m_impl->exampleSDict)
-  {
-     result = m_impl->exampleSDict->count()>0;
-  }
-  return result;
+  return !m_impl->examples.empty();
 }
 
 void ClassDefImpl::addTypeConstraint(const QCString &typeConstraint,const QCString &type)
@@ -3218,11 +3145,13 @@ void ClassDefImpl::addTypeConstraint(const QCString &typeConstraint,const QCStri
                  getDefColumn(),
                  typeConstraint,
                  ClassDef::Class))));
-
-    cd->setUsedOnly(TRUE);
-    cd->setLanguage(getLanguage());
-    //printf("Adding undocumented constraint '%s' to class %s on type %s\n",
-    //       typeConstraint.data(),name().data(),type.data());
+    if (cd)
+    {
+      cd->setUsedOnly(TRUE);
+      cd->setLanguage(getLanguage());
+      //printf("Adding undocumented constraint '%s' to class %s on type %s\n",
+      //       typeConstraint.data(),name().data(),type.data());
+    }
   }
   if (cd)
   {
@@ -3340,15 +3269,10 @@ void ClassDefImpl::writeDeclaration(OutputList &ol,const MemberDef *md,bool inGr
   ol.endMemberItem();
 
   // write user defined member groups
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->setInGroup(inGroup);
-      mg->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
-    }
+    mg->setInGroup(inGroup);
+    mg->writePlainDeclarations(ol,this,0,0,0,inheritedFrom,inheritId);
   }
 
   QListIterator<LayoutDocEntry> eli(
@@ -3939,15 +3863,15 @@ QCString ClassDefImpl::getOutputFileBase() const
   if (!Doxygen::generatingXmlOutput)
   {
     Definition *scope=0;
-    if (inlineGroupedClasses && partOfGroups()!=0)
+    if (inlineGroupedClasses && !partOfGroups().empty())
     {
       // point to the group that embeds this class
-      return partOfGroups()->at(0)->getOutputFileBase();
+      return partOfGroups().front()->getOutputFileBase();
     }
-    else if (inlineSimpleClasses && m_impl->isSimple && partOfGroups()!=0)
+    else if (inlineSimpleClasses && m_impl->isSimple && !partOfGroups().empty())
     {
       // point to simple struct inside a group
-      return partOfGroups()->at(0)->getOutputFileBase();
+      return partOfGroups().front()->getOutputFileBase();
     }
     else if (inlineSimpleClasses && m_impl->isSimple && (scope=getOuterScope()))
     {
@@ -4035,17 +3959,22 @@ ClassDef *ClassDefImpl::insertTemplateInstance(const QCString &fileName,
     QCString tcname = removeRedundantWhiteSpace(localName()+templSpec);
     Debug::print(Debug::Classes,0,"      New template instance class '%s''%s' inside '%s' hidden=%d\n",qPrint(name()),qPrint(templSpec),qPrint(name()),isHidden());
 
-    templateClass = toClassDefMutable(Doxygen::classLinkedMap->find(tcname));
-    if (templateClass==0)
+    ClassDef *foundCd = Doxygen::classLinkedMap->find(tcname);
+    if (foundCd)
+    {
+      return foundCd;
+    }
+    templateClass =
+      toClassDefMutable(
+          Doxygen::classLinkedMap->add(tcname,
+            std::unique_ptr<ClassDef>(
+              new ClassDefImpl(fileName,startLine,startColumn,tcname,ClassDef::Class))));
+    if (templateClass)
     {
-      templateClass =
-        toClassDefMutable(
-            Doxygen::classLinkedMap->add(tcname,
-              std::unique_ptr<ClassDef>(
-                new ClassDefImpl(fileName,startLine,startColumn,tcname,ClassDef::Class))));
       templateClass->setTemplateMaster(this);
       templateClass->setOuterScope(getOuterScope());
       templateClass->setHidden(isHidden());
+      templateClass->setArtificial(isArtificial());
       m_impl->templateInstances->insert(templSpec,templateClass);
 
       // also add nested classes
@@ -4057,11 +3986,15 @@ ClassDef *ClassDefImpl::insertTemplateInstance(const QCString &fileName,
               Doxygen::classLinkedMap->add(innerName,
                 std::unique_ptr<ClassDef>(
                   new ClassDefImpl(fileName,startLine,startColumn,innerName,ClassDef::Class))));
-        templateClass->addInnerCompound(innerClass);
-        innerClass->setOuterScope(templateClass);
-        innerClass->setHidden(isHidden());
+        if (innerClass)
+        {
+          templateClass->addInnerCompound(innerClass);
+          innerClass->setOuterScope(templateClass);
+          innerClass->setHidden(isHidden());
+          innerClass->setArtificial(TRUE);
+          freshInstance=TRUE;
+        }
       }
-      freshInstance=TRUE;
     }
   }
   return templateClass;
@@ -4232,18 +4165,11 @@ void ClassDefImpl::addListReferences()
              this
             );
   }
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->addListReferences(this);
-    }
+    mg->addListReferences(this);
   }
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     if (ml->listType()&MemberListType_detailedLists)
     {
@@ -4282,33 +4208,13 @@ bool ClassDefImpl::isAccessibleMember(const MemberDef *md) const
   return md->getClassDef() && isBaseClass(md->getClassDef(),TRUE);
 }
 
-MemberList *ClassDefImpl::createMemberList(MemberListType lt)
-{
-  m_impl->memberLists.setAutoDelete(TRUE);
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
-  {
-    if (ml->listType()==lt)
-    {
-      return ml;
-    }
-  }
-  // not found, create a new member list
-  ml = new MemberList(lt);
-  m_impl->memberLists.append(ml);
-  return ml;
-}
-
 MemberList *ClassDefImpl::getMemberList(MemberListType lt) const
 {
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     if (ml->listType()==lt)
     {
-      return ml;
+      return ml.get();
     }
   }
   return 0;
@@ -4318,7 +4224,7 @@ void ClassDefImpl::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief)
 {
   static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
   static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
-  MemberList *ml = createMemberList(lt);
+  const auto &ml = m_impl->memberLists.get(lt);
   ml->setNeedsSorting((isBrief && sortBriefDocs) || (!isBrief && sortMemberDocs));
   ml->append(md);
 
@@ -4328,16 +4234,14 @@ void ClassDefImpl::addMemberToList(MemberListType lt,MemberDef *md,bool isBrief)
     MemberDefMutable *mdm = toMemberDefMutable(md);
     if (mdm)
     {
-      mdm->setSectionList(this,ml);
+      mdm->setSectionList(this,ml.get());
     }
   }
 }
 
 void ClassDefImpl::sortMemberLists()
 {
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
   }
@@ -4371,11 +4275,9 @@ int ClassDefImpl::countMemberDeclarations(MemberListType lt,const ClassDef *inhe
       //printf("-> ml2=%d\n",ml2->numDecMembers());
     }
     // also include grouped members that have their own section in the class (see bug 722759)
-    if (inheritedFrom && m_impl->memberGroupSDict)
+    if (inheritedFrom)
     {
-      MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-      MemberGroup *mg;
-      for (;(mg=mgli.current());++mgli)
+      for (const auto &mg : m_impl->memberGroups)
       {
         count+=mg->countGroupedInheritedMembers(lt);
         if (lt2!=1) count+=mg->countGroupedInheritedMembers((MemberListType)lt2);
@@ -4409,14 +4311,9 @@ void ClassDefImpl::setAnonymousEnumType()
     }
     else if (lde->kind()==LayoutDocEntry::MemberGroups)
     {
-      if (m_impl->memberGroupSDict)
+      for (const auto &mg : m_impl->memberGroups)
       {
-        MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-        MemberGroup *mg;
-        for (;(mg=mgli.current());++mgli)
-        {
-          mg->setAnonymousEnumType();
-        }
+        mg->setAnonymousEnumType();
       }
     }
   }
@@ -4424,22 +4321,15 @@ void ClassDefImpl::setAnonymousEnumType()
 
 void ClassDefImpl::countMembers()
 {
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     ml->countDecMembers();
     ml->countDocMembers();
   }
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->countDecMembers();
-      mg->countDocMembers();
-    }
+    mg->countDecMembers();
+    mg->countDocMembers();
   }
 }
 
@@ -4557,18 +4447,13 @@ int ClassDefImpl::countMembersIncludingGrouped(MemberListType lt,
     count=ml->countInheritableMembers(inheritedFrom);
   }
   //printf("%s:countMembersIncludingGrouped: count=%d\n",name().data(),count);
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    bool hasOwnSection = !mg->allMembersInSameSection() ||
+                         !m_impl->subGrouping; // group is in its own section
+    if ((additional && hasOwnSection) || (!additional && !hasOwnSection))
     {
-      bool hasOwnSection = !mg->allMembersInSameSection() ||
-                           !m_impl->subGrouping; // group is in its own section
-      if ((additional && hasOwnSection) || (!additional && !hasOwnSection))
-      {
-        count+=mg->countGroupedInheritedMembers(lt);
-      }
+      count+=mg->countGroupedInheritedMembers(lt);
     }
   }
   //printf("%s:countMembersIncludingGrouped(lt=%d,%s)=%d\n",
@@ -4673,16 +4558,11 @@ void ClassDefImpl::addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
                         const ClassDef *inheritedFrom,const QCString &inheritId) const
 {
   //printf("** %s::addGroupedInheritedMembers(%p) inheritId=%s\n",name().data(),m_impl->memberGroupSDict,inheritId.data());
-  if (m_impl->memberGroupSDict)
+  for (const auto &mg : m_impl->memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_impl->memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
     {
-      if (!mg->allMembersInSameSection() || !m_impl->subGrouping) // group is in its own section
-      {
-        mg->addGroupedInheritedMembers(ol,this,lt,inheritedFrom,inheritId);
-      }
+      mg->addGroupedInheritedMembers(ol,this,lt,inheritedFrom,inheritId);
     }
   }
 }
@@ -4879,14 +4759,14 @@ ClassDef *ClassDefImpl::categoryOf() const
   return m_impl->categoryOf;
 }
 
-const QList<MemberList> &ClassDefImpl::getMemberLists() const
+const MemberLists &ClassDefImpl::getMemberLists() const
 {
   return m_impl->memberLists;
 }
 
-MemberGroupSDict *ClassDefImpl::getMemberGroupSDict() const
+const MemberGroupList &ClassDefImpl::getMemberGroups() const
 {
-  return m_impl->memberGroupSDict;
+  return m_impl->memberGroups;
 }
 
 void ClassDefImpl::setNamespace(NamespaceDef *nd)
@@ -4957,9 +4837,7 @@ MemberDef *ClassDefImpl::isSmartPointer() const
 void ClassDefImpl::reclassifyMember(MemberDefMutable *md,MemberType t)
 {
   md->setMemberType(t);
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     ml->remove(md);
   }
@@ -4999,11 +4877,11 @@ bool ClassDefImpl::isEmbeddedInOuterScope() const
        );
 
   // inline because of INLINE_GROUPED_CLASSES=YES ?
-  bool b1 = (inlineGroupedClasses && partOfGroups()!=0); // a grouped class
+  bool b1 = (inlineGroupedClasses && !partOfGroups().empty()); // a grouped class
   // inline because of INLINE_SIMPLE_STRUCTS=YES ?
   bool b2 = (inlineSimpleClasses && m_impl->isSimple && // a simple class
              (containerLinkable || // in a documented container
-              partOfGroups()!=0    // or part of a group
+              !partOfGroups().empty()    // or part of a group
              )
            );
   //printf("%s::isEmbeddedInOuterScope(): inlineGroupedClasses=%d "
@@ -5026,9 +4904,7 @@ void ClassDefImpl::setTagLessReference(const ClassDef *cd)
 
 void ClassDefImpl::removeMemberFromLists(MemberDef *md)
 {
-  QListIterator<MemberList> mli(m_impl->memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_impl->memberLists)
   {
     ml->remove(md);
   }
@@ -5063,9 +4939,9 @@ const ArgumentList &ClassDefImpl::typeConstraints() const
   return m_impl->typeConstraints;
 }
 
-const ExampleSDict *ClassDefImpl::exampleList() const
+const ExampleList &ClassDefImpl::getExamples() const
 {
-  return m_impl->exampleSDict;
+  return m_impl->examples;
 }
 
 bool ClassDefImpl::subGrouping() const
index 217002d..46e1f7d 100644 (file)
 #include "containers.h"
 #include "definition.h"
 #include "arguments.h"
+#include "membergroup.h"
 
 struct Argument;
 class MemberDef;
 class MemberDefMutable;
 class MemberList;
-class MemberDict;
-class ClassList;
+class MemberLists;
 class ClassLinkedRefMap;
 class OutputList;
 class FileDef;
 class FileList;
 class NamespaceDef;
 class MemberDef;
-class ExampleSDict;
+class ExampleList;
 class MemberNameInfoLinkedMap;
 class UsesClassDict;
 class ConstraintClassDict;
-class MemberGroupSDict;
 class QTextStream;
 class PackageDef;
 class GroupDef;
@@ -318,10 +317,10 @@ class ClassDef : public Definition
     virtual MemberList *getMemberList(MemberListType lt) const = 0;
 
     /** Returns the list containing the list of members sorted per type */
-    virtual const QList<MemberList> &getMemberLists() const = 0;
+    virtual const MemberLists &getMemberLists() const = 0;
 
     /** Returns the member groups defined for this class */
-    virtual MemberGroupSDict *getMemberGroupSDict() const = 0;
+    virtual const MemberGroupList &getMemberGroups() const = 0;
 
     virtual QDict<int> *getTemplateBaseClassNames() const = 0;
 
@@ -346,7 +345,7 @@ class ClassDef : public Definition
     virtual const FileList &usedFiles() const = 0;
 
     virtual const ArgumentList &typeConstraints() const = 0;
-    virtual const ExampleSDict *exampleList() const = 0;
+    virtual const ExampleList &getExamples() const = 0;
     virtual bool hasExamples() const = 0;
     virtual QCString getMemberListFileName() const = 0;
     virtual bool subGrouping() const = 0;
index 2998ac4..af64478 100644 (file)
 #include "arguments.h"
 #include "groupdef.h"
 
-ClassList::ClassList() : QList<ClassDef>()
-{
-}
-
-ClassList::~ClassList()
-{
-}
-
-static int compItems(const ClassDef *c1,const ClassDef *c2)
-{
-  static bool b = Config_getBool(SORT_BY_SCOPE_NAME);
-  if (b)
-  {
-     return qstricmp(c1->name(), c2->name());
-  }
-  else
-  {
-     return qstricmp(c1->className(), c2->className());
-  }
-}
-
-int ClassList::compareValues(const ClassDef *item1, const ClassDef *item2) const
-{
-  return compItems(item1,item2);
-}
-
-ClassListIterator::ClassListIterator(const ClassList &cllist) :
-  QListIterator<ClassDef>(cllist)
-{
-}
-
-//-------------------------------------------
-
 bool ClassLinkedRefMap::declVisible(const ClassDef::CompoundType *filter) const
 {
   bool hideUndocClasses = Config_getBool(HIDE_UNDOC_CLASSES);
@@ -116,15 +83,15 @@ void ClassLinkedRefMap::writeDocumentation(OutputList &ol,const Definition * con
 
   for (const auto &cd : *this)
   {
-    //printf("%s:writeDocumentation() %p linkable=%d embedded=%d container=%p partOfGroups=%d\n",
+    //printf("%s:writeDocumentation() %p linkable=%d embedded=%d container=%p partOfGroups=%zu\n",
     //  cd->name().data(),cd->getOuterScope(),cd->isLinkableInProject(),cd->isEmbeddedInOuterScope(),
-    //  container,cd->partOfGroups() ? cd->partOfGroups()->count() : 0);
+    //  container,cd->partOfGroups()->size());
 
     if (!cd->isAnonymous() &&
         cd->isLinkableInProject() &&
         cd->isEmbeddedInOuterScope() &&
         !cd->isAlias() &&
-        (container==0 || cd->partOfGroups()==0) // if container==0 -> show as part of the group docs, otherwise only show if not part of a group
+        (container==0 || cd->partOfGroups().empty()) // if container==0 -> show as part of the group docs, otherwise only show if not part of a group
        )
     {
       //printf("  showing class %s\n",cd->name().data());
@@ -146,52 +113,4 @@ void ClassLinkedRefMap::writeDocumentation(OutputList &ol,const Definition * con
   }
 }
 
-//-------------------------------------------
-
-void GenericsSDict::insert(const QCString &key,ClassDef *cd)
-{
-  int i=key.find('<');
-  if (i==-1) return;
-  auto argList = stringToArgumentList(SrcLangExt_CSharp, key.mid(i));
-  int c = (int)argList->size();
-  if (c==0) return;
-  GenericsCollection *collection = m_dict.find(key.left(i));
-  if (collection==0) // new name
-  {
-    collection = new GenericsCollection;
-    m_dict.append(key.left(i),collection);
-  }
-  if (collection->find(c)==0) // should always be 0!
-  {
-    collection->insert(c,cd);
-  }
-}
-
-ClassDef *GenericsSDict::find(const QCString &key)
-{
-  int i=key.find('<');
-  if (i==-1)
-  {
-    GenericsCollection *collection = m_dict.find(key);
-    if (collection && collection->count()==1)
-    {
-      QIntDictIterator<ClassDef> it(*collection);
-      return it.current();
-    }
-  }
-  else
-  {
-    GenericsCollection *collection = m_dict.find(key.left(i));
-    if (collection)
-    {
-      auto argList = stringToArgumentList(SrcLangExt_CSharp,key.mid(i));
-      int c = (int)argList->size();
-      return collection->find(c);
-    }
-  }
-  return 0;
-}
-
-
-
 
index 9ff53db..709412b 100644 (file)
 #ifndef CLASSLIST_H
 #define CLASSLIST_H
 
-#include <qlist.h>
-#include <qdict.h>
-
 #include "linkedmap.h"
 #include "classdef.h"
-#include "sortdict.h"
 
 class Definition;
 
-/** A list of ClassDef objects. */
-class ClassList : public QList<ClassDef>
-{
-  public:
-    ClassList();
-   ~ClassList();
-
-  private:
-    int compareValues(const ClassDef *item1,const ClassDef *item2) const;
-};
-
-/** An iterator for ClassDef objects in a ClassList. */
-class ClassListIterator : public QListIterator<ClassDef>
-{
-  public:
-    ClassListIterator(const ClassList &list);
-};
-
-class GenericsCollection : public QIntDict<ClassDef>
-{
-  public:
-    GenericsCollection() : QIntDict<ClassDef>(17) {}
-   ~GenericsCollection() {}
-};
-
-class GenericsSDict
-{
-  public:
-   GenericsSDict() : m_dict(17) { m_dict.setAutoDelete(TRUE); }
-  ~GenericsSDict() {}
-   void insert(const QCString &key,ClassDef *cd);
-   ClassDef *find(const QCString &key);
-  private:
-   SDict<GenericsCollection> m_dict;
-};
-
 class ClassLinkedMap : public LinkedMap<ClassDef>
 {
 };
@@ -75,6 +35,4 @@ class ClassLinkedRefMap : public LinkedRefMap<const ClassDef>
     void writeDocumentation(OutputList &ol,const Definition * container=0) const;
 };
 
-
-
 #endif
index 94a7bcd..6feda35 100644 (file)
@@ -121,7 +121,7 @@ struct codeYY_state
   FileDef *     sourceFileDef = 0;
   bool          lineNumbers = FALSE;
   const Definition *  currentDefinition = 0;
-  MemberDef *   currentMemberDef = 0;
+  const MemberDef *   currentMemberDef = 0;
   bool          includeCodeFragment = FALSE;
   const char *  currentFontClass = 0;
   bool          searchingForBody = FALSE;
@@ -224,7 +224,7 @@ static bool getLink(yyscan_t yyscanner,const char *className,
                     bool varOnly=FALSE);
 static void generateClassOrGlobalLink(yyscan_t yyscanner,CodeOutputInterface &ol,const char *clName,
                                       bool typeOnly=FALSE,bool varOnly=FALSE);
-static bool generateClassMemberLink(yyscan_t yyscanner,CodeOutputInterface &ol,MemberDef *xmd,const char *memName);
+static bool generateClassMemberLink(yyscan_t yyscanner,CodeOutputInterface &ol,const MemberDef *xmd,const char *memName);
 static bool generateClassMemberLink(yyscan_t yyscanner,CodeOutputInterface &ol,const Definition *def,const char *memName);
 static void generateMemberLink(yyscan_t yyscanner,CodeOutputInterface &ol,const QCString &varName,
             const char *memName);
@@ -537,7 +537,6 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
                                         }
 <SkipCPP>"//"/[^/!]                     {
                                           REJECT;
-                                          yyextra->code->codify(yytext);
                                         }
 <Body,FuncCall>"{"                      {
                                           yyextra->theVarContext.pushScope();
@@ -2344,7 +2343,7 @@ static void startCodeLine(yyscan_t yyscanner)
     //lineNumber.sprintf("%05d",yyextra->yyLineNr);
     //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
 
-    Definition *d   = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
+    const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
     //printf("%s:startCodeLine(%d)=%p\n",yyextra->sourceFileDef->name().data(),yyextra->yyLineNr,d);
     if (!yyextra->includeCodeFragment && d)
     {
@@ -2613,7 +2612,7 @@ static const MemberDef *setCallContextForVar(yyscan_t yyscanner,const QCString &
       const NamespaceDef *mnd = getResolvedNamespace(scope);
       if (mnd && !locName.isEmpty())
       {
-        MemberDef *md=mnd->getMemberByName(locName);
+        const MemberDef *md=mnd->getMemberByName(locName);
         if (md)
         {
           //printf("name=%s scope=%s\n",locName.data(),scope.data());
@@ -2981,7 +2980,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
 
 static bool generateClassMemberLink(yyscan_t yyscanner,
                                     CodeOutputInterface &ol,
-                                    MemberDef *xmd,
+                                    const MemberDef *xmd,
                                     const char *memName)
 {
   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
@@ -3050,7 +3049,7 @@ static bool generateClassMemberLink(yyscan_t yyscanner,
   if (def && def->definitionType()==Definition::TypeClass)
   {
     const ClassDef *cd = toClassDef(def);
-    MemberDef *xmd = cd->getMemberByName(memName);
+    const MemberDef *xmd = cd->getMemberByName(memName);
     //printf("generateClassMemberLink(class=%s,member=%s)=%p\n",def->name().data(),memName,xmd);
     if (xmd)
     {
index 036f830..b5f8e41 100644 (file)
@@ -348,6 +348,16 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
                                        yyextra->commentStack.push(new CommentCtx(yyextra->lineNr));
                                     }
                                   }
+<Scan>"--"[^!][^\n]*              {
+                                     if (yyextra->lang!=SrcLangExt_VHDL)
+                                    {
+                                      REJECT;
+                                    }
+                                    else
+                                    {
+                                       copyToOutput(yyscanner,yytext,(int)yyleng); 
+                                    }
+                                  }
 <Scan>"--!"                       {
                                      if (yyextra->lang!=SrcLangExt_VHDL)
                                     {
@@ -541,7 +551,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
                                    }
 <SkipString>\\.                    { /* escaped character in string */
-                                     if (yyextra->lang==SrcLangExt_Fortran)
+                                     if (yyextra->lang==SrcLangExt_Fortran || yyextra->lang==SrcLangExt_VHDL)
                                      {
                                        unput(yytext[1]);
                                        copyToOutput(yyscanner,yytext,1);
@@ -562,7 +572,7 @@ NUMBER {INTEGER_NUMBER}|{FLOAT_NUMBER}
                                      copyToOutput(yyscanner,yytext,(int)yyleng); 
                                    }
 <SkipChar>\\.                     { /* escaped character */
-                                     if (yyextra->lang==SrcLangExt_Fortran)
+                                     if (yyextra->lang==SrcLangExt_Fortran || yyextra->lang==SrcLangExt_VHDL)
                                      {
                                        unput(yytext[1]);
                                        copyToOutput(yyscanner,yytext,1);
index 3f0d406..c0b846a 100644 (file)
@@ -982,14 +982,14 @@ Go to the <a href="commands.html">next</a> section or return to the
       <docs>
 <![CDATA[
  With the correct setting of option \c CASE_SENSE_NAMES doxygen will better be able to match the
- capabilities of the underlying filesystem. 
+ capabilities of the underlying filesystem.
 
- In case the filesystem is case sensitive (i.e. it supports files in the same directory 
+ In case the filesystem is case sensitive (i.e. it supports files in the same directory
  whose names only differ in casing), the option must be set to \c YES to properly deal with such files
- in case they appear in the input. 
- For filesystems that are not case sensitive the option should be be set to \c NO to properly 
- deal with output files written for symbols that only differ in casing, such as for two classes, 
+ in case they appear in the input.
+
+ For filesystems that are not case sensitive the option should be be set to \c NO to properly
+ deal with output files written for symbols that only differ in casing, such as for two classes,
  one named \c CLASS and the other named \c Class, and to also support references to files without
  having to specify the exact matching casing.
 
@@ -1740,6 +1740,15 @@ to disable this feature.
 ]]>
       </docs>
     </option>
+    <option type='bool' id='CLANG_ADD_INC_PATHS' setting='USE_LIBCLANG' defval='1'>
+      <docs>
+<![CDATA[
+  If clang assisted parsing is enabled and the \c CLANG_ADD_INC_PATHS tag
+  is set to \c YES then doxygen will add the directory of each input to the
+  include path.
+]]>
+      </docs>
+    </option>
     <option type='list' id='CLANG_OPTIONS' format='string' setting='USE_LIBCLANG' depends='CLANG_ASSISTED_PARSING'>
       <docs>
 <![CDATA[
@@ -2429,7 +2438,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
     <option type='string' id='FORMULA_MACROFILE' format='file' defval=''>
       <docs>
 <![CDATA[
- The \c FORMULA_MACROFILE can contain \f$\mbox{\LaTeX}\f$ `\newcommand` and 
+ The \c FORMULA_MACROFILE can contain \f$\mbox{\LaTeX}\f$ `\newcommand` and
  `\renewcommand` commands to create new \f$\mbox{\LaTeX}\f$ commands to be used
  in formulas as building blocks.
  See the section \ref formulas for details.
@@ -2863,7 +2872,7 @@ or
     <option type='string' id='LATEX_EMOJI_DIRECTORY' format='dir' defval='' depends='GENERATE_LATEX'>
       <docs>
 <![CDATA[
- The \c LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) 
+ The \c LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
  path from which the emoji images will be read.
  If a relative path is entered, it will be relative to the \ref cfg_latex_output "LATEX_OUTPUT"
  directory. If left blank the \ref cfg_latex_output "LATEX_OUTPUT" directory will be used.
index e2ef8eb..7f73ec0 100644 (file)
@@ -153,7 +153,7 @@ void ConfigOption::writeStringValue(FTextStream &t,const QCString &s)
   {
     t << " ";
     while ((c=*p++)!=0 && !needsEscaping)
-      needsEscaping = (c==' ' || c=='\n' || c=='\t' || c=='"' || c=='#');
+      needsEscaping = (c==' ' || c== ',' || c=='\n' || c=='\t' || c=='"' || c=='#');
     if (needsEscaping)
     {
       t << "\"";
@@ -873,7 +873,7 @@ static void readIncludeFile(const char *incName)
                                            g_config->appendUserComment(yytext);
                                            g_yyLineNr++;
                                          }
-<Start>"#"[^#].*"\n"                     { /* normal comment */
+<Start>"#".*"\n"                         { /* normal comment */
                                            g_yyLineNr++;
                                          }
 
index b7a547f..7f3a33e 100644 (file)
@@ -2339,7 +2339,7 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
           if (!cd->isAnonymous() &&
               cd->isLinkableInProject() &&
               cd->isEmbeddedInOuterScope() &&
-              cd->partOfGroups()==0
+              cd->partOfGroups().empty()
              )
           {
             classList->append(ClassContext::alloc(cd));
@@ -2376,15 +2376,13 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
     {
       if (m_classDef->hasExamples())
       {
-        ExampleSDict::Iterator it(*m_classDef->exampleList());
-        Example *ex;
-        for (it.toFirst();(ex=it.current());++it)
+        for (const auto &ex : m_classDef->getExamples())
         {
           TemplateStruct *s = TemplateStruct::alloc();
-          s->set("text",ex->name);
+          s->set("text",ex.name);
           s->set("isLinkable",TRUE);
-          s->set("anchor",ex->anchor);
-          s->set("fileName",ex->file);
+          s->set("anchor",ex.anchor);
+          s->set("fileName",ex.file);
           s->set("isReference",FALSE);
           s->set("externalReference","");
           list->append(s);
@@ -2500,9 +2498,9 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
       Cachable &cache = getCache();
       if (!cache.memberGroups)
       {
-        if (m_classDef->getMemberGroupSDict())
+        if (!m_classDef->getMemberGroups().empty())
         {
-          cache.memberGroups.reset(MemberGroupListContext::alloc(m_classDef,relPathAsString(),m_classDef->getMemberGroupSDict(),m_classDef->subGrouping()));
+          cache.memberGroups.reset(MemberGroupListContext::alloc(m_classDef,relPathAsString(),m_classDef->getMemberGroups(),m_classDef->subGrouping()));
         }
         else
         {
@@ -2848,9 +2846,9 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri
       Cachable &cache = getCache();
       if (!cache.memberGroups)
       {
-        if (m_namespaceDef->getMemberGroupSDict())
+        if (!m_namespaceDef->getMemberGroups().empty())
         {
-          cache.memberGroups.reset(MemberGroupListContext::alloc(m_namespaceDef,relPathAsString(),m_namespaceDef->getMemberGroupSDict(),m_namespaceDef->subGrouping()));
+          cache.memberGroups.reset(MemberGroupListContext::alloc(m_namespaceDef,relPathAsString(),m_namespaceDef->getMemberGroups(),m_namespaceDef->subGrouping()));
         }
         else
         {
@@ -2900,7 +2898,7 @@ class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Pri
           if (!cd->isAnonymous() &&
               cd->isLinkableInProject() &&
               cd->isEmbeddedInOuterScope() &&
-              cd->partOfGroups()==0)
+              cd->partOfGroups().empty())
           {
             classList->append(ClassContext::alloc(cd));
           }
@@ -3291,9 +3289,9 @@ class FileContext::Private : public DefinitionContext<FileContext::Private>
       Cachable &cache = getCache();
       if (!cache.memberGroups)
       {
-        if (m_fileDef->getMemberGroupSDict())
+        if (!m_fileDef->getMemberGroups().empty())
         {
-          cache.memberGroups.reset(MemberGroupListContext::alloc(m_fileDef,relPathAsString(),m_fileDef->getMemberGroupSDict(),m_fileDef->subGrouping()));
+          cache.memberGroups.reset(MemberGroupListContext::alloc(m_fileDef,relPathAsString(),m_fileDef->getMemberGroups(),m_fileDef->subGrouping()));
         }
         else
         {
@@ -3344,7 +3342,7 @@ class FileContext::Private : public DefinitionContext<FileContext::Private>
           if (!cd->isAnonymous() &&
               cd->isLinkableInProject() &&
               cd->isEmbeddedInOuterScope() &&
-              cd->partOfGroups()==0)
+              cd->partOfGroups().empty())
           {
             classList->append(ClassContext::alloc(cd));
           }
@@ -4064,7 +4062,7 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
         s_inst.addProperty("nameWithContextFor",  &Private::nameWithContextFor);
         init=TRUE;
       }
-      if (!md->cookie()) { md->setCookie(new MemberContext::Private::Cachable(md)); }
+      if (md && !md->cookie()) { md->setCookie(new MemberContext::Private::Cachable(md)); }
 
       Cachable &cache = getCache();
       cache.propertyAttrs.reset(TemplateList::alloc());
@@ -4845,15 +4843,13 @@ class MemberContext::Private : public DefinitionContext<MemberContext::Private>
     {
       if (m_memberDef->hasExamples())
       {
-        ExampleSDict::Iterator it(*m_memberDef->getExamples());
-        Example *ex;
-        for (it.toFirst();(ex=it.current());++it)
+        for (const auto &ex : m_memberDef->getExamples())
         {
           TemplateStruct *s = TemplateStruct::alloc();
-          s->set("text",ex->name);
+          s->set("text",ex.name);
           s->set("isLinkable",TRUE);
-          s->set("anchor",ex->anchor);
-          s->set("fileName",ex->file);
+          s->set("anchor",ex.anchor);
+          s->set("fileName",ex.file);
           s->set("isReference",FALSE);
           s->set("externalReference","");
           list->append(s);
@@ -5366,16 +5362,11 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
       if (!cache.modules)
       {
         TemplateList *moduleList = TemplateList::alloc();
-        if (m_groupDef->getSubGroups())
+        for (const auto &gd : m_groupDef->getSubGroups())
         {
-          GroupListIterator gli(*m_groupDef->getSubGroups());
-          const GroupDef *gd;
-          for (gli.toFirst();(gd=gli.current());++gli)
+          if (gd->isVisible())
           {
-            if (gd->isVisible())
-            {
-              moduleList->append(ModuleContext::alloc(gd));
-            }
+            moduleList->append(ModuleContext::alloc(gd));
           }
         }
         cache.modules.reset(moduleList);
@@ -5388,14 +5379,9 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
       if (!cache.examples)
       {
         TemplateList *exampleList = TemplateList::alloc();
-        if (m_groupDef->getExamples())
+        for (const auto &ex : m_groupDef->getExamples())
         {
-          PageSDict::Iterator eli(*m_groupDef->getExamples());
-          const PageDef *ex;
-          for (eli.toFirst();(ex=eli.current());++eli)
-          {
-            exampleList->append(PageContext::alloc(ex,FALSE,TRUE));
-          }
+          exampleList->append(PageContext::alloc(ex,FALSE,TRUE));
         }
         cache.examples.reset(exampleList);
       }
@@ -5407,14 +5393,9 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
       if (!cache.pages)
       {
         TemplateList *pageList = TemplateList::alloc();
-        if (m_groupDef->getExamples())
+        for (const auto &ex : m_groupDef->getPages())
         {
-          PageSDict::Iterator eli(*m_groupDef->getPages());
-          const PageDef *ex;
-          for (eli.toFirst();(ex=eli.current());++eli)
-          {
-            pageList->append(PageContext::alloc(ex,FALSE,TRUE));
-          }
+          pageList->append(PageContext::alloc(ex,FALSE,TRUE));
         }
         cache.pages.reset(pageList);
       }
@@ -5588,9 +5569,9 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
       Cachable &cache = getCache();
       if (!cache.memberGroups)
       {
-        if (m_groupDef->getMemberGroupSDict())
+        if (!m_groupDef->getMemberGroups().empty())
         {
-          cache.memberGroups.reset(MemberGroupListContext::alloc(m_groupDef,relPathAsString(),m_groupDef->getMemberGroupSDict(),m_groupDef->subGrouping()));
+          cache.memberGroups.reset(MemberGroupListContext::alloc(m_groupDef,relPathAsString(),m_groupDef->getMemberGroups(),m_groupDef->subGrouping()));
         }
         else
         {
@@ -5665,7 +5646,7 @@ class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
           if (!cd->isAnonymous() &&
               cd->isLinkableInProject() &&
               cd->isEmbeddedInOuterScope() &&
-              cd->partOfGroups()==0)
+              cd->partOfGroups().empty())
           {
             classList->append(ClassContext::alloc(cd));
           }
@@ -6397,17 +6378,17 @@ class NestingNodeContext::Private
     void addPages(ClassDefSet &visitedClasses)
     {
       const PageDef *pd = toPageDef(m_def);
-      if (pd && pd->getSubPages())
+      if (pd && !pd->getSubPages().empty())
       {
-        m_children->addPages(*pd->getSubPages(),FALSE,visitedClasses);
+        m_children->addPages(pd->getSubPages(),FALSE,visitedClasses);
       }
     }
     void addModules(ClassDefSet &visitedClasses)
     {
       const GroupDef *gd = toGroupDef(m_def);
-      if (gd && gd->getSubGroups())
+      if (gd && !gd->getSubGroups().empty())
       {
-        m_children->addModules(*gd->getSubGroups(),visitedClasses);
+        m_children->addModules(gd->getSubGroups(),visitedClasses);
       }
     }
   private:
@@ -6532,15 +6513,13 @@ class NestingContext::Private : public GenericNodeListContext
         addClass(cd.get(),rootOnly,visitedClasses);
       }
     }
-    void addDirs(const DirSDict &dirDict,ClassDefSet &visitedClasses)
+    void addDirs(const DirLinkedMap &dirLinkedMap,ClassDefSet &visitedClasses)
     {
-      SDict<DirDef>::Iterator dli(dirDict);
-      const DirDef *dd;
-      for (dli.toFirst();(dd=dli.current());++dli)
+      for (const auto &dd : dirLinkedMap)
       {
         if (dd->getOuterScope()==Doxygen::globalScope)
         {
-          append(NestingNodeContext::alloc(m_parent,dd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
+          append(NestingNodeContext::alloc(m_parent,dd.get(),m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
           m_index++;
         }
       }
@@ -6577,42 +6556,47 @@ class NestingContext::Private : public GenericNodeListContext
         m_index++;
       }
     }
-    void addPages(const PageSDict &pages,bool rootOnly,ClassDefSet &visitedClasses)
+    void addPage(const PageDef *pd,bool rootOnly,ClassDefSet &visitedClasses)
     {
-      SDict<PageDef>::Iterator pli(pages);
-      const PageDef *pd;
-      for (pli.toFirst();(pd=pli.current());++pli)
+      if (!rootOnly ||
+          pd->getOuterScope()==0 ||
+          pd->getOuterScope()->definitionType()!=Definition::TypePage)
       {
-        if (!rootOnly ||
-            pd->getOuterScope()==0 ||
-            pd->getOuterScope()->definitionType()!=Definition::TypePage)
-        {
-          append(NestingNodeContext::alloc(m_parent,pd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
-          m_index++;
-        }
+        append(NestingNodeContext::alloc(m_parent,pd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
+        m_index++;
+      }
+    }
+    void addPages(const PageLinkedMap &pages,bool rootOnly,ClassDefSet &visitedClasses)
+    {
+      for (const auto &pd : pages)
+      {
+        addPage(pd.get(),rootOnly,visitedClasses);
       }
     }
-    void addModules(const GroupSDict &groups,ClassDefSet &visitedClasses)
+    void addPages(const PageLinkedRefMap &pages,bool rootOnly,ClassDefSet &visitedClasses)
     {
-      GroupSDict::Iterator gli(groups);
-      const GroupDef *gd;
-      for (gli.toFirst();(gd=gli.current());++gli)
+      for (const auto &pd : pages)
       {
-        static bool externalGroups = Config_getBool(EXTERNAL_GROUPS);
+        addPage(pd,rootOnly,visitedClasses);
+      }
+    }
+    void addModules(const GroupLinkedMap &groups,ClassDefSet &visitedClasses)
+    {
+      for (const auto &gd : groups)
+      {
+        bool externalGroups = Config_getBool(EXTERNAL_GROUPS);
         if (!gd->isASubGroup() && gd->isVisible() &&
-             (!gd->isReference() || externalGroups)
+            (!gd->isReference() || externalGroups)
            )
         {
-          append(NestingNodeContext::alloc(m_parent,gd,m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
+          append(NestingNodeContext::alloc(m_parent,gd.get(),m_index,m_level,FALSE,FALSE,FALSE,visitedClasses));
           m_index++;
         }
       }
     }
-    void addModules(const GroupList &list,ClassDefSet &visitedClasses)
+    void addModules(const GroupList &groups,ClassDefSet &visitedClasses)
     {
-      GroupListIterator gli(list);
-      const GroupDef *gd;
-      for (gli.toFirst();(gd=gli.current());++gli)
+      for (const auto &gd : groups)
       {
         if (gd->isVisible())
         {
@@ -6731,7 +6715,7 @@ void NestingContext::addNamespaces(const NamespaceLinkedRefMap &nsLinkedRefMap,b
   p->addNamespaces(nsLinkedRefMap,rootOnly,addClasses,visitedClasses);
 }
 
-void NestingContext::addDirs(const DirSDict &dirs,ClassDefSet &visitedClasses)
+void NestingContext::addDirs(const DirLinkedMap &dirs,ClassDefSet &visitedClasses)
 {
   p->addDirs(dirs,visitedClasses);
 }
@@ -6751,12 +6735,17 @@ void NestingContext::addFiles(const FileList &files,ClassDefSet &visitedClasses)
   p->addFiles(files,visitedClasses);
 }
 
-void NestingContext::addPages(const PageSDict &pages,bool rootOnly,ClassDefSet &visitedClasses)
+void NestingContext::addPages(const PageLinkedMap &pages,bool rootOnly,ClassDefSet &visitedClasses)
 {
   p->addPages(pages,rootOnly,visitedClasses);
 }
 
-void NestingContext::addModules(const GroupSDict &modules,ClassDefSet &visitedClasses)
+void NestingContext::addPages(const PageLinkedRefMap &pages,bool rootOnly,ClassDefSet &visitedClasses)
+{
+  p->addPages(pages,rootOnly,visitedClasses);
+}
+
+void NestingContext::addModules(const GroupLinkedMap &modules,ClassDefSet &visitedClasses)
 {
   p->addModules(modules,visitedClasses);
 }
@@ -7122,11 +7111,9 @@ class DirListContext::Private : public GenericNodeListContext
   public:
     Private()
     {
-      const DirDef *dir;
-      DirSDict::Iterator sdi(*Doxygen::directories);
-      for (sdi.toFirst();(dir=sdi.current());++sdi)
+      for (const auto &dir : *Doxygen::dirLinkedMap)
       {
-        append(DirContext::alloc(dir));
+        append(DirContext::alloc(dir.get()));
       }
     }
 };
@@ -7222,10 +7209,7 @@ class FileTreeContext::Private
       // Add dirs tree
       m_dirFileTree.reset(NestingContext::alloc(0,0));
       ClassDefSet visitedClasses;
-      if (Doxygen::directories)
-      {
-        m_dirFileTree->addDirs(*Doxygen::directories,visitedClasses);
-      }
+      m_dirFileTree->addDirs(*Doxygen::dirLinkedMap,visitedClasses);
       if (Doxygen::inputNameLinkedMap)
       {
         m_dirFileTree->addFiles(*Doxygen::inputNameLinkedMap,visitedClasses);
@@ -7331,15 +7315,12 @@ TemplateVariant FileTreeContext::get(const char *name) const
 class PageTreeContext::Private
 {
   public:
-    Private(const PageSDict *pages)
+    Private(const PageLinkedMap &pages)
     {
       m_pageTree.reset(NestingContext::alloc(0,0));
       ClassDefSet visitedClasses;
       // Add pages
-      if (pages)
-      {
-        m_pageTree->addPages(*pages,TRUE,visitedClasses);
-      }
+      m_pageTree->addPages(pages,TRUE,visitedClasses);
 
       //%% PageNodeList tree:
       static bool init=FALSE;
@@ -7420,7 +7401,7 @@ class PageTreeContext::Private
 
 PropertyMapper<PageTreeContext::Private> PageTreeContext::Private::s_inst;
 
-PageTreeContext::PageTreeContext(const PageSDict *pages) : RefCountedContext("PageTreeContext")
+PageTreeContext::PageTreeContext(const PageLinkedMap &pages) : RefCountedContext("PageTreeContext")
 {
   p = new Private(pages);
 }
@@ -7441,24 +7422,22 @@ TemplateVariant PageTreeContext::get(const char *name) const
 class PageListContext::Private : public GenericNodeListContext
 {
   public:
-    void addPages(const PageSDict &pages)
+    void addPages(const PageLinkedMap &pages)
     {
-      PageSDict::Iterator pdi(pages);
-      const PageDef *pd=0;
-      for (pdi.toFirst();(pd=pdi.current());++pdi)
+      for (const auto &pd : pages)
       {
         if (!pd->getGroupDef() && !pd->isReference())
         {
-          append(PageContext::alloc(pd,FALSE,FALSE));
+          append(PageContext::alloc(pd.get(),FALSE,FALSE));
         }
       }
     }
 };
 
-PageListContext::PageListContext(const PageSDict *pages) : RefCountedContext("PageListContext")
+PageListContext::PageListContext(const PageLinkedMap &pages) : RefCountedContext("PageListContext")
 {
   p = new Private;
-  if (pages) p->addPages(*pages);
+  p->addPages(pages);
 }
 
 PageListContext::~PageListContext()
@@ -7490,16 +7469,11 @@ class ExampleListContext::Private : public GenericNodeListContext
   public:
     Private()
     {
-      if (Doxygen::exampleSDict)
+      for (const auto &pd : *Doxygen::exampleLinkedMap)
       {
-        PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-        const PageDef *pd=0;
-        for (pdi.toFirst();(pd=pdi.current());++pdi)
+        if (!pd->getGroupDef() && !pd->isReference())
         {
-          if (!pd->getGroupDef() && !pd->isReference())
-          {
-            append(PageContext::alloc(pd,FALSE,TRUE));
-          }
+          append(PageContext::alloc(pd.get(),FALSE,TRUE));
         }
       }
     }
@@ -7539,13 +7513,11 @@ class ModuleListContext::Private : public GenericNodeListContext
   public:
     void addModules()
     {
-      GroupSDict::Iterator gli(*Doxygen::groupSDict);
-      const GroupDef *gd;
-      for (gli.toFirst();(gd=gli.current());++gli)
+      for (const auto &gd : *Doxygen::groupLinkedMap)
       {
         if (!gd->isReference())
         {
-          append(ModuleContext::alloc(gd));
+          append(ModuleContext::alloc(gd.get()));
         }
       }
     }
@@ -7590,10 +7562,7 @@ class ModuleTreeContext::Private
       m_moduleTree.reset(NestingContext::alloc(0,0));
       ClassDefSet visitedClasses;
       // Add modules
-      if (Doxygen::groupSDict)
-      {
-        m_moduleTree->addModules(*Doxygen::groupSDict,visitedClasses);
-      }
+      m_moduleTree->addModules(*Doxygen::groupLinkedMap,visitedClasses);
 
       //%% ModuleList tree:
       static bool init=FALSE;
@@ -7796,10 +7765,7 @@ class ExampleTreeContext::Private
       m_exampleTree.reset(NestingContext::alloc(0,0));
       ClassDefSet visitedClasses;
       // Add pages
-      if (Doxygen::exampleSDict)
-      {
-        m_exampleTree->addPages(*Doxygen::exampleSDict,TRUE,visitedClasses);
-      }
+      m_exampleTree->addPages(*Doxygen::exampleLinkedMap,TRUE,visitedClasses);
 
       static bool init=FALSE;
       if (!init)
@@ -8566,24 +8532,6 @@ MemberListContext::MemberListContext(const MemberList *list) : RefCountedContext
   }
 }
 
-MemberListContext::MemberListContext(MemberSDict *list,bool doSort) : RefCountedContext("MemberListContext")
-{
-  p = new Private;
-  if (list)
-  {
-    if (doSort)
-    {
-      list->sort();
-    }
-    MemberSDict::Iterator it(*list);
-    MemberDef *md;
-    for (it.toFirst();(md=it.current());++it)
-    {
-      p->addMember(md);
-    }
-  }
-}
-
 MemberListContext::MemberListContext(std::vector<const MemberDef *> &&ml) : RefCountedContext("MemberListContext")
 {
   p = new Private;
@@ -8818,7 +8766,7 @@ class MemberGroupInfoContext::Private
     {
       if (!m_cache.memberGroups)
       {
-        m_cache.memberGroups.reset(MemberGroupListContext::alloc(m_def,m_relPath,0));
+        m_cache.memberGroups.reset(MemberGroupListContext::alloc());
       }
       return m_cache.memberGroups.get();
     }
@@ -8895,33 +8843,23 @@ MemberGroupListContext::MemberGroupListContext() : RefCountedContext("MemberGrou
   p = new Private;
 }
 
-MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupList *list) : RefCountedContext("MemberGroupListContext")
+MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupRefList &list) : RefCountedContext("MemberGroupListContext")
 {
   p = new Private;
-  if (list)
+  for (const auto &mg : list)
   {
-    MemberGroupListIterator mgli(*list);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      p->addMemberGroup(def,relPath,mg);
-    }
+    p->addMemberGroup(def,relPath,mg);
   }
 }
 
-MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping) : RefCountedContext("MemberGroupListContext")
+MemberGroupListContext::MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupList &list,bool subGrouping) : RefCountedContext("MemberGroupListContext")
 {
   p = new Private;
-  if (dict)
+  for (const auto &mg : list)
   {
-    MemberGroupSDict::Iterator di(*dict);
-    const MemberGroup *mg;
-    for (di.toFirst();(mg=di.current());++di)
+    if (!mg->allMembersInSameSection() || !subGrouping)
     {
-      if (!mg->allMembersInSameSection() || !subGrouping)
-      {
-        p->addMemberGroup(def,relPath,mg);
-      }
+      p->addMemberGroup(def,relPath,mg.get());
     }
   }
 }
@@ -9180,38 +9118,30 @@ class InheritedMemberInfoListContext::Private : public GenericNodeListContext
       if (ml)
       {
         addMemberList(inheritedFrom,ml,combinedList);
-        if (ml->getMemberGroupList())
+        for (const auto *mg : ml->getMemberGroupList())
         {
-          MemberGroupListIterator mgli(*ml->getMemberGroupList());
-          MemberGroup *mg;
-          for (mgli.toFirst();(mg=mgli.current());++mgli)
-          {
-            addMemberList(inheritedFrom,mg->members(),combinedList);
-          }
+          addMemberList(inheritedFrom,mg->members(),combinedList);
         }
       }
     }
     void addMemberGroupsOfClass(const ClassDef *inheritedFrom,
                                 const ClassDef *cd,MemberListType lt,MemberList *combinedList)
     {
-      if (cd->getMemberGroupSDict())
+      // TODO: why this there no addMemberGroupsOfNamespace, addMembersGroupsOfFile,
+      // addMemberGroupsOfGroup?
+      for (const auto &mg: cd->getMemberGroups())
       {
-        MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
-        MemberGroup *mg;
-        for (;(mg=mgli.current());++mgli)
+        if (mg->members() && (!mg->allMembersInSameSection() || !cd->subGrouping())) // group is in its own section
         {
-          if (mg->members() && (!mg->allMembersInSameSection() || !cd->subGrouping())) // group is in its own section
+          MemberListIterator li(*mg->members());
+          MemberDef *md;
+          for (li.toFirst();(md=li.current());++li)
           {
-            MemberListIterator li(*mg->members());
-            MemberDef *md;
-            for (li.toFirst();(md=li.current());++li)
+            if (lt==md->getSectionList(mg->container())->listType() &&
+                !md->isReimplementedBy(inheritedFrom) &&
+                md->isBriefSectionVisible())
             {
-              if (lt==md->getSectionList(mg->container())->listType() &&
-                  !md->isReimplementedBy(inheritedFrom) &&
-                  md->isBriefSectionVisible())
-              {
-                combinedList->append(md);
-              }
+              combinedList->append(md);
             }
           }
         }
@@ -9610,25 +9540,26 @@ TemplateVariant SymbolContext::get(const char *name) const
 class SymbolListContext::Private : public GenericNodeListContext
 {
   public:
-    Private(const SearchDefinitionList *sdl)
+    Private(const SearchIndexList::const_iterator &start,
+            const SearchIndexList::const_iterator &end)
     {
-      QListIterator<Definition> li(*sdl);
-      const Definition *def;
       const Definition *prev = 0;
-      for (li.toFirst();(def=li.current());)
+      for (auto it = start; it!=end;)
       {
-        ++li;
-        const Definition *next = li.current();
+        const Definition *def = *it;
+        ++it;
+        const Definition *next = it!=end ? *it : 0;
         append(SymbolContext::alloc(def,prev,next));
         prev = def;
       }
     }
 };
 
-SymbolListContext::SymbolListContext(const SearchDefinitionList *sdl)
+SymbolListContext::SymbolListContext(const SearchIndexList::const_iterator &start,
+                                     const SearchIndexList::const_iterator &end)
     : RefCountedContext("SymbolListContext")
 {
-  p = new Private(sdl);
+  p = new Private(start,end);
 }
 
 SymbolListContext::~SymbolListContext()
@@ -9659,7 +9590,8 @@ TemplateListIntf::ConstIterator *SymbolListContext::createIterator() const
 class SymbolGroupContext::Private
 {
   public:
-    Private(const SearchDefinitionList *sdl) : m_sdl(sdl)
+    Private(const SearchIndexList::const_iterator &start,
+            const SearchIndexList::const_iterator &end) : m_start(start), m_end(end)
     {
       static bool init=FALSE;
       if (!init)
@@ -9676,22 +9608,23 @@ class SymbolGroupContext::Private
     }
     TemplateVariant id() const
     {
-      return m_sdl->id();
+      return searchId(*m_start);
     }
     TemplateVariant name() const
     {
-      return m_sdl->name();
+      return searchName(*m_start);
     }
     TemplateVariant symbolList() const
     {
       if (!m_cache.symbolList)
       {
-        m_cache.symbolList.reset(SymbolListContext::alloc(m_sdl));
+        m_cache.symbolList.reset(SymbolListContext::alloc(m_start,m_end));
       }
       return m_cache.symbolList.get();
     }
   private:
-    const SearchDefinitionList *m_sdl;
+    SearchIndexList::const_iterator m_start;
+    SearchIndexList::const_iterator m_end;
     struct Cachable
     {
       SharedPtr<SymbolListContext> symbolList;
@@ -9703,10 +9636,11 @@ class SymbolGroupContext::Private
 
 PropertyMapper<SymbolGroupContext::Private> SymbolGroupContext::Private::s_inst;
 
-SymbolGroupContext::SymbolGroupContext(const SearchDefinitionList *sdl)
+SymbolGroupContext::SymbolGroupContext(const SearchIndexList::const_iterator &start,
+                                       const SearchIndexList::const_iterator &end)
     : RefCountedContext("SymbolGroupContext")
 {
-  p = new Private(sdl);
+  p = new Private(start,end);
 }
 
 SymbolGroupContext::~SymbolGroupContext()
@@ -9725,18 +9659,30 @@ TemplateVariant SymbolGroupContext::get(const char *name) const
 class SymbolGroupListContext::Private : public GenericNodeListContext
 {
   public:
-    Private(const SearchIndexList *sil)
+    Private(const SearchIndexList &sil)
     {
-      SDict<SearchDefinitionList>::Iterator li(*sil);
-      SearchDefinitionList *dl;
-      for (li.toFirst();(dl=li.current());++li)
+      QCString lastName;
+      auto it = sil.begin();
+      auto it_begin = it;
+      while (it!=sil.end())
+      {
+        QCString name = searchName(*it);
+        if (name!=lastName)
+        {
+          append(SymbolGroupContext::alloc(it_begin,it));
+          it_begin = it;
+          lastName = name;
+        }
+        ++it;
+      }
+      if (it_begin!=sil.end())
       {
-        append(SymbolGroupContext::alloc(dl));
+        append(SymbolGroupContext::alloc(it_begin,sil.end()));
       }
     }
 };
 
-SymbolGroupListContext::SymbolGroupListContext(const SearchIndexList *sil)
+SymbolGroupListContext::SymbolGroupListContext(const SearchIndexList &sil)
     : RefCountedContext("SymbolGroupListContext")
 {
   p = new Private(sil);
@@ -9770,7 +9716,9 @@ TemplateListIntf::ConstIterator *SymbolGroupListContext::createIterator() const
 class SymbolIndexContext::Private
 {
   public:
-    Private(const SearchIndexList *sl,const QCString &name) : m_searchList(sl), m_name(name)
+    Private(const std::string &letter,
+            const SearchIndexList &sl,
+            const QCString &name) : m_letter(letter), m_searchList(sl), m_name(name)
     {
       static bool init=FALSE;
       if (!init)
@@ -9791,7 +9739,7 @@ class SymbolIndexContext::Private
     }
     TemplateVariant letter() const
     {
-      return QString(QChar(m_searchList->letter())).utf8();
+      return m_letter;
     }
     TemplateVariant symbolGroups() const
     {
@@ -9802,7 +9750,8 @@ class SymbolIndexContext::Private
       return m_cache.symbolGroups.get();
     }
   private:
-    const SearchIndexList *m_searchList;
+    QCString m_letter;
+    const SearchIndexList &m_searchList;
     QCString m_name;
     struct Cachable
     {
@@ -9815,10 +9764,10 @@ class SymbolIndexContext::Private
 
 PropertyMapper<SymbolIndexContext::Private> SymbolIndexContext::Private::s_inst;
 
-SymbolIndexContext::SymbolIndexContext(const SearchIndexList *sl,const QCString &name)
+SymbolIndexContext::SymbolIndexContext(const std::string &letter,const SearchIndexList &sl,const QCString &name)
     : RefCountedContext("SymbolIndexContext")
 {
-  p = new Private(sl,name);
+  p = new Private(letter,sl,name);
 }
 
 SymbolIndexContext::~SymbolIndexContext()
@@ -9837,19 +9786,17 @@ TemplateVariant SymbolIndexContext::get(const char *name) const
 class SymbolIndicesContext::Private : public GenericNodeListContext
 {
   public:
-    Private(const SearchIndexInfo *info)
+    Private(const SearchIndexInfo &info)
     {
       // use info->symbolList to populate the list
-      SIntDict<SearchIndexList>::Iterator it(info->symbolList);
-      const SearchIndexList *sl;
-      for (it.toFirst();(sl=it.current());++it) // for each letter
+      for (const auto &kv : info.symbolMap)
       {
-        append(SymbolIndexContext::alloc(sl,info->name));
+        append(SymbolIndexContext::alloc(kv.first,kv.second,info.name));
       }
     }
 };
 
-SymbolIndicesContext::SymbolIndicesContext(const SearchIndexInfo *info) : RefCountedContext("SymbolIndicesContext")
+SymbolIndicesContext::SymbolIndicesContext(const SearchIndexInfo &info) : RefCountedContext("SymbolIndicesContext")
 {
   p = new Private(info);
 }
@@ -9882,7 +9829,7 @@ TemplateListIntf::ConstIterator *SymbolIndicesContext::createIterator() const
 class SearchIndexContext::Private
 {
   public:
-    Private(const SearchIndexInfo *info) : m_info(info)
+    Private(const SearchIndexInfo &info) : m_info(info)
     {
       static bool init=FALSE;
       if (!init)
@@ -9899,11 +9846,11 @@ class SearchIndexContext::Private
     }
     TemplateVariant name() const
     {
-      return m_info->name;
+      return m_info.name;
     }
     TemplateVariant text() const
     {
-      return m_info->text;
+      return m_info.getText();
     }
     TemplateVariant symbolIndices() const
     {
@@ -9914,7 +9861,7 @@ class SearchIndexContext::Private
       return m_cache.symbolIndices.get();
     }
   private:
-    const SearchIndexInfo *m_info;
+    const SearchIndexInfo &m_info;
     struct Cachable
     {
       SharedPtr<SymbolIndicesContext> symbolIndices;
@@ -9926,7 +9873,7 @@ class SearchIndexContext::Private
 
 PropertyMapper<SearchIndexContext::Private> SearchIndexContext::Private::s_inst;
 
-SearchIndexContext::SearchIndexContext(const SearchIndexInfo *info)
+SearchIndexContext::SearchIndexContext(const SearchIndexInfo &info)
     : RefCountedContext("SearchIndexContext")
 {
   p = new Private(info);
@@ -9950,10 +9897,9 @@ class SearchIndicesContext::Private : public GenericNodeListContext
   public:
     Private()
     {
-      const SearchIndexInfo *indices = getSearchIndices();
-      for (int i=0;i<NUM_SEARCH_INDICES;i++)
+      for (const auto &si : getSearchIndices())
       {
-        append(SearchIndexContext::alloc(&indices[i]));
+        append(SearchIndexContext::alloc(si));
       }
     }
 };
@@ -10143,8 +10089,8 @@ void generateOutputViaTemplate()
       SharedPtr<DirListContext>               dirList              (DirListContext::alloc());
       SharedPtr<FileListContext>              fileList             (FileListContext::alloc());
       SharedPtr<FileTreeContext>              fileTree             (FileTreeContext::alloc());
-      SharedPtr<PageTreeContext>              pageTree             (PageTreeContext::alloc(Doxygen::pageSDict));
-      SharedPtr<PageListContext>              pageList             (PageListContext::alloc(Doxygen::pageSDict));
+      SharedPtr<PageTreeContext>              pageTree             (PageTreeContext::alloc(*Doxygen::pageLinkedMap));
+      SharedPtr<PageListContext>              pageList             (PageListContext::alloc(*Doxygen::pageLinkedMap));
       SharedPtr<ExampleTreeContext>           exampleTree          (ExampleTreeContext::alloc());
       SharedPtr<ExampleListContext>           exampleList          (ExampleListContext::alloc());
       SharedPtr<ModuleTreeContext>            moduleTree           (ModuleTreeContext::alloc());
@@ -10193,15 +10139,15 @@ void generateOutputViaTemplate()
       //%% Page mainPage
       if (Doxygen::mainPage)
       {
-        SharedPtr<PageContext> mainPage(PageContext::alloc(Doxygen::mainPage,TRUE,FALSE));
+        SharedPtr<PageContext> mainPage(PageContext::alloc(Doxygen::mainPage.get(),TRUE,FALSE));
         ctx->set("mainPage",mainPage.get());
       }
       else
       {
         // TODO: for LaTeX output index should be main... => solve in template
-        Doxygen::mainPage = createPageDef("[generated]",1,"index","",theTranslator->trMainPage());
+        Doxygen::mainPage.reset(createPageDef("[generated]",1,"index","",theTranslator->trMainPage()));
         Doxygen::mainPage->setFileName("index");
-        SharedPtr<PageContext> mainPage(PageContext::alloc(Doxygen::mainPage,TRUE,FALSE));
+        SharedPtr<PageContext> mainPage(PageContext::alloc(Doxygen::mainPage.get(),TRUE,FALSE));
         ctx->set("mainPage",mainPage.get());
       }
       //%% GlobalsIndex globalsIndex:
index 1a2df8c..a975d3d 100644 (file)
 #include "template.h"
 #include <qlist.h>
 #include <stdio.h>
-#include "dirdef.h"
 #include "classdef.h"
+#include "searchindex.h"
+#include "membergroup.h"
 
 class Definition;
+
 class PageDef;
+class PageLinkedMap;
+class PageLinkedRefMap;
+
 class GroupDef;
+class GroupLinkedMap;
+class GroupList;
+
 class NamespaceDef;
 class NamespaceLinkedMap;
 class NamespaceLinkedRefMap;
-class FileDef;
-class FileList;
+
 class FileNameLinkedMap;
 class ClassLinkedMap;
-class DirSDict;
+class MemberNameInfoLinkedMap;
+
 class DirDef;
-class PageSDict;
-class GroupSDict;
-class GroupDef;
-class GroupList;
+class DirLinkedMap;
+class DirList;
+
+class FileDef;
+class FileList;
 struct IncludeInfo;
 class MemberList;
-class MemberSDict;
 class MemberDef;
 struct Argument;
 class ArgumentList;
-class MemberNameInfoLinkedMap;
 class MemberInfo;
-class MemberGroup;
-class MemberGroupSDict;
-class MemberGroupList;
 class DotNode;
 class DotGfxHierarchyTable;
-struct SearchIndexInfo;
-class SearchIndexList;
-class SearchDefinitionList;
 
 //----------------------------------------------------
 
@@ -547,14 +548,15 @@ class NestingContext : public RefCountedContext, public TemplateListIntf
 
     void addNamespaces(const NamespaceLinkedMap &nsLinkedMap,bool rootOnly,bool addClasses,ClassDefSet &visitedClasses);
     void addNamespaces(const NamespaceLinkedRefMap &nsLinkedMap,bool rootOnly,bool addClasses,ClassDefSet &visitedClasses);
-    void addClasses(const ClassLinkedRefMap &clLinkedMap,bool rootOnly,ClassDefSet &visitedClasses);
     void addClasses(const ClassLinkedMap &clLinkedMap,bool rootOnly,ClassDefSet &visitedClasses);
-    void addDirs(const DirSDict &,ClassDefSet &visitedClasses);
+    void addClasses(const ClassLinkedRefMap &clLinkedMap,bool rootOnly,ClassDefSet &visitedClasses);
+    void addDirs(const DirLinkedMap &,ClassDefSet &visitedClasses);
     void addDirs(const DirList &,ClassDefSet &visitedClasses);
     void addFiles(const FileNameLinkedMap &,ClassDefSet &visitedClasses);
     void addFiles(const FileList &,ClassDefSet &visitedClasses);
-    void addPages(const PageSDict &pages,bool rootOnly,ClassDefSet &visitedClasses);
-    void addModules(const GroupSDict &modules,ClassDefSet &visitedClasses);
+    void addPages(const PageLinkedMap &pages,bool rootOnly,ClassDefSet &visitedClasses);
+    void addPages(const PageLinkedRefMap &pages,bool rootOnly,ClassDefSet &visitedClasses);
+    void addModules(const GroupLinkedMap &modules,ClassDefSet &visitedClasses);
     void addModules(const GroupList &modules,ClassDefSet &visitedClasses);
     void addClassHierarchy(const ClassLinkedMap &clLinkedMap,ClassDefSet &visitedClasses);
     void addDerivedClasses(const BaseClassList &bcl,bool hideSuper,ClassDefSet &visitedClasses);
@@ -691,7 +693,7 @@ class FileTreeContext : public RefCountedContext, public TemplateStructIntf
 class PageListContext : public RefCountedContext, public TemplateListIntf
 {
   public:
-    static PageListContext *alloc(const PageSDict *pages) { return new PageListContext(pages); }
+    static PageListContext *alloc(const PageLinkedMap &pages) { return new PageListContext(pages); }
 
     // TemplateListIntf methods
     virtual uint count() const;
@@ -700,10 +702,10 @@ class PageListContext : public RefCountedContext, public TemplateListIntf
     virtual int addRef()  { return RefCountedContext::addRef(); }
     virtual int release() { return RefCountedContext::release(); }
 
-    void addPages(const PageSDict &pages);
+    void addPages(const PageLinkedMap &pages);
 
   private:
-    PageListContext(const PageSDict *pages);
+    PageListContext(const PageLinkedMap &pages);
    ~PageListContext();
     class Private;
     Private *p;
@@ -714,7 +716,7 @@ class PageListContext : public RefCountedContext, public TemplateListIntf
 class PageTreeContext : public RefCountedContext, public TemplateStructIntf
 {
   public:
-    static PageTreeContext *alloc(const PageSDict *pages) { return new PageTreeContext(pages); }
+    static PageTreeContext *alloc(const PageLinkedMap &pages) { return new PageTreeContext(pages); }
 
     // TemplateStructIntf methods
     virtual TemplateVariant get(const char *name) const;
@@ -722,7 +724,7 @@ class PageTreeContext : public RefCountedContext, public TemplateStructIntf
     virtual int release() { return RefCountedContext::release(); }
 
   private:
-    PageTreeContext(const PageSDict *pages);
+    PageTreeContext(const PageLinkedMap &pages);
    ~PageTreeContext();
     class Private;
     Private *p;
@@ -761,7 +763,7 @@ class ModuleListContext : public RefCountedContext, public TemplateListIntf
     virtual int addRef()  { return RefCountedContext::addRef(); }
     virtual int release() { return RefCountedContext::release(); }
 
-    void addModules(const GroupSDict &);
+    void addModules(const GroupLinkedMap &);
     void addModules(const GroupList &);
 
   private:
@@ -959,8 +961,6 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf
     { return new MemberListContext; }
     static MemberListContext *alloc(const MemberList *ml)
     { return new MemberListContext(ml); }
-    static MemberListContext *alloc(MemberSDict *ml,bool doSort)
-    { return new MemberListContext(ml,doSort); }
     static MemberListContext *alloc(std::vector<const MemberDef *> &&ml)
     { return new MemberListContext(std::move(ml)); }
 
@@ -974,7 +974,6 @@ class MemberListContext : public RefCountedContext, public TemplateListIntf
   private:
     MemberListContext();
     MemberListContext(const MemberList *ml);
-    MemberListContext(MemberSDict *ml,bool doSort);
     MemberListContext(std::vector<const MemberDef *> &&ml);
    ~MemberListContext();
     class Private;
@@ -1008,10 +1007,10 @@ class MemberGroupListContext : public RefCountedContext, public TemplateListIntf
   public:
     static MemberGroupListContext *alloc()
     { return new MemberGroupListContext; }
-    static MemberGroupListContext *alloc(const Definition *def,const QCString &relPath,const MemberGroupList *list)
+    static MemberGroupListContext *alloc(const Definition *def,const QCString &relPath,const MemberGroupRefList &list)
     { return new MemberGroupListContext(def,relPath,list); }
-    static MemberGroupListContext *alloc(const Definition *def,const QCString &relPath,const MemberGroupSDict *dict,bool subGrouping)
-    { return new MemberGroupListContext(def,relPath,dict,subGrouping); }
+    static MemberGroupListContext *alloc(const Definition *def,const QCString &relPath,const MemberGroupList &list,bool subGrouping)
+    { return new MemberGroupListContext(def,relPath,list,subGrouping); }
 
     // TemplateListIntf
     virtual uint count() const;
@@ -1022,8 +1021,8 @@ class MemberGroupListContext : public RefCountedContext, public TemplateListIntf
 
   private:
     MemberGroupListContext();
-    MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupList *list);
-    MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupSDict *mgDict,bool subGrouping);
+    MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupRefList &list);
+    MemberGroupListContext(const Definition *def,const QCString &relPath,const MemberGroupList &list,bool subGrouping);
    ~MemberGroupListContext();
     class Private;
     Private *p;
@@ -1206,8 +1205,9 @@ class SymbolContext : public RefCountedContext, public TemplateStructIntf
 class SymbolListContext : public RefCountedContext, public TemplateListIntf
 {
   public:
-    static SymbolListContext *alloc(const SearchDefinitionList *sdl)
-    { return new SymbolListContext(sdl); }
+    static SymbolListContext *alloc(const SearchIndexList::const_iterator &start,
+                                    const SearchIndexList::const_iterator &end)
+    { return new SymbolListContext(start,end); }
 
     // TemplateListIntf
     virtual uint count() const;
@@ -1217,7 +1217,8 @@ class SymbolListContext : public RefCountedContext, public TemplateListIntf
     virtual int release() { return RefCountedContext::release(); }
 
   private:
-    SymbolListContext(const SearchDefinitionList *sdl);
+    SymbolListContext(const SearchIndexList::const_iterator &start,
+                      const SearchIndexList::const_iterator &end);
    ~SymbolListContext();
     class Private;
     Private *p;
@@ -1228,8 +1229,9 @@ class SymbolListContext : public RefCountedContext, public TemplateListIntf
 class SymbolGroupContext : public RefCountedContext, public TemplateStructIntf
 {
   public:
-    static SymbolGroupContext *alloc(const SearchDefinitionList *sdl)
-    { return new SymbolGroupContext(sdl); }
+    static SymbolGroupContext *alloc(const SearchIndexList::const_iterator &start,
+                                     const SearchIndexList::const_iterator &end)
+    { return new SymbolGroupContext(start,end); }
 
     // TemplateStructIntf methods
     virtual TemplateVariant get(const char *name) const;
@@ -1237,7 +1239,8 @@ class SymbolGroupContext : public RefCountedContext, public TemplateStructIntf
     virtual int release() { return RefCountedContext::release(); }
 
   private:
-    SymbolGroupContext(const SearchDefinitionList *sdl);
+    SymbolGroupContext(const SearchIndexList::const_iterator &start,
+                       const SearchIndexList::const_iterator &end);
    ~SymbolGroupContext();
     class Private;
     Private *p;
@@ -1248,7 +1251,7 @@ class SymbolGroupContext : public RefCountedContext, public TemplateStructIntf
 class SymbolGroupListContext : public RefCountedContext, public TemplateListIntf
 {
   public:
-    static SymbolGroupListContext *alloc(const SearchIndexList *sil)
+    static SymbolGroupListContext *alloc(const SearchIndexList &sil)
     { return new SymbolGroupListContext(sil); }
 
     // TemplateListIntf
@@ -1259,7 +1262,7 @@ class SymbolGroupListContext : public RefCountedContext, public TemplateListIntf
     virtual int release() { return RefCountedContext::release(); }
 
   private:
-    SymbolGroupListContext(const SearchIndexList *sil);
+    SymbolGroupListContext(const SearchIndexList &sil);
    ~SymbolGroupListContext();
     class Private;
     Private *p;
@@ -1270,8 +1273,9 @@ class SymbolGroupListContext : public RefCountedContext, public TemplateListIntf
 class SymbolIndexContext : public RefCountedContext, public TemplateStructIntf
 {
   public:
-    static SymbolIndexContext *alloc(const SearchIndexList *sl,const QCString &name)
-    { return new SymbolIndexContext(sl,name); }
+    static SymbolIndexContext *alloc(const std::string &letter,
+                                     const SearchIndexList &sl,const QCString &name)
+    { return new SymbolIndexContext(letter,sl,name); }
 
     // TemplateStructIntf methods
     virtual TemplateVariant get(const char *name) const;
@@ -1279,7 +1283,7 @@ class SymbolIndexContext : public RefCountedContext, public TemplateStructIntf
     virtual int release() { return RefCountedContext::release(); }
 
   private:
-    SymbolIndexContext(const SearchIndexList *sl,const QCString &name);
+    SymbolIndexContext(const std::string &letter,const SearchIndexList &sl,const QCString &name);
    ~SymbolIndexContext();
     class Private;
     Private *p;
@@ -1290,7 +1294,7 @@ class SymbolIndexContext : public RefCountedContext, public TemplateStructIntf
 class SymbolIndicesContext : public RefCountedContext, public TemplateListIntf
 {
   public:
-    static SymbolIndicesContext *alloc(const SearchIndexInfo *info)
+    static SymbolIndicesContext *alloc(const SearchIndexInfo &info)
     { return new SymbolIndicesContext(info); }
 
     // TemplateListIntf
@@ -1301,7 +1305,7 @@ class SymbolIndicesContext : public RefCountedContext, public TemplateListIntf
     virtual int release() { return RefCountedContext::release(); }
 
   private:
-    SymbolIndicesContext(const SearchIndexInfo *info);
+    SymbolIndicesContext(const SearchIndexInfo &info);
    ~SymbolIndicesContext();
     class Private;
     Private *p;
@@ -1312,7 +1316,7 @@ class SymbolIndicesContext : public RefCountedContext, public TemplateListIntf
 class SearchIndexContext : public RefCountedContext, public TemplateStructIntf
 {
   public:
-    static SearchIndexContext *alloc(const SearchIndexInfo *info)
+    static SearchIndexContext *alloc(const SearchIndexInfo &info)
     { return new SearchIndexContext(info); }
 
     // TemplateStructIntf methods
@@ -1321,7 +1325,7 @@ class SearchIndexContext : public RefCountedContext, public TemplateStructIntf
     virtual int release() { return RefCountedContext::release(); }
 
   private:
-    SearchIndexContext(const SearchIndexInfo *info);
+    SearchIndexContext(const SearchIndexInfo &info);
    ~SearchIndexContext();
     class Private;
     Private *p;
index a1cd28d..89f7568 100644 (file)
@@ -392,9 +392,7 @@ void generateDEFForClass(ClassDef *cd,FTextStream &t)
   }
 
   int numMembers = 0;
-  QListIterator<MemberList> mli(cd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : cd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_detailedLists)==0)
     {
index b719388..2a03ef9 100644 (file)
@@ -68,7 +68,7 @@ class DefinitionImpl::IMPL
     std::unordered_map<std::string,const MemberDef *> sourceRefByDict;
     std::unordered_map<std::string,const MemberDef *> sourceRefsDict;
     RefItemVector xrefListItems;
-    GroupList *partOfGroups = 0;
+    GroupList partOfGroups;
 
     DocInfo   *details = 0;    // not exported
     DocInfo   *inbodyDocs = 0; // not exported
@@ -107,7 +107,6 @@ class DefinitionImpl::IMPL
 
 DefinitionImpl::IMPL::~IMPL()
 {
-  delete partOfGroups;
   delete brief;
   delete details;
   delete body;
@@ -146,7 +145,6 @@ void DefinitionImpl::IMPL::init(const char *df, const char *n)
   sourceRefByDict.clear();
   sourceRefsDict.clear();
   outerScope      = Doxygen::globalScope;
-  partOfGroups    = 0;
   hidden          = FALSE;
   isArtificial    = FALSE;
   lang            = SrcLangExt_Unknown;
@@ -263,20 +261,10 @@ DefinitionImpl::DefinitionImpl(const DefinitionImpl &d)
 {
   m_impl = new DefinitionImpl::IMPL;
   *m_impl = *d.m_impl;
-  m_impl->partOfGroups = 0;
   m_impl->brief = 0;
   m_impl->details = 0;
   m_impl->body = 0;
   m_impl->inbodyDocs = 0;
-  if (d.m_impl->partOfGroups)
-  {
-    GroupListIterator it(*d.m_impl->partOfGroups);
-    GroupDef *gd;
-    for (it.toFirst();(gd=it.current());++it)
-    {
-      makePartOfGroup(gd);
-    }
-  }
   if (d.m_impl->brief)
   {
     m_impl->brief = new BriefInfo(*d.m_impl->brief);
@@ -303,11 +291,8 @@ DefinitionImpl::~DefinitionImpl()
   {
     removeFromMap(m_impl->symbolName,m_impl->def);
   }
-  if (m_impl)
-  {
-    delete m_impl;
-    m_impl=0;
-  }
+  delete m_impl;
+  m_impl=0;
 }
 
 void DefinitionImpl::setName(const char *name)
@@ -326,7 +311,7 @@ void DefinitionImpl::setId(const char *id)
   if (Doxygen::clangUsrMap)
   {
     //printf("DefinitionImpl::setId '%s'->'%s'\n",id,m_impl->name.data());
-    Doxygen::clangUsrMap->insert(id,m_impl->def);
+    Doxygen::clangUsrMap->insert(std::make_pair(id,m_impl->def));
   }
 }
 
@@ -631,7 +616,7 @@ struct FilterCacheItem
 class FilterCache
 {
   public:
-    FilterCache() : m_endPos(0) { m_cache.setAutoDelete(TRUE); }
+    FilterCache() : m_endPos(0) { }
     bool getFileContents(const QCString &fileName,BufStr &str)
     {
       static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
@@ -640,30 +625,31 @@ class FilterCache
       FILE *f=0;
       const int blockSize = 4096;
       char buf[blockSize];
-      FilterCacheItem *item=0;
-      if (usePipe && (item = m_cache.find(fileName))) // cache hit: reuse stored result
+      auto it = m_cache.find(fileName.str());
+      if (usePipe && it!=m_cache.end()) // cache hit: reuse stored result
       {
+        auto item = it->second;
         //printf("getFileContents(%s): cache hit\n",qPrint(fileName));
         // file already processed, get the results after filtering from the tmp file
         Debug::print(Debug::FilterOutput,0,"Reusing filter result for %s from %s at offset=%d size=%d\n",
-               qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item->filePos,(int)item->fileSize);
+               qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item.filePos,(int)item.fileSize);
         f = Portable::fopen(Doxygen::filterDBFileName,"rb");
         if (f)
         {
           bool success=TRUE;
-          str.resize(static_cast<uint>(item->fileSize+1));
-          if (Portable::fseek(f,item->filePos,SEEK_SET)==-1)
+          str.resize(static_cast<uint>(item.fileSize+1));
+          if (Portable::fseek(f,item.filePos,SEEK_SET)==-1)
           {
-            err("Failed to seek to position %d in filter database file %s\n",(int)item->filePos,qPrint(Doxygen::filterDBFileName));
+            err("Failed to seek to position %d in filter database file %s\n",(int)item.filePos,qPrint(Doxygen::filterDBFileName));
             success=FALSE;
           }
           if (success)
           {
-            size_t numBytes = fread(str.data(),1,item->fileSize,f);
-            if (numBytes!=item->fileSize)
+            size_t numBytes = fread(str.data(),1,item.fileSize,f);
+            if (numBytes!=item.fileSize)
             {
               err("Failed to read %d bytes from position %d in filter database file %s: got %d bytes\n",
-                 (int)item->fileSize,(int)item->filePos,qPrint(Doxygen::filterDBFileName),(int)numBytes);
+                 (int)item.fileSize,(int)item.filePos,qPrint(Doxygen::filterDBFileName),(int)numBytes);
               success=FALSE;
             }
           }
@@ -685,14 +671,13 @@ class FilterCache
         Debug::print(Debug::ExtCmd,0,"Executing popen(`%s`)\n",qPrint(cmd));
         f = Portable::popen(cmd,"r");
         FILE *bf = Portable::fopen(Doxygen::filterDBFileName,"a+b");
-        item = new FilterCacheItem;
-        item->filePos = m_endPos;
+        FilterCacheItem item;
+        item.filePos = m_endPos;
         if (bf==0)
         {
           // handle error
           err("Error opening filter database file %s\n",qPrint(Doxygen::filterDBFileName));
           str.addChar('\0');
-          delete item;
           Portable::pclose(f);
           return FALSE;
         }
@@ -708,7 +693,6 @@ class FilterCache
             err("Failed to write to filter database %s. Wrote %d out of %d bytes\n",
                 qPrint(Doxygen::filterDBFileName),(int)bytesWritten,(int)bytesRead);
             str.addChar('\0');
-            delete item;
             Portable::pclose(f);
             fclose(bf);
             return FALSE;
@@ -717,11 +701,11 @@ class FilterCache
           str.addArray(buf,static_cast<uint>(bytesWritten));
         }
         str.addChar('\0');
-        item->fileSize = size;
+        item.fileSize = size;
         // add location entry to the dictionary
-        m_cache.append(fileName,item);
+        m_cache.insert(std::make_pair(fileName.str(),item));
         Debug::print(Debug::FilterOutput,0,"Storing new filter result for %s in %s at offset=%d size=%d\n",
-               qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item->filePos,(int)item->fileSize);
+               qPrint(fileName),qPrint(Doxygen::filterDBFileName),(int)item.filePos,(int)item.fileSize);
         // update end of file position
         m_endPos += size;
         Portable::pclose(f);
@@ -743,7 +727,7 @@ class FilterCache
       return TRUE;
     }
   private:
-    SDict<FilterCacheItem> m_cache;
+    std::unordered_map<std::string,FilterCacheItem> m_cache;
     portable_off_t m_endPos;
 };
 
@@ -1506,10 +1490,9 @@ QCString DefinitionImpl::localName() const
   return m_impl->localName;
 }
 
-void DefinitionImpl::makePartOfGroup(GroupDef *gd)
+void DefinitionImpl::makePartOfGroup(const GroupDef *gd)
 {
-  if (m_impl->partOfGroups==0) m_impl->partOfGroups = new GroupList;
-  m_impl->partOfGroups->append(gd);
+  m_impl->partOfGroups.push_back(gd);
 }
 
 void DefinitionImpl::setRefItems(const RefItemVector &sli)
@@ -2000,24 +1983,18 @@ FileDef *DefinitionImpl::getBodyDef() const
   return m_impl->body ? m_impl->body->fileDef : 0;
 }
 
-GroupList *DefinitionImpl::partOfGroups() const
+const GroupList &DefinitionImpl::partOfGroups() const
 {
   return m_impl->partOfGroups;
 }
 
 bool DefinitionImpl::isLinkableViaGroup() const
 {
-  GroupList *gl = partOfGroups();
-  if (gl)
+  for (const auto &gd : partOfGroups())
   {
-    GroupListIterator gli(*gl);
-    GroupDef *gd;
-    for (gli.toFirst();(gd=gli.current());++gli)
-    {
-      if (gd->isLinkable()) return TRUE;
-    }
+    if (gd->isLinkable()) return true;
   }
-  return FALSE;
+  return false;
 }
 
 Definition *DefinitionImpl::getOuterScope() const
index 204e6f6..444b188 100644 (file)
@@ -34,7 +34,6 @@
 class FileDef;
 class OutputList;
 class SectionRefs;
-class MemberSDict;
 class MemberDef;
 class GroupDef;
 class GroupList;
@@ -261,7 +260,7 @@ class Definition
     /** Returns the programming language this definition was written in. */
     virtual SrcLangExt getLanguage() const = 0;
 
-    virtual GroupList *partOfGroups() const = 0;
+    virtual const GroupList &partOfGroups() const = 0;
     virtual bool isLinkableViaGroup() const = 0;
 
     virtual const RefItemVector &xrefListItems() const = 0;
@@ -361,7 +360,7 @@ class DefinitionMutable
     // --- actions ----
     //-----------------------------------------------------------------------------------
 
-    virtual void makePartOfGroup(GroupDef *gd) = 0;
+    virtual void makePartOfGroup(const GroupDef *gd) = 0;
 
     /*! Add the list of anchors that mark the sections that are found in the
      * documentation.
index e455dc4..541e346 100644 (file)
@@ -68,7 +68,7 @@ class DefinitionImpl
     int getEndBodyLine() const;
     FileDef *getBodyDef() const;
     SrcLangExt getLanguage() const;
-    GroupList *partOfGroups() const;
+    const GroupList &partOfGroups() const;
     bool isLinkableViaGroup() const;
     const RefItemVector &xrefListItems() const;
     const Definition *findInnerCompound(const char *name) const;
@@ -105,7 +105,7 @@ class DefinitionImpl
     void writeInlineCode(OutputList &ol,const char *scopeName) const;
     void writeSourceRefs(OutputList &ol,const char *scopeName) const;
     void writeSourceReffedBy(OutputList &ol,const char *scopeName) const;
-    void makePartOfGroup(GroupDef *gd);
+    void makePartOfGroup(const GroupDef *gd);
     void writeNavigationPath(OutputList &ol) const;
     QCString navigationPathAsString() const;
     void writeQuickMemberLinks(OutputList &,const MemberDef *) const;
@@ -187,7 +187,7 @@ class DefinitionMixin : public Base
     virtual int getEndBodyLine() const { return m_impl.getEndBodyLine(); }
     virtual FileDef *getBodyDef() const { return m_impl.getBodyDef(); }
     virtual SrcLangExt getLanguage() const { return m_impl.getLanguage(); }
-    virtual GroupList *partOfGroups() const { return m_impl.partOfGroups(); }
+    virtual const GroupList &partOfGroups() const { return m_impl.partOfGroups(); }
     virtual bool isLinkableViaGroup() const { return m_impl.isLinkableViaGroup(); }
     virtual const RefItemVector &xrefListItems() const { return m_impl.xrefListItems(); }
     virtual const Definition *findInnerCompound(const char *name) const { return m_impl.findInnerCompound(name); }
@@ -249,7 +249,7 @@ class DefinitionMixin : public Base
     { m_impl.writeSourceRefs(ol,scopeName); }
     virtual void writeSourceReffedBy(OutputList &ol,const char *scopeName) const
     { m_impl.writeSourceReffedBy(ol,scopeName); }
-    virtual void makePartOfGroup(GroupDef *gd)
+    virtual void makePartOfGroup(const GroupDef *gd)
     { m_impl.makePartOfGroup(gd); }
     virtual void writeNavigationPath(OutputList &ol) const
     { m_impl.writeNavigationPath(ol); }
@@ -393,7 +393,7 @@ class DefinitionAliasMixin : public Base
     { return m_alias->getBodyDef(); }
     virtual SrcLangExt getLanguage() const
     { return m_alias->getLanguage(); }
-    virtual GroupList *partOfGroups() const
+    virtual const GroupList &partOfGroups() const
     { return m_alias->partOfGroups(); }
     virtual bool isLinkableViaGroup() const
     { return m_alias->isLinkableViaGroup(); }
index 64ea491..80c85c6 100644 (file)
@@ -1054,7 +1054,7 @@ void ClassDiagram::writeFigure(FTextStream &output,const char *path,
   p->base.computeExtremes(&baseMaxLabelWidth,&baseMaxX);
   p->super.computeExtremes(&superMaxLabelWidth,&superMaxX);
 
-  uint rows=baseRows+superRows-1;
+  uint rows=QMAX(1,baseRows+superRows-1);
   uint cols=(QMAX(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth;
 
   // Estimate the image aspect width and height in pixels.
index 14d978e..6f23251 100644 (file)
@@ -1,6 +1,22 @@
-#include "md5.h"
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2020 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <algorithm>
 
 #include "dirdef.h"
+#include "md5.h"
 #include "filename.h"
 #include "doxygen.h"
 #include "util.h"
@@ -15,7 +31,7 @@
 #include "docparser.h"
 #include "definitionimpl.h"
 #include "filedef.h"
-#include <algorithm>
+
 
 //----------------------------------------------------------------------
 
@@ -40,7 +56,7 @@ class DirDefImpl : public DefinitionMixin<DirDef>
     virtual int level() const { return m_level; }
     virtual DirDef *parent() const { return m_parent; }
     virtual int dirCount() const { return m_dirCount; }
-    virtual const QDict<UsedDir> *usedDirs() const { return m_usedDirs; }
+    virtual const UsedDirLinkedMap &usedDirs() const { return m_usedDirs; }
     virtual bool isParentOf(const DirDef *dir) const;
     virtual bool depGraphIsTrivial() const;
     virtual QCString shortTitle() const;
@@ -79,7 +95,7 @@ class DirDefImpl : public DefinitionMixin<DirDef>
     int m_dirCount;
     int m_level;
     DirDef *m_parent;
-    QDict<UsedDir> *m_usedDirs;
+    UsedDirLinkedMap m_usedDirs;
 };
 
 DirDef *createDirDef(const char *path)
@@ -117,8 +133,6 @@ DirDefImpl::DirDefImpl(const char *path) : DefinitionMixin(path,1,1,path)
   }
 
   m_fileList   = new FileList;
-  m_usedDirs   = new QDict<UsedDir>(257);
-  m_usedDirs->setAutoDelete(TRUE);
   m_dirCount   = g_dirCount++;
   m_level=-1;
   m_parent=0;
@@ -127,7 +141,6 @@ DirDefImpl::DirDefImpl(const char *path) : DefinitionMixin(path,1,1,path)
 DirDefImpl::~DirDefImpl()
 {
   delete m_fileList;
-  delete m_usedDirs;
 }
 
 bool DirDefImpl::isLinkableInProject() const
@@ -641,10 +654,10 @@ void DirDefImpl::addUsesDependency(DirDef *dir,FileDef *srcFd,
 
   // levels match => add direct dependency
   bool added=FALSE;
-  UsedDir *usedDir = m_usedDirs->find(dir->getOutputFileBase());
+  UsedDir *usedDir = m_usedDirs.find(dir->getOutputFileBase());
   if (usedDir) // dir dependency already present
   {
-     FilePair *usedPair = usedDir->findFilePair(
+     const FilePair *usedPair = usedDir->findFilePair(
          srcFd->getOutputFileBase()+dstFd->getOutputFileBase());
      if (usedPair==0) // new file dependency
      {
@@ -660,9 +673,9 @@ void DirDefImpl::addUsesDependency(DirDef *dir,FileDef *srcFd,
   else // new directory dependency
   {
     //printf("  => new file\n");
-    usedDir = new UsedDir(dir,inherited);
-    usedDir->addFileDep(srcFd,dstFd);
-    m_usedDirs->insert(dir->getOutputFileBase(),usedDir);
+    auto newUsedDir = std::make_unique<UsedDir>(dir,inherited);
+    newUsedDir->addFileDep(srcFd,dstFd);
+    usedDir = m_usedDirs.add(dir->getOutputFileBase(),std::move(newUsedDir));
     added=TRUE;
   }
   if (added)
@@ -717,14 +730,14 @@ void DirDefImpl::computeDependencies()
       }
     }
   }
-  if (m_usedDirs)
+
+  std::sort(m_usedDirs.begin(),m_usedDirs.end(),
+            [](const auto &u1,const auto &u2)
+            { return qstricmp(u1->dir()->getOutputFileBase(),u2->dir()->getOutputFileBase())<0; });
+
+  for (const auto& usedDirectory : m_usedDirs)
   {
-    QDictIterator<UsedDir> udi(*m_usedDirs);
-    UsedDir *udir;
-    for (udi.toFirst();(udir=udi.current());++udi)
-    {
-      udir->sort();
-    }
+    usedDirectory->sort();
   }
 }
 
@@ -740,7 +753,7 @@ bool DirDefImpl::isParentOf(const DirDef *dir) const
 
 bool DirDefImpl::depGraphIsTrivial() const
 {
-  return m_usedDirs->count()==0;
+  return m_usedDirs.empty();
 }
 
 //----------------------------------------------------------------------
@@ -786,13 +799,14 @@ FilePair *UsedDir::findFilePair(const char *name)
 DirDef *DirDefImpl::createNewDir(const char *path)
 {
   ASSERT(path!=0);
-  DirDef *dir = Doxygen::directories->find(path);
+  DirDef *dir = Doxygen::dirLinkedMap->find(path);
   if (dir==0) // new dir
   {
+    dir = Doxygen::dirLinkedMap->add(path,
+            std::unique_ptr<DirDef>(
+              createDirDef(path)));
     //printf("Adding new dir %s\n",path);
-    dir = createDirDef(path);
     //printf("createNewDir %s short=%s\n",path,dir->shortName().data());
-    Doxygen::directories->append(path,dir);
   }
   return dir;
 }
@@ -926,14 +940,11 @@ void DirRelation::writeDocumentation(OutputList &ol)
 static void computeCommonDirPrefix()
 {
   QCString path;
-  DirDef *dir;
-  DirSDict::Iterator sdi(*Doxygen::directories);
-  if (Doxygen::directories->count()>0) // we have at least one dir
+  auto it = Doxygen::dirLinkedMap->begin();
+  if (!Doxygen::dirLinkedMap->empty()) // we have at least one dir
   {
     // start will full path of first dir
-    sdi.toFirst();
-    dir=sdi.current();
-    path=dir->name();
+    path=(*it)->name();
     int i=path.findRev('/',(int)path.length()-2);
     path=path.left(i+1);
     bool done=FALSE;
@@ -946,8 +957,8 @@ static void computeCommonDirPrefix()
       while (!done)
       {
         uint l = path.length();
-        uint count=0;
-        for (sdi.toFirst();(dir=sdi.current());++sdi)
+        size_t count=0;
+        for (const auto &dir : *Doxygen::dirLinkedMap)
         {
           QCString dirName = dir->name();
           if (dirName.length()>path.length())
@@ -985,7 +996,7 @@ static void computeCommonDirPrefix()
           }
           count++;
         }
-        if (count==Doxygen::directories->count())
+        if (count==Doxygen::dirLinkedMap->size())
           // path matches for all directories -> found the common prefix
         {
           done=TRUE;
@@ -993,7 +1004,7 @@ static void computeCommonDirPrefix()
       }
     }
   }
-  for (sdi.toFirst();(dir=sdi.current());++sdi)
+  for (const auto &dir : *Doxygen::dirLinkedMap)
   {
     QCString diskName = dir->name().right(dir->name().length()-path.length());
     dir->setDiskName(diskName);
@@ -1012,7 +1023,7 @@ void buildDirectories()
       if (fd->getReference().isEmpty())
       {
         DirDef *dir;
-        if ((dir=Doxygen::directories->find(fd->getPath()))==0) // new directory
+        if ((dir=Doxygen::dirLinkedMap->find(fd->getPath()))==0) // new directory
         {
           dir = DirDefImpl::mergeDirectoryInTree(fd->getPath());
         }
@@ -1025,45 +1036,48 @@ void buildDirectories()
     }
   }
 
-  //DirDef *root = new DirDef("root:");
   // compute relations between directories => introduce container dirs.
-  DirDef *dir;
-  DirSDict::Iterator sdi(*Doxygen::directories);
-  for (sdi.toFirst();(dir=sdi.current());++sdi)
+  for (const auto &dir : *Doxygen::dirLinkedMap)
   {
     QCString name = dir->name();
     int i=name.findRev('/',(int)name.length()-2);
     if (i>0)
     {
-      DirDef *parent = Doxygen::directories->find(name.left(i+1));
+      DirDef *parent = Doxygen::dirLinkedMap->find(name.left(i+1));
       //if (parent==0) parent=root;
       if (parent)
       {
-        parent->addSubDir(dir);
+        parent->addSubDir(dir.get());
         //printf("DirDefImpl::addSubdir(): Adding subdir\n%s to\n%s\n",
         //  dir->displayName().data(), parent->displayName().data());
       }
     }
   }
-  for (sdi.toFirst();(dir=sdi.current());++sdi)
+
+  // sort the directory contents
+  for (const auto &dir : *Doxygen::dirLinkedMap)
   {
     dir->sort();
   }
-  Doxygen::directories->sort();
+
+  // short the directories themselves
+  std::sort(Doxygen::dirLinkedMap->begin(),
+            Doxygen::dirLinkedMap->end(),
+            [](const auto &d1,const auto &d2)
+            { return qstricmp(d1->shortName(),d2->shortName()) < 0; });
+
   computeCommonDirPrefix();
 }
 
 void computeDirDependencies()
 {
-  DirDef *dir;
-  DirSDict::Iterator sdi(*Doxygen::directories);
   // compute nesting level for each directory
-  for (sdi.toFirst();(dir=sdi.current());++sdi)
+  for (const auto &dir : *Doxygen::dirLinkedMap)
   {
     dir->setLevel();
   }
   // compute uses dependencies between directories
-  for (sdi.toFirst();(dir=sdi.current());++sdi)
+  for (const auto &dir : *Doxygen::dirLinkedMap)
   {
     //printf("computeDependencies for %s: #dirs=%d\n",dir->name().data(),Doxygen::directories.count());
     dir->computeDependencies();
@@ -1073,9 +1087,7 @@ void computeDirDependencies()
 
 void generateDirDocs(OutputList &ol)
 {
-  DirDef *dir;
-  DirSDict::Iterator sdi(*Doxygen::directories);
-  for (sdi.toFirst();(dir=sdi.current());++sdi)
+  for (const auto &dir : *Doxygen::dirLinkedMap)
   {
     ol.pushGeneratorState();
     if (!dir->hasDocumentation())
@@ -1087,9 +1099,7 @@ void generateDirDocs(OutputList &ol)
   }
   if (Config_getBool(DIRECTORY_GRAPH))
   {
-    SDict<DirRelation>::Iterator rdi(Doxygen::dirRelations);
-    DirRelation *dr;
-    for (rdi.toFirst();(dr=rdi.current());++rdi)
+    for (const auto &dr : Doxygen::dirRelations)
     {
       dr->writeDocumentation(ol);
     }
index 1057049..b3f2a30 100644 (file)
 #ifndef DIRDEF_H
 #define DIRDEF_H
 
+#include "linkedmap.h"
 #include "sortdict.h"
 #include "definition.h"
 
 #include <vector>
+#include <map>
 #include <qglobal.h>
 #include <qcstring.h>
 
+
 class FileList;
 class QStrList;
 class FileDef;
 class OutputList;
 class UsedDir;
 class FTextStream;
-
+class FilePair;
+class FilePairDict;
 class DirDef;
-
-/** A list of directories. */
-typedef std::vector<DirDef*> DirList;
+class DirList;
 
 bool compareDirDefs(const DirDef *item1, const DirDef *item2);
 
+// ------------------
+
+/** Class representing a pair of FileDef objects */
+class FilePair
+{
+  public:
+    FilePair(FileDef *src,FileDef *dst) : m_src(src), m_dst(dst) {}
+    const FileDef *source() const { return m_src; }
+    const FileDef *destination() const { return m_dst; }
+  private:
+    FileDef *m_src;
+    FileDef *m_dst;
+};
+
+// ------------------
+
+/** A sorted dictionary of FilePair objects. */
+class FilePairDict : public SDict<FilePair>
+{
+  public:
+    FilePairDict(uint size) : SDict<FilePair>(size) {}
+  private:
+    int compareValues(const FilePair *item1,const FilePair *item2) const;
+};
+
+// ------------------
+
+/** Usage information of a directory. */
+class UsedDir
+{
+  public:
+    UsedDir(const DirDef *dir,bool inherited);
+    virtual ~UsedDir();
+    void addFileDep(FileDef *srcFd,FileDef *dstFd);
+    FilePair *findFilePair(const char *name);
+    const FilePairDict &filePairs() const { return m_filePairs; }
+    const DirDef *dir() const { return m_dir; }
+    bool inherited() const { return m_inherited; }
+    void sort();
+
+  private:
+    const DirDef *m_dir;
+    FilePairDict m_filePairs;
+    bool m_inherited;
+};
+
+// ------------------
+
 /** A model of a directory symbol. */
 class DirDef : public DefinitionMutable, public Definition
 {
   public:
     virtual ~DirDef() {}
 
+    class UsedDirLinkedMap : public LinkedMap<UsedDir> {};
+
     // accessors
     virtual DefType definitionType() const = 0;
     virtual QCString getOutputFileBase() const = 0;
@@ -59,7 +111,7 @@ class DirDef : public DefinitionMutable, public Definition
     virtual int level() const = 0;
     virtual DirDef *parent() const = 0;
     virtual int dirCount() const = 0;
-    virtual const QDict<UsedDir> *usedDirs() const = 0;
+    virtual const UsedDirLinkedMap &usedDirs() const = 0;
     virtual bool isParentOf(const DirDef *dir) const = 0;
     virtual bool depGraphIsTrivial() const = 0;
     virtual QCString shortTitle() const = 0;
@@ -83,49 +135,6 @@ class DirDef : public DefinitionMutable, public Definition
 DirDef            *toDirDef(Definition *d);
 const DirDef      *toDirDef(const Definition *d);
 
-// ------------------
-
-
-/** Class representing a pair of FileDef objects */
-class FilePair
-{
-  public:
-    FilePair(FileDef *src,FileDef *dst) : m_src(src), m_dst(dst) {}
-    const FileDef *source() const { return m_src; }
-    const FileDef *destination() const { return m_dst; }
-  private:
-    FileDef *m_src;
-    FileDef *m_dst;
-};
-
-/** A sorted dictionary of FilePair objects. */
-class FilePairDict : public SDict<FilePair>
-{
-  public:
-    FilePairDict(uint size) : SDict<FilePair>(size) {}
-  private:
-    int compareValues(const FilePair *item1,const FilePair *item2) const;
-};
-
-/** Usage information of a directory. */
-class UsedDir
-{
-  public:
-    UsedDir(const DirDef *dir,bool inherited);
-    virtual ~UsedDir();
-    void addFileDep(FileDef *srcFd,FileDef *dstFd);
-    FilePair *findFilePair(const char *name);
-    const FilePairDict &filePairs() const { return m_filePairs; }
-    const DirDef *dir() const { return m_dir; }
-    bool inherited() const { return m_inherited; }
-    void sort();
-
-  private:
-    const DirDef *m_dir;
-    FilePairDict m_filePairs;
-    bool m_inherited;
-};
-
 /** A usage relation between two directories. */
 class DirRelation
 {
@@ -143,17 +152,21 @@ class DirRelation
     UsedDir *m_dst;
 };
 
-/** A sorted dictionary of DirDef objects. */
-class DirSDict : public SDict<DirDef>
+/** A linked map of directories */
+class DirLinkedMap : public LinkedMap<DirDef>
 {
-  public:
-    DirSDict(uint size) : SDict<DirDef>(size) {}
-    int compareValues(const DirDef *item1,const DirDef *item2) const
-    {
-      return qstricmp(item1->shortName(),item2->shortName());
-    }
 };
 
+/** A list of directories. */
+class DirList : public std::vector<const DirDef*>
+{
+};
+
+class DirRelationLinkedMap : public LinkedMap<DirRelation>
+{
+};
+
+// ------------------
 
 void buildDirectories();
 void generateDirDocs(OutputList &ol);
index 2d0521b..05e9347 100644 (file)
@@ -484,18 +484,7 @@ DB_GEN_C2("IndexSections " << is)
     case isModuleDocumentation:
       {
         t << "</title>" << endl;
-        GroupSDict::Iterator gli(*Doxygen::groupSDict);
-        GroupDef *gd;
-        bool found=FALSE;
-        for (gli.toFirst();(gd=gli.current()) && !found;++gli)
-        {
-          if (!gd->isReference())
-          {
-            t << "    <xi:include href=\"" << gd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
-            found=TRUE;
-          }
-        }
-        for (;(gd=gli.current());++gli)
+        for (const auto &gd : *Doxygen::groupLinkedMap)
         {
           if (!gd->isReference())
           {
@@ -508,22 +497,11 @@ DB_GEN_C2("IndexSections " << is)
     case isDirDocumentation:
       {
         t << "</title>" << endl;
-        SDict<DirDef>::Iterator dli(*Doxygen::directories);
-        DirDef *dd;
-        bool found=FALSE;
-        for (dli.toFirst();(dd=dli.current()) && !found;++dli)
+        for (const auto &dd : *Doxygen::dirLinkedMap)
         {
           if (dd->isLinkableInProject())
           {
             t << "<    xi:include href=\"" << dd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
-            found=TRUE;
-          }
-        }
-        for (;(dd=dli.current());++dli)
-        {
-          if (dd->isLinkableInProject())
-          {
-            t << "    <xi:include href=\"" << dd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
           }
         }
       }
@@ -595,13 +573,7 @@ DB_GEN_C2("IndexSections " << is)
     case isExampleDocumentation:
       {
         t << "</title>" << endl;
-        PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-        PageDef *pd=pdi.toFirst();
-        if (pd)
-        {
-          t << "    <xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
-        }
-        for (++pdi;(pd=pdi.current());++pdi)
+        for (const auto &pd : *Doxygen::exampleLinkedMap)
         {
           t << "    <xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
         }
@@ -620,9 +592,7 @@ DB_GEN_C2("IndexSections " << is)
 void DocbookGenerator::writePageLink(const char *name, bool /*first*/)
 {
 DB_GEN_C
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd = pdi.toFirst();
-  for (pd = pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
     if (!pd->getGroupDef() && !pd->isReference() && pd->name() == stripPath(name))
     {
index d82d1b3..49fb9dc 100644 (file)
@@ -3,8 +3,8 @@
  * Copyright (C) 1997-2019 by Dimitri van Heesch.
  *
  * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby 
- * granted. No representations are made about the suitability of this software 
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
  * for any purpose. It is provided "as is" without express or implied warranty.
  * See the GNU General Public License for more details.
  *
@@ -62,7 +62,7 @@ void DocGroup::enterCompound(const char *fileName,int line,const char *name)
   m_memberGroupDocs.resize(0);
   m_compoundName = name;
   int i = m_compoundName.find('(');
-  if (i!=-1) 
+  if (i!=-1)
   {
     m_compoundName=m_compoundName.left(i); // strip category (Obj-C)
   }
@@ -89,17 +89,15 @@ void DocGroup::leaveCompound(const char *,int,const char * /*name*/)
 int DocGroup::findExistingGroup(const MemberGroupInfo *info)
 {
   //printf("findExistingGroup %s:%s\n",info->header.data(),info->compoundName.data());
-  QIntDictIterator<MemberGroupInfo> di(Doxygen::memGrpInfoDict);
-  MemberGroupInfo *mi;
-  for (di.toFirst();(mi=di.current());++di)
+  for (const auto &kv : Doxygen::memberGroupInfoMap)
   {
-    if (m_compoundName==mi->compoundName &&  // same file or scope
-       !mi->header.isEmpty() &&             // not a nameless group
-       qstricmp(mi->header,info->header)==0  // same header name
+    if (m_compoundName==kv.second->compoundName &&  // same file or scope
+       !kv.second->header.isEmpty() &&             // not a nameless group
+       qstricmp(kv.second->header,info->header)==0  // same header name
        )
     {
       //printf("Found it!\n");
-      return (int)di.currentKey(); // put the item in this group
+      return kv.first; // put the item in this group
     }
   }
   return ++g_groupId; // start new group
@@ -119,13 +117,16 @@ void DocGroup::open(Entry *e,const char *,int, bool implicit)
     //printf("    membergroup id=%d %s\n",m_memberGroupId,m_memberGroupHeader.data());
     if (m_memberGroupId==DOX_NOGROUP) // no group started yet
     {
-      MemberGroupInfo *info = new MemberGroupInfo;
+      auto info = std::make_unique<MemberGroupInfo>();
       info->header = m_memberGroupHeader.stripWhiteSpace();
       info->compoundName = m_compoundName;
-      m_memberGroupId = findExistingGroup(info);
-      //printf("    use membergroup %d\n",m_memberGroupId);
-      Doxygen::memGrpInfoDict.insert(m_memberGroupId,info);
-
+      m_memberGroupId = findExistingGroup(info.get());
+      auto it = Doxygen::memberGroupInfoMap.find(m_memberGroupId);
+      if (it==Doxygen::memberGroupInfoMap.end())
+      {
+         //printf("    use membergroup %d\n",m_memberGroupId);
+         Doxygen::memberGroupInfoMap.insert(std::make_pair(m_memberGroupId,std::move(info)));
+      }
       m_memberGroupRelates = e->relates;
       e->mGrpId = m_memberGroupId;
     }
@@ -149,9 +150,10 @@ void DocGroup::close(Entry *e,const char *fileName,int line,bool foundInline,boo
   //    e->name.data(),e->section,fileName,line,m_autoGroupStack.size());
   if (m_memberGroupId!=DOX_NOGROUP) // end of member group
   {
-    MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(m_memberGroupId);
-    if (info) // known group
+    auto it = Doxygen::memberGroupInfoMap.find(m_memberGroupId);
+    if (it!=Doxygen::memberGroupInfoMap.end()) // known group
     {
+      auto &info = it->second;
       info->doc = m_memberGroupDocs;
       info->docFile = fileName;
       info->docLine = line;
@@ -199,9 +201,10 @@ void DocGroup::addDocs(Entry *e)
       m_memberGroupDocs+="\n\n";
     }
     m_memberGroupDocs+=e->doc;
-    MemberGroupInfo *info=Doxygen::memGrpInfoDict.find(m_memberGroupId);
-    if (info) 
+    auto it =Doxygen::memberGroupInfoMap.find(m_memberGroupId);
+    if (it!=Doxygen::memberGroupInfoMap.end())
     {
+      auto &info = it->second;
       info->doc = m_memberGroupDocs;
       info->docFile = e->docFile;
       info->docLine = e->docLine;
index af9e6a8..33faf54 100644 (file)
@@ -685,7 +685,7 @@ static bool findDocsForMemberOrCompound(const char *commandName,
   const FileDef      *fd=0;
   const GroupDef     *gd=0;
   const PageDef      *pd=0;
-  gd = Doxygen::groupSDict->find(cmdArg);
+  gd = Doxygen::groupLinkedMap->find(cmdArg);
   if (gd) // group
   {
     *pDoc=gd->documentation();
@@ -693,7 +693,7 @@ static bool findDocsForMemberOrCompound(const char *commandName,
     *pDef=gd;
     return TRUE;
   }
-  pd = Doxygen::pageSDict->find(cmdArg);
+  pd = Doxygen::pageLinkedMap->find(cmdArg);
   if (pd) // page
   {
     *pDoc=pd->documentation();
@@ -2427,7 +2427,7 @@ DocRef::DocRef(DocNode *parent,const QCString &target,const QCString &context) :
     PageDef *pd = 0;
     if (sec->type()==SectionType::Page)
     {
-      pd = Doxygen::pageSDict->find(target);
+      pd = Doxygen::pageLinkedMap->find(target);
     }
     m_text         = sec->title();
     if (m_text.isEmpty()) m_text = sec->label();
index 330db00..63a49ca 100644 (file)
@@ -755,6 +755,7 @@ RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revisio
 <St_Para,St_Text>[\-+0-9] |
 <St_Para,St_Text>{WORD1} |
 <St_Para,St_Text>{WORD2} { /* function call */
+                         if (QCString(yytext).find("\\ilinebr")!=-1) REJECT; // see issue #8311
                          lineCount(yytext,yyleng);
                          if (yytext[0]=='%') // strip % if present
                            g_token->name = &yytext[1];
@@ -1042,6 +1043,7 @@ RCSID "$"("Author"|"Date"|"Header"|"Id"|"Locker"|"Log"|"Name"|"RCSfile"|"Revisio
 <St_TitleN>[\-+0-9]    |
 <St_TitleN>{WORD1}     |
 <St_TitleN>{WORD2}     { /* word */
+                         if (QCString(yytext).find("\\ilinebr")!=-1) REJECT; // see issue #8311
                          lineCount(yytext,yyleng);
                          if (yytext[0]=='%') // strip % if present
                            g_token->name = &yytext[1];
index c0e4712..da6364f 100644 (file)
 #include "doxygen.h"
 #include "config.h"
 
+/**
+ * Puts DOT code for drawing directory to stream and adds it to the list.
+ * @param[in,out] outStream stream to which the DOT code is written to
+ * @param[in] directory will be mapped to a node in DOT code
+ * @param[in] fillBackground if the node shall be explicitly filled
+ * @param[in,out] directoriesInGraph lists the directories which have been written to the output stream
+ */
+static void drawDirectory(FTextStream &outStream, const DirDef *const directory, const bool fillBackground,
+    QDict<DirDef> &directoriesInGraph)
+{
+  outStream << "  " << directory->getOutputFileBase() << " [shape=box "
+      "label=\"" << directory->shortName() << "\" ";
+  if (fillBackground)
+  {
+    outStream << "fillcolor=\"white\" style=\"filled\" ";
+  }
+  if (directory->isCluster())
+  {
+    outStream << "color=\"red\" ";
+  }
+  outStream << "URL=\"" << directory->getOutputFileBase() << Doxygen::htmlFileExtension << "\"];\n";
+  directoriesInGraph.insert(directory->getOutputFileBase(), directory);
+}
+
 void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
 {
   int fontSize = Config_getInt(DOT_FONTSIZE);
@@ -36,50 +60,59 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
   QDict<DirDef> dirsInGraph(257);
 
   dirsInGraph.insert(dd->getOutputFileBase(),dd);
-  if (dd->parent())
+
+  std::vector<const DirDef *> usedDirsNotDrawn;
+  for(const auto& usedDir : dd->usedDirs())
+  {
+    usedDirsNotDrawn.push_back(usedDir->dir());
+  }
+
+  const auto parent = dd->parent();
+  if (parent)
   {
     t << "  subgraph cluster" << dd->parent()->getOutputFileBase() << " {\n";
-    t << "    graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\"" 
-      << dd->parent()->shortName() 
+    t << "    graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\""
+      << dd->parent()->shortName()
       << "\" fontname=\"" << fontName << "\", fontsize=\"" << fontSize << "\", URL=\"";
     t << dd->parent()->getOutputFileBase() << Doxygen::htmlFileExtension;
     t << "\"]\n";
+
+    {
+      // draw all directories which have `dd->parent()` as parent and `dd` as dependent
+      const auto newEnd = std::remove_if(usedDirsNotDrawn.begin(), usedDirsNotDrawn.end(), [&](const DirDef *const usedDir)
+      {
+        if (dd!=usedDir && dd->parent()==usedDir->parent())
+        {
+          drawDirectory(t, usedDir, usedDir->isCluster() && !Config_getBool(DOT_TRANSPARENT), dirsInGraph);
+          return true;
+        }
+        return false;
+      }
+      );
+      usedDirsNotDrawn.erase(newEnd, usedDirsNotDrawn.end());
+    }
   }
   if (dd->isCluster())
   {
     t << "  subgraph cluster" << dd->getOutputFileBase() << " {\n";
     t << "    graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\""
-      << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension 
+      << " URL=\"" << dd->getOutputFileBase() << Doxygen::htmlFileExtension
       << "\"];\n";
-    t << "    " << dd->getOutputFileBase() << " [shape=plaintext label=\"" 
+    t << "    " << dd->getOutputFileBase() << " [shape=plaintext label=\""
       << dd->shortName() << "\"];\n";
 
     // add nodes for sub directories
     for(const auto sdir : dd->subDirs())
     {
-      t << "    " << sdir->getOutputFileBase() << " [shape=box label=\""
-        << sdir->shortName() << "\"";
-      if (sdir->isCluster())
-      {
-        t << " color=\"red\"";
-      }
-      else
-      {
-        t << " color=\"black\"";
-      }
-      t << " fillcolor=\"white\" style=\"filled\"";
-      t << " URL=\"" << sdir->getOutputFileBase()
-        << Doxygen::htmlFileExtension << "\"";
-      t << "];\n";
-      dirsInGraph.insert(sdir->getOutputFileBase(),sdir);
+      drawDirectory(t, sdir, true, dirsInGraph);
     }
     t << "  }\n";
   }
   else
   {
-    t << "  " << dd->getOutputFileBase() << " [shape=box, label=\"" 
+    t << "  " << dd->getOutputFileBase() << " [shape=box, label=\""
       << dd->shortName() << "\", style=\"filled\", fillcolor=\"#eeeeff\","
-      << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase() 
+      << " pencolor=\"black\", URL=\"" << dd->getOutputFileBase()
       << Doxygen::htmlFileExtension << "\"];\n";
   }
   if (dd->parent())
@@ -89,13 +122,10 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
 
   // add nodes for other used directories
   {
-    QDictIterator<UsedDir> udi(*dd->usedDirs());
-    UsedDir *udir;
     //printf("*** For dir %s\n",shortName().data());
-    for (udi.toFirst();(udir=udi.current());++udi) 
+    for (const auto &usedDir : usedDirsNotDrawn)
       // for each used dir (=directly used or a parent of a directly used dir)
     {
-      const DirDef *usedDir=udir->dir();
       const DirDef *dir=dd;
       while (dir)
       {
@@ -106,23 +136,10 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
         //    shortName().data(),
         //    !usedDir->isParentOf(this)
         //    );
-        if (dir!=usedDir && dir->parent()==usedDir->parent() && 
-            !usedDir->isParentOf(dd))
+        if (dir!=usedDir && dir->parent()==usedDir->parent())
           // include if both have the same parent (or no parent)
         {
-          t << "  " << usedDir->getOutputFileBase() << " [shape=box label=\"" 
-            << usedDir->shortName() << "\"";
-          if (usedDir->isCluster())
-          {
-            if (!Config_getBool(DOT_TRANSPARENT))
-            {
-              t << " fillcolor=\"white\" style=\"filled\"";
-            }
-            t << " color=\"red\"";
-          }
-          t << " URL=\"" << usedDir->getOutputFileBase() 
-            << Doxygen::htmlFileExtension << "\"];\n";
-          dirsInGraph.insert(usedDir->getOutputFileBase(),usedDir);
+          drawDirectory(t, usedDir, usedDir->isCluster() && !Config_getBool(DOT_TRANSPARENT), dirsInGraph);
           break;
         }
         dir=dir->parent();
@@ -135,9 +152,7 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
   QDictIterator<DirDef> di(dirsInGraph);
   for (;(dir=di.current());++di) // foreach dir in the graph
   {
-    QDictIterator<UsedDir> udi(*dir->usedDirs());
-    UsedDir *udir;
-    for (udi.toFirst();(udir=udi.current());++udi) // foreach used dir
+    for (const auto &udir : dir->usedDirs())
     {
       const DirDef *usedDir=udir->dir();
       if ((dir!=dd || !udir->inherited()) &&     // only show direct dependencies for this dir
@@ -147,12 +162,9 @@ void writeDotDirDepGraph(FTextStream &t,const DirDef *dd,bool linkRelations)
       {
         QCString relationName;
         relationName.sprintf("dir_%06d_%06d",dir->dirCount(),usedDir->dirCount());
-        if (Doxygen::dirRelations.find(relationName)==0)
-        {
-          // new relation
-          Doxygen::dirRelations.append(relationName,
-            new DirRelation(relationName,dir,udir));
-        }
+        Doxygen::dirRelations.add(relationName,
+            std::make_unique<DirRelation>(
+               relationName,dir,udir.get()));
         int nrefs = udir->filePairs().count();
         t << "  " << dir->getOutputFileBase() << "->"
           << usedDir->getOutputFileBase();
index 655a0e8..1b632ce 100644 (file)
@@ -60,46 +60,35 @@ void DotGroupCollaboration::buildGraph(const GroupDef* gd)
   // hierarchy.
 
   // Write parents
-  const GroupList *groups = gd->partOfGroups();
-  if ( groups )
+  for (const auto &d : gd->partOfGroups())
   {
-    GroupListIterator gli(*groups);
-    const GroupDef *d;
-    for (gli.toFirst();(d=gli.current());++gli)
-    {
-      DotNode* nnode = m_usedNodes->find(d->name());
-      if ( !nnode )
-      { // add node
-        tmp_url = d->getReference()+"$"+d->getOutputFileBase();
-        QCString tooltip = d->briefDescriptionAsTooltip();
-        nnode = new DotNode(getNextNodeNumber(), d->groupTitle(), tooltip, tmp_url );
-        nnode->markAsVisible();
-        m_usedNodes->insert(d->name(), nnode );
-      }
-      tmp_url = "";
-      addEdge( nnode, m_rootNode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url );
+    DotNode* nnode = m_usedNodes->find(d->name());
+    if ( !nnode )
+    { // add node
+      tmp_url = d->getReference()+"$"+d->getOutputFileBase();
+      QCString tooltip = d->briefDescriptionAsTooltip();
+      nnode = new DotNode(getNextNodeNumber(), d->groupTitle(), tooltip, tmp_url );
+      nnode->markAsVisible();
+      m_usedNodes->insert(d->name(), nnode );
     }
+    tmp_url = "";
+    addEdge( nnode, m_rootNode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url );
   }
 
   // Add subgroups
-  if ( gd->getSubGroups() && gd->getSubGroups()->count() )
+  for (const auto &def : gd->getSubGroups())
   {
-    QListIterator<GroupDef> defli(*gd->getSubGroups());
-    const GroupDef *def;
-    for (;(def=defli.current());++defli)
-    {
-      DotNode* nnode = m_usedNodes->find(def->name());
-      if ( !nnode )
-      { // add node
-        tmp_url = def->getReference()+"$"+def->getOutputFileBase();
-        QCString tooltip = def->briefDescriptionAsTooltip();
-        nnode = new DotNode(getNextNodeNumber(), def->groupTitle(), tooltip, tmp_url );
-        nnode->markAsVisible();
-        m_usedNodes->insert(def->name(), nnode );
-      }
-      tmp_url = "";
-      addEdge( m_rootNode, nnode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url );
+    DotNode* nnode = m_usedNodes->find(def->name());
+    if ( !nnode )
+    { // add node
+      tmp_url = def->getReference()+"$"+def->getOutputFileBase();
+      QCString tooltip = def->briefDescriptionAsTooltip();
+      nnode = new DotNode(getNextNodeNumber(), def->groupTitle(), tooltip, tmp_url );
+      nnode->markAsVisible();
+      m_usedNodes->insert(def->name(), nnode );
     }
+    tmp_url = "";
+    addEdge( m_rootNode, nnode, DotGroupCollaboration::thierarchy, tmp_url, tmp_url );
   }
 
   //=======================
@@ -139,15 +128,10 @@ void DotGroupCollaboration::buildGraph(const GroupDef* gd)
   }
 
   // Add pages
-  if ( gd->getPages() && gd->getPages()->count() )
+  for (const auto &def : gd->getPages())
   {
-    PageSDict::Iterator defli(*gd->getPages());
-    PageDef *def;
-    for (;(def=defli.current());++defli)
-    {
-      tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension;
-      addCollaborationMember( def, tmp_url, DotGroupCollaboration::tpages );
-    }
+    tmp_url = def->getReference()+"$"+def->getOutputFileBase()+Doxygen::htmlFileExtension;
+    addCollaborationMember( def, tmp_url, DotGroupCollaboration::tpages );
   }
 
   // Add directories
@@ -209,12 +193,8 @@ void DotGroupCollaboration::addCollaborationMember(
   const Definition* def, QCString& url, EdgeType eType )
 {
   // Create group nodes
-  if ( !def->partOfGroups() )
-    return;
-  GroupListIterator gli(*def->partOfGroups());
-  GroupDef *d;
   QCString tmp_str;
-  for (;(d=gli.current());++gli)
+  for (const auto &d : def->partOfGroups())
   {
     DotNode* nnode = m_usedNodes->find(d->name());
     if ( nnode != m_rootNode )
index 86f99a2..06de5f4 100644 (file)
@@ -119,7 +119,7 @@ static UmlDetailLevel getUmlDetailLevelFromConfig()
     result=UmlDetailLevel::None;
   }
   return result;
-} 
+}
 
 static QCString escapeTooltip(const QCString &tooltip)
 {
@@ -197,17 +197,11 @@ static void writeBoxMemberList(FTextStream &t,
       }
     }
     // write member groups within the memberlist
-    MemberGroupList *mgl = ml->getMemberGroupList();
-    if (mgl)
+    for (const auto &mg : ml->getMemberGroupList())
     {
-      MemberGroupListIterator mgli(*mgl);
-      MemberGroup *mg;
-      for (mgli.toFirst();(mg=mgli.current());++mgli)
+      if (mg->members())
       {
-        if (mg->members())
-        {
-          writeBoxMemberList(t,prot,mg->members(),scope,isStatic,skipNames);
-        }
+        writeBoxMemberList(t,prot,mg->members(),scope,isStatic,skipNames);
       }
     }
   }
@@ -483,12 +477,9 @@ void DotNode::writeBox(FTextStream &t,
         writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priStaticMethods),m_classDef,TRUE);
         writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType_priSlots),m_classDef);
       }
-      if (m_classDef->getLanguage()!=SrcLangExt_Fortran &&
-        m_classDef->getMemberGroupSDict())
+      if (m_classDef->getLanguage()!=SrcLangExt_Fortran)
       {
-        MemberGroupSDict::Iterator mgdi(*m_classDef->getMemberGroupSDict());
-        MemberGroup *mg;
-        for (mgdi.toFirst();(mg=mgdi.current());++mgdi)
+        for (const auto &mg : m_classDef->getMemberGroups())
         {
           if (mg->members())
           {
index 3472f8f..3fdde9b 100644 (file)
@@ -123,9 +123,9 @@ NamespaceLinkedMap   *Doxygen::namespaceLinkedMap = 0;
 MemberNameLinkedMap  *Doxygen::memberNameLinkedMap = 0;
 MemberNameLinkedMap  *Doxygen::functionNameLinkedMap = 0;
 FileNameLinkedMap    *Doxygen::inputNameLinkedMap = 0;
-GroupSDict           *Doxygen::groupSDict = 0;
-PageSDict            *Doxygen::pageSDict = 0;
-PageSDict            *Doxygen::exampleSDict = 0;
+GroupLinkedMap       *Doxygen::groupLinkedMap = 0;
+PageLinkedMap        *Doxygen::pageLinkedMap = 0;
+PageLinkedMap        *Doxygen::exampleLinkedMap = 0;
 StringDict            Doxygen::aliasDict(257);          // aliases
 StringSet             Doxygen::inputPaths;
 FileNameLinkedMap    *Doxygen::includeNameLinkedMap = 0;     // include names
@@ -134,27 +134,24 @@ FileNameLinkedMap    *Doxygen::imageNameLinkedMap = 0;       // images
 FileNameLinkedMap    *Doxygen::dotFileNameLinkedMap = 0;     // dot files
 FileNameLinkedMap    *Doxygen::mscFileNameLinkedMap = 0;     // msc files
 FileNameLinkedMap    *Doxygen::diaFileNameLinkedMap = 0;     // dia files
-StringUnorderedMap    Doxygen::namespaceAliasMap;      // all namespace aliases
-StringDict            Doxygen::tagDestinationDict(257); // all tag locations
-StringUnorderedSet    Doxygen::expandAsDefinedSet; // all macros that should be expanded
-QIntDict<MemberGroupInfo> Doxygen::memGrpInfoDict(1009); // dictionary of the member groups heading
-PageDef              *Doxygen::mainPage = 0;
+StringUnorderedMap    Doxygen::namespaceAliasMap;            // all namespace aliases
+StringDict            Doxygen::tagDestinationDict(257);      // all tag locations
+StringUnorderedSet    Doxygen::expandAsDefinedSet;           // all macros that should be expanded
+MemberGroupInfoMap    Doxygen::memberGroupInfoMap;           // dictionary of the member groups heading
+std::unique_ptr<PageDef> Doxygen::mainPage;
 bool                  Doxygen::insideMainPage = FALSE; // are we generating docs for the main page?
 NamespaceDefMutable  *Doxygen::globalScope = 0;
 bool                  Doxygen::parseSourcesNeeded = FALSE;
 SearchIndexIntf      *Doxygen::searchIndex=0;
 SymbolMap<Definition> Doxygen::symbolMap;
-QDict<Definition>    *Doxygen::clangUsrMap = 0;
+ClangUsrMap          *Doxygen::clangUsrMap = 0;
 bool                  Doxygen::outputToWizard=FALSE;
-QDict<int> *          Doxygen::htmlDirMap = 0;
 Cache<std::string,LookupInfo> *Doxygen::lookupCache;
-DirSDict             *Doxygen::directories;
-SDict<DirRelation>    Doxygen::dirRelations(257);
+DirLinkedMap         *Doxygen::dirLinkedMap;
+DirRelationLinkedMap  Doxygen::dirRelations;
 ParserManager        *Doxygen::parserManager = 0;
 QCString              Doxygen::htmlFileExtension;
 bool                  Doxygen::suppressDocWarnings = FALSE;
-QCString              Doxygen::objDBFileName;
-QCString              Doxygen::entryDBFileName;
 QCString              Doxygen::filterDBFileName;
 IndexList            *Doxygen::indexList;
 int                   Doxygen::subpageNestingLevel = 0;
@@ -183,8 +180,8 @@ void clearAll()
   Doxygen::classLinkedMap->clear();
   Doxygen::hiddenClassLinkedMap->clear();
   Doxygen::namespaceLinkedMap->clear();
-  Doxygen::pageSDict->clear();
-  Doxygen::exampleSDict->clear();
+  Doxygen::pageLinkedMap->clear();
+  Doxygen::exampleLinkedMap->clear();
   Doxygen::inputNameLinkedMap->clear();
   Doxygen::includeNameLinkedMap->clear();
   Doxygen::exampleNameLinkedMap->clear();
@@ -195,7 +192,7 @@ void clearAll()
   Doxygen::tagDestinationDict.clear();
   SectionManager::instance().clear();
   CitationManager::instance().clear();
-  delete Doxygen::mainPage; Doxygen::mainPage=0;
+  Doxygen::mainPage.reset();
   FormulaManager::instance().clear();
 }
 
@@ -261,6 +258,8 @@ void statistics()
   Doxygen::mscFileNameDict->statistics();
   fprintf(stderr,"--- diaFileNameDict stats ----\n");
   Doxygen::diaFileNameDict->statistics();
+  fprintf(stderr,"--- memGrpInfoDict stats ----\n");
+  Doxygen::memGrpInfoDict.statistics();
 #endif
   //fprintf(stderr,"--- g_excludeNameDict stats ----\n");
   //g_excludeNameDict.statistics();
@@ -270,8 +269,6 @@ void statistics()
   Doxygen::tagDestinationDict.statistics();
   fprintf(stderr,"--- g_compoundKeywordDict stats ----\n");
   g_compoundKeywordDict.statistics();
-  fprintf(stderr,"--- memGrpInfoDict stats ----\n");
-  Doxygen::memGrpInfoDict.statistics();
 }
 
 
@@ -334,7 +331,7 @@ static void addRelatedPage(Entry *root)
   GroupDef *gd=0;
   for (const Grouping &g : root->groups)
   {
-    if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname))) break;
+    if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname))) break;
   }
   //printf("---> addRelatedPage() %s gd=%p\n",root->name.data(),gd);
   QCString doc;
@@ -375,7 +372,7 @@ static void buildGroupListFiltered(const Entry *root,bool additional, bool inclu
     if ((root->groupDocType==Entry::GROUPDOC_NORMAL && !additional) ||
         (root->groupDocType!=Entry::GROUPDOC_NORMAL &&  additional))
     {
-      GroupDef *gd = Doxygen::groupSDict->find(root->name);
+      GroupDef *gd = Doxygen::groupLinkedMap->find(root->name);
       //printf("Processing group '%s':'%s' add=%d ext=%d gd=%p\n",
       //    root->type.data(),root->name.data(),additional,includeExternal,gd);
 
@@ -402,19 +399,22 @@ static void buildGroupListFiltered(const Entry *root,bool additional, bool inclu
       {
         if (root->tagInfo())
         {
-          gd = createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo()->fileName);
+          gd = Doxygen::groupLinkedMap->add(root->name,
+               std::unique_ptr<GroupDef>(
+                  createGroupDef(root->fileName,root->startLine,root->name,root->type,root->tagInfo()->fileName)));
           gd->setReference(root->tagInfo()->tagName);
         }
         else
         {
-          gd = createGroupDef(root->fileName,root->startLine,root->name,root->type);
+          gd = Doxygen::groupLinkedMap->add(root->name,
+               std::unique_ptr<GroupDef>(
+                  createGroupDef(root->fileName,root->startLine,root->name,root->type)));
         }
         gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
         // allow empty docs for group
         gd->setDocumentation(!root->doc.isEmpty() ? root->doc : QCString(" "),root->docFile,root->docLine,FALSE);
         gd->setInbodyDocumentation( root->inbodyDocs, root->inbodyFile, root->inbodyLine );
         gd->addSectionsToDefinition(root->anchors);
-        Doxygen::groupSDict->append(root->name,gd);
         gd->setRefItems(root->sli);
         gd->setLanguage(root->lang);
       }
@@ -444,7 +444,7 @@ static void findGroupScope(const Entry *root)
       root->parent() && !root->parent()->name.isEmpty())
   {
     GroupDef *gd;
-    if ((gd=Doxygen::groupSDict->find(root->name)))
+    if ((gd=Doxygen::groupLinkedMap->find(root->name)))
     {
       QCString scope = root->parent()->name;
       if (root->parent()->section==Entry::PACKAGEDOC_SEC)
@@ -471,7 +471,7 @@ static void organizeSubGroupsFiltered(const Entry *root,bool additional)
         (root->groupDocType!=Entry::GROUPDOC_NORMAL && additional))
     {
       GroupDef *gd;
-      if ((gd=Doxygen::groupSDict->find(root->name)))
+      if ((gd=Doxygen::groupLinkedMap->find(root->name)))
       {
         //printf("adding %s to group %s\n",root->name.data(),gd->name().data());
         addGroupToGroups(root,gd);
@@ -526,7 +526,7 @@ static void buildFileList(const Entry *root)
       for (const Grouping &g : root->groups)
       {
         GroupDef *gd=0;
-        if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname)))
+        if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname)))
         {
           gd->addFile(fd);
           fd->makePartOfGroup(gd);
@@ -775,11 +775,13 @@ static Definition *buildScopeFromQualifiedName(const QCString name_,SrcLangExt l
                 "[generated]",1,1,fullScope,
                 tagInfo?tagInfo->tagName:QCString(),
                 tagInfo?tagInfo->fileName:QCString()))));
-      newNd->setLanguage(lang);
-      newNd->setArtificial(TRUE);
-
-      // add namespace to the list
-      innerScope = newNd;
+      if (newNd)
+      {
+        newNd->setLanguage(lang);
+        newNd->setArtificial(TRUE);
+        // add namespace to the list
+        innerScope = newNd;
+      }
     }
     else // scope is a namespace
     {
@@ -1089,62 +1091,70 @@ static void addClassToContext(const Entry *root)
           std::unique_ptr<ClassDef>(
             createClassDef(tagInfo?tagName:root->fileName,root->startLine,root->startColumn,
                fullName,sec,tagName,refFileName,TRUE,root->spec&Entry::Enum) )));
-    Debug::print(Debug::Classes,0,"  New class '%s' (sec=0x%08x)! #tArgLists=%d tagInfo=%p hidden=%d artificial=%d\n",
-        qPrint(fullName),sec,root->tArgLists.size(), tagInfo,root->hidden,root->artificial);
-    cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
-    cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
-    cd->setLanguage(root->lang);
-    cd->setId(root->id);
-    cd->setHidden(root->hidden);
-    cd->setArtificial(root->artificial);
-    cd->setClassSpecifier(root->spec);
-    cd->setTypeConstraints(root->typeConstr);
-    //printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data());
-
-    //printf("class %s template args=%s\n",fullName.data(),
-    //    tArgList ? tempArgListToString(tArgList,root->lang).data() : "<none>");
-    if (tArgList)
+    if (cd)
     {
-      cd->setTemplateArguments(*tArgList);
-    }
-    cd->setProtection(root->protection);
-    cd->setIsStatic(root->stat);
-
-    // file definition containing the class cd
-    cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
-    cd->setBodyDef(fd);
-
-    cd->setMetaData(root->metaData);
+      Debug::print(Debug::Classes,0,"  New class '%s' (sec=0x%08x)! #tArgLists=%d tagInfo=%p hidden=%d artificial=%d\n",
+          qPrint(fullName),sec,root->tArgLists.size(), tagInfo,root->hidden,root->artificial);
+      cd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
+      cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+      cd->setLanguage(root->lang);
+      cd->setId(root->id);
+      cd->setHidden(root->hidden);
+      cd->setArtificial(root->artificial);
+      cd->setClassSpecifier(root->spec);
+      cd->setTypeConstraints(root->typeConstr);
+      //printf("new ClassDef %s tempArgList=%p specScope=%s\n",fullName.data(),root->tArgList,root->scopeSpec.data());
+
+      //printf("class %s template args=%s\n",fullName.data(),
+      //    tArgList ? tempArgListToString(tArgList,root->lang).data() : "<none>");
+      if (tArgList)
+      {
+        cd->setTemplateArguments(*tArgList);
+      }
+      cd->setProtection(root->protection);
+      cd->setIsStatic(root->stat);
 
-    // see if the class is found inside a namespace
-    //bool found=addNamespace(root,cd);
+      // file definition containing the class cd
+      cd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
+      cd->setBodyDef(fd);
 
-    cd->insertUsedFile(fd);
+      cd->setMetaData(root->metaData);
 
+      // see if the class is found inside a namespace
+      //bool found=addNamespace(root,cd);
 
+      cd->insertUsedFile(fd);
+    }
+    else
+    {
+      Debug::print(Debug::Classes,0,"  Not added class '%s', already exists as alias\n", qPrint(fullName));
+    }
   }
 
-  cd->addSectionsToDefinition(root->anchors);
-  if (!root->subGrouping) cd->setSubGrouping(FALSE);
-  if ((root->spec&Entry::ForwardDecl)==0)
+  if (cd)
   {
-    if (cd->hasDocumentation())
+    cd->addSectionsToDefinition(root->anchors);
+    if (!root->subGrouping) cd->setSubGrouping(FALSE);
+    if ((root->spec&Entry::ForwardDecl)==0)
     {
-      addIncludeFile(cd,fd,root);
-    }
-    if (fd && (root->section & Entry::COMPOUND_MASK))
-    {
-      //printf(">> Inserting class '%s' in file '%s' (root->fileName='%s')\n",
-      //    cd->name().data(),
-      //    fd->name().data(),
-      //    root->fileName.data()
-      //   );
-      cd->setFileDef(fd);
-      fd->insertClass(cd);
+      if (cd->hasDocumentation())
+      {
+        addIncludeFile(cd,fd,root);
+      }
+      if (fd && (root->section & Entry::COMPOUND_MASK))
+      {
+        //printf(">> Inserting class '%s' in file '%s' (root->fileName='%s')\n",
+        //    cd->name().data(),
+        //    fd->name().data(),
+        //    root->fileName.data()
+        //   );
+        cd->setFileDef(fd);
+        fd->insertClass(cd);
+      }
     }
+    addClassToGroups(root,cd);
+    cd->setRefItems(root->sli);
   }
-  addClassToGroups(root,cd);
-  cd->setRefItems(root->sli);
 }
 
 //----------------------------------------------------------------------
@@ -1185,10 +1195,11 @@ static void resolveClassNestingRelations()
     ++iteration;
     struct ClassAlias
     {
-      ClassAlias(const QCString &name,std::unique_ptr<ClassDef> cd) :
-        aliasFullName(name),aliasCd(std::move(cd)) {}
+      ClassAlias(const QCString &name,std::unique_ptr<ClassDef> cd,DefinitionMutable *ctx) :
+        aliasFullName(name),aliasCd(std::move(cd)), aliasContext(ctx) {}
       const QCString aliasFullName;
       std::unique_ptr<ClassDef> aliasCd;
+      DefinitionMutable *aliasContext;
     };
     std::vector<ClassAlias> aliases;
     for (const auto &icd : *Doxygen::classLinkedMap)
@@ -1225,9 +1236,8 @@ static void resolveClassNestingRelations()
                 if (dm)
                 {
                   std::unique_ptr<ClassDef> aliasCd { createClassDefAlias(d,cd) };
-                  dm->addInnerCompound(aliasCd.get());
                   QCString aliasFullName = d->qualifiedName()+"::"+aliasCd->localName();
-                  aliases.push_back(ClassAlias(aliasFullName,std::move(aliasCd)));
+                  aliases.push_back(ClassAlias(aliasFullName,std::move(aliasCd),dm));
                   //printf("adding %s to %s as %s\n",qPrint(aliasCd->name()),qPrint(d->name()),qPrint(aliasFullName));
                 }
               }
@@ -1250,7 +1260,11 @@ static void resolveClassNestingRelations()
     // add aliases
     for (auto &alias : aliases)
     {
-       Doxygen::classLinkedMap->add(alias.aliasFullName,std::move(alias.aliasCd));
+       ClassDef *aliasCd = Doxygen::classLinkedMap->add(alias.aliasFullName,std::move(alias.aliasCd));
+       if (aliasCd)
+       {
+         alias.aliasContext->addInnerCompound(aliasCd);
+       }
     }
   }
 
@@ -1296,19 +1310,19 @@ void distributeClassGroupRelations()
   {
     //printf("Checking %s\n",cd->name().data());
     // distribute the group to nested classes as well
-    if (visitedClasses.find(cd.get())==visitedClasses.end() && cd->partOfGroups()!=0)
+    if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->partOfGroups().empty())
     {
       //printf("  Candidate for merging\n");
-      GroupDef *gd = cd->partOfGroups()->at(0);
+      const GroupDef *gd = cd->partOfGroups().front();
       for (const auto &ncd : cd->getClasses())
       {
         ClassDefMutable *ncdm = toClassDefMutable(ncd);
-        if (ncdm && ncdm->partOfGroups()==0)
+        if (ncdm && ncdm->partOfGroups().empty())
         {
           //printf("  Adding %s to group '%s'\n",ncd->name().data(),
           //    gd->groupTitle());
           ncdm->makePartOfGroup(gd);
-          gd->addClass(ncdm);
+          const_cast<GroupDef*>(gd)->addClass(ncdm);
         }
       }
       visitedClasses.insert(cd.get()); // only visit every class once
@@ -1333,64 +1347,61 @@ static ClassDefMutable *createTagLessInstance(const ClassDef *rootCd,const Class
                               templ->getDefColumn(),
                               fullName,
                               templ->compoundType()))));
-  cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
-  cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
-  cd->setLanguage(templ->getLanguage());
-  cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine());
-  cd->setBodyDef(templ->getBodyDef());
-
-  cd->setOuterScope(rootCd->getOuterScope());
-  if (rootCd->getOuterScope()!=Doxygen::globalScope)
+  if (cd)
   {
-    DefinitionMutable *outerScope = toDefinitionMutable(rootCd->getOuterScope());
-    if (outerScope)
+    cd->setDocumentation(templ->documentation(),templ->docFile(),templ->docLine()); // copy docs to definition
+    cd->setBriefDescription(templ->briefDescription(),templ->briefFile(),templ->briefLine());
+    cd->setLanguage(templ->getLanguage());
+    cd->setBodySegment(templ->getDefLine(),templ->getStartBodyLine(),templ->getEndBodyLine());
+    cd->setBodyDef(templ->getBodyDef());
+
+    cd->setOuterScope(rootCd->getOuterScope());
+    if (rootCd->getOuterScope()!=Doxygen::globalScope)
     {
-      outerScope->addInnerCompound(cd);
+      DefinitionMutable *outerScope = toDefinitionMutable(rootCd->getOuterScope());
+      if (outerScope)
+      {
+        outerScope->addInnerCompound(cd);
+      }
     }
-  }
 
-  FileDef *fd = templ->getFileDef();
-  if (fd)
-  {
-    cd->setFileDef(fd);
-    fd->insertClass(cd);
-  }
-  GroupList *groups = rootCd->partOfGroups();
-  if ( groups!=0 )
-  {
-    GroupListIterator gli(*groups);
-    GroupDef *gd;
-    for (gli.toFirst();(gd=gli.current());++gli)
+    FileDef *fd = templ->getFileDef();
+    if (fd)
+    {
+      cd->setFileDef(fd);
+      fd->insertClass(cd);
+    }
+    for (const auto &gd : rootCd->partOfGroups())
     {
       cd->makePartOfGroup(gd);
-      gd->addClass(cd);
+      const_cast<GroupDef*>(gd)->addClass(cd);
     }
-  }
 
-  MemberList *ml = templ->getMemberList(MemberListType_pubAttribs);
-  if (ml)
-  {
-    MemberListIterator li(*ml);
-    MemberDef *md;
-    for (li.toFirst();(md=li.current());++li)
+    MemberList *ml = templ->getMemberList(MemberListType_pubAttribs);
+    if (ml)
     {
-      //printf("    Member %s type=%s\n",md->name().data(),md->typeString());
-      MemberDefMutable *imd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
-                                     md->typeString(),md->name(),md->argsString(),md->excpString(),
-                                     md->protection(),md->virtualness(),md->isStatic(),Member,
-                                     md->memberType(),
-                                     ArgumentList(),ArgumentList(),"");
-      imd->setMemberClass(cd);
-      imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
-      imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
-      imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
-      imd->setMemberSpecifiers(md->getMemberSpecifiers());
-      imd->setMemberGroupId(md->getMemberGroupId());
-      imd->setInitializer(md->initializer());
-      imd->setMaxInitLines(md->initializerLines());
-      imd->setBitfields(md->bitfieldString());
-      imd->setLanguage(md->getLanguage());
-      cd->insertMember(imd);
+      MemberListIterator li(*ml);
+      MemberDef *md;
+      for (li.toFirst();(md=li.current());++li)
+      {
+        //printf("    Member %s type=%s\n",md->name().data(),md->typeString());
+        MemberDefMutable *imd = createMemberDef(md->getDefFileName(),md->getDefLine(),md->getDefColumn(),
+            md->typeString(),md->name(),md->argsString(),md->excpString(),
+            md->protection(),md->virtualness(),md->isStatic(),Member,
+            md->memberType(),
+            ArgumentList(),ArgumentList(),"");
+        imd->setMemberClass(cd);
+        imd->setDocumentation(md->documentation(),md->docFile(),md->docLine());
+        imd->setBriefDescription(md->briefDescription(),md->briefFile(),md->briefLine());
+        imd->setInbodyDocumentation(md->inbodyDocumentation(),md->inbodyFile(),md->inbodyLine());
+        imd->setMemberSpecifiers(md->getMemberSpecifiers());
+        imd->setMemberGroupId(md->getMemberGroupId());
+        imd->setInitializer(md->initializer());
+        imd->setMaxInitLines(md->initializerLines());
+        imd->setBitfields(md->bitfieldString());
+        imd->setLanguage(md->getLanguage());
+        cd->insertMember(imd);
+      }
     }
   }
   return cd;
@@ -1435,29 +1446,32 @@ static void processTagLessClasses(const ClassDef *rootCd,
               if (!prefix.isEmpty()) name.prepend(prefix+".");
               //printf("    found %s for class %s\n",name.data(),cd->name().data());
               ClassDefMutable *ncd = createTagLessInstance(rootCd,icd,name);
-              processTagLessClasses(rootCd,icd,ncd,name,count+1);
-              //printf("    addTagged %s to %s\n",ncd->name().data(),tagParentCd->name().data());
-              ncd->setTagLessReference(icd);
-
-              // replace tag-less type for generated/original member
-              // by newly created class name.
-              // note the difference between changing cd and tagParentCd.
-              // for the initial call this is the same pointer, but for
-              // recursive calls cd is the original tag-less struct (of which
-              // there is only one instance) and tagParentCd is the newly
-              // generated tagged struct of which there can be multiple instances!
-              MemberList *pml = tagParentCd->getMemberList(MemberListType_pubAttribs);
-              if (pml)
+              if (ncd)
               {
-                MemberListIterator pli(*pml);
-                MemberDef *pmd;
-                for (pli.toFirst();(pmd=pli.current());++pli)
+                processTagLessClasses(rootCd,icd,ncd,name,count+1);
+                //printf("    addTagged %s to %s\n",ncd->name().data(),tagParentCd->name().data());
+                ncd->setTagLessReference(icd);
+
+                // replace tag-less type for generated/original member
+                // by newly created class name.
+                // note the difference between changing cd and tagParentCd.
+                // for the initial call this is the same pointer, but for
+                // recursive calls cd is the original tag-less struct (of which
+                // there is only one instance) and tagParentCd is the newly
+                // generated tagged struct of which there can be multiple instances!
+                MemberList *pml = tagParentCd->getMemberList(MemberListType_pubAttribs);
+                if (pml)
                 {
-                  MemberDefMutable *pmdm = toMemberDefMutable(pmd);
-                  if (pmdm && pmd->name()==md->name())
+                  MemberListIterator pli(*pml);
+                  MemberDef *pmd;
+                  for (pli.toFirst();(pmd=pli.current());++pli)
                   {
-                    pmdm->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name()));
-                    //pmd->setType(substitute(pmd->typeString(),icd->name(),ncd->name()));
+                    MemberDefMutable *pmdm = toMemberDefMutable(pmd);
+                    if (pmdm && pmd->name()==md->name())
+                    {
+                      pmdm->setAccessorType(ncd,substitute(pmd->typeString(),icd->name(),ncd->name()));
+                      //pmd->setType(substitute(pmd->typeString(),icd->name(),ncd->name()));
+                    }
                   }
                 }
               }
@@ -1469,29 +1483,41 @@ static void processTagLessClasses(const ClassDef *rootCd,
   }
 }
 
-static void findTagLessClasses(const ClassDef *cd)
+static void findTagLessClasses(std::vector<ClassDefMutable*> &candidates,const ClassDef *cd)
 {
   for (const auto &icd : cd->getClasses())
   {
     if (icd->name().find("@")==-1) // process all non-anonymous inner classes
     {
-      findTagLessClasses(icd);
+      findTagLessClasses(candidates,icd);
     }
   }
 
-  processTagLessClasses(cd,cd,toClassDefMutable(cd),"",0); // process tag less inner struct/classes (if any)
+  ClassDefMutable *cdm = toClassDefMutable(cd);
+  if (cdm)
+  {
+    candidates.push_back(cdm);
+  }
 }
 
 static void findTagLessClasses()
 {
+  std::vector<ClassDefMutable *> candidates;
   for (const auto &cd : *Doxygen::classLinkedMap)
   {
     Definition *scope = cd->getOuterScope();
     if (scope && scope->definitionType()!=Definition::TypeClass) // that is not nested
     {
-      findTagLessClasses(cd.get());
+      findTagLessClasses(candidates,cd.get());
     }
   }
+
+  // since processTagLessClasses is potentially adding classes to Doxygen::classLinkedMap
+  // we need to call it outside of the loop above, otherwise the iterator gets invalidated!
+  for (auto &cd : candidates)
+  {
+    processTagLessClasses(cd,cd,cd,"",0); // process tag less inner struct/classes
+  }
 }
 
 
@@ -1521,32 +1547,36 @@ static void buildNamespaceList(const Entry *root)
     {
       //printf("Found namespace %s in %s at line %d\n",root->name.data(),
       //        root->fileName.data(), root->startLine);
-      NamespaceDefMutable *nd;
-      if ((nd=toNamespaceDefMutable(Doxygen::namespaceLinkedMap->find(fullName)))) // existing namespace
+      NamespaceDef *ndi = Doxygen::namespaceLinkedMap->find(fullName);
+      if (ndi) // existing namespace
       {
-        nd->setDocumentation(root->doc,root->docFile,root->docLine);
-        nd->setName(fullName); // change name to match docs
-        nd->addSectionsToDefinition(root->anchors);
-        nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
-        if (nd->getLanguage()==SrcLangExt_Unknown)
-        {
-          nd->setLanguage(root->lang);
-        }
-        if (root->tagInfo()==0) // if we found the namespace in a tag file
-                                   // and also in a project file, then remove
-                                   // the tag file reference
+        NamespaceDefMutable *nd = toNamespaceDefMutable(ndi);
+        if (nd) // non-inline namespace
         {
-          nd->setReference("");
-          nd->setFileName(fullName);
-        }
-        nd->setMetaData(root->metaData);
+          nd->setDocumentation(root->doc,root->docFile,root->docLine);
+          nd->setName(fullName); // change name to match docs
+          nd->addSectionsToDefinition(root->anchors);
+          nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+          if (nd->getLanguage()==SrcLangExt_Unknown)
+          {
+            nd->setLanguage(root->lang);
+          }
+          if (root->tagInfo()==0) // if we found the namespace in a tag file
+            // and also in a project file, then remove
+            // the tag file reference
+          {
+            nd->setReference("");
+            nd->setFileName(fullName);
+          }
+          nd->setMetaData(root->metaData);
 
-        // file definition containing the namespace nd
-        FileDef *fd=root->fileDef();
-        // insert the namespace in the file definition
-        if (fd) fd->insertNamespace(nd);
-        addNamespaceToGroups(root,nd);
-        nd->setRefItems(root->sli);
+          // file definition containing the namespace nd
+          FileDef *fd=root->fileDef();
+          // insert the namespace in the file definition
+          if (fd) fd->insertNamespace(nd);
+          addNamespaceToGroups(root,nd);
+          nd->setRefItems(root->sli);
+        }
       }
       else // fresh namespace
       {
@@ -1560,85 +1590,92 @@ static void buildNamespaceList(const Entry *root)
         }
         //printf("++ new namespace %s lang=%s tagName=%s\n",fullName.data(),langToString(root->lang).data(),tagName.data());
         // add namespace to the list
-        nd = toNamespaceDefMutable(
+        NamespaceDefMutable *nd = toNamespaceDefMutable(
             Doxygen::namespaceLinkedMap->add(fullName,
               std::unique_ptr<NamespaceDef>(
                 createNamespaceDef(tagInfo?tagName:root->fileName,root->startLine,
-                             root->startColumn,fullName,tagName,tagFileName,
-                             root->type,root->spec&Entry::Published))));
-        nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
-        nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
-        nd->addSectionsToDefinition(root->anchors);
-        nd->setHidden(root->hidden);
-        nd->setArtificial(root->artificial);
-        nd->setLanguage(root->lang);
-        nd->setId(root->id);
-        nd->setMetaData(root->metaData);
-        nd->setInline((root->spec&Entry::Inline)!=0);
-
-        //printf("Adding namespace to group\n");
-        addNamespaceToGroups(root,nd);
-        nd->setRefItems(root->sli);
-
-        // file definition containing the namespace nd
-        FileDef *fd=root->fileDef();
-        // insert the namespace in the file definition
-        if (fd) fd->insertNamespace(nd);
-
-        // the empty string test is needed for extract all case
-        nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
-        nd->insertUsedFile(fd);
-        nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
-        nd->setBodyDef(fd);
-
-        // also add namespace to the correct structural context
-        Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,0,tagInfo);
-        //printf("adding namespace %s to context %s\n",nd->name().data(),d?d->name().data():"<none>");
-        if (d==0) // we didn't find anything, create the scope artificially
-                  // anyway, so we can at least relate scopes properly.
-        {
-          d = buildScopeFromQualifiedName(fullName,nd->getLanguage(),tagInfo);
-          DefinitionMutable *dm = toDefinitionMutable(d);
-          if (dm)
-          {
-            dm->addInnerCompound(nd);
-          }
-          nd->setOuterScope(d);
-          // TODO: Due to the order in which the tag file is written
-          // a nested class can be found before its parent!
-        }
-        else
+                  root->startColumn,fullName,tagName,tagFileName,
+                  root->type,root->spec&Entry::Published))));
+        if (nd)
         {
-          DefinitionMutable *dm = toDefinitionMutable(d);
-          if (dm)
+          nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
+          nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+          nd->addSectionsToDefinition(root->anchors);
+          nd->setHidden(root->hidden);
+          nd->setArtificial(root->artificial);
+          nd->setLanguage(root->lang);
+          nd->setId(root->id);
+          nd->setMetaData(root->metaData);
+          nd->setInline((root->spec&Entry::Inline)!=0);
+
+          //printf("Adding namespace to group\n");
+          addNamespaceToGroups(root,nd);
+          nd->setRefItems(root->sli);
+
+          // file definition containing the namespace nd
+          FileDef *fd=root->fileDef();
+          // insert the namespace in the file definition
+          if (fd) fd->insertNamespace(nd);
+
+          // the empty string test is needed for extract all case
+          nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+          nd->insertUsedFile(fd);
+          nd->setBodySegment(root->startLine,root->bodyLine,root->endBodyLine);
+          nd->setBodyDef(fd);
+
+          // also add namespace to the correct structural context
+          Definition *d = findScopeFromQualifiedName(Doxygen::globalScope,fullName,0,tagInfo);
+          //printf("adding namespace %s to context %s\n",nd->name().data(),d?d->name().data():"<none>");
+          if (d==0) // we didn't find anything, create the scope artificially
+            // anyway, so we can at least relate scopes properly.
           {
-            dm->addInnerCompound(nd);
+            d = buildScopeFromQualifiedName(fullName,nd->getLanguage(),tagInfo);
+            DefinitionMutable *dm = toDefinitionMutable(d);
+            if (dm)
+            {
+              dm->addInnerCompound(nd);
+            }
+            nd->setOuterScope(d);
+            // TODO: Due to the order in which the tag file is written
+            // a nested class can be found before its parent!
           }
-          nd->setOuterScope(d);
-          // in case of d is an inline namespace, alias insert nd in the part scope of d.
-          while (d->definitionType()==Definition::TypeNamespace)
+          else
           {
-            NamespaceDef *pnd = toNamespaceDef(d);
-            if (pnd && pnd->isInline())
+            DefinitionMutable *dm = toDefinitionMutable(d);
+            if (dm)
             {
-              d = d->getOuterScope();
-              if (d)
+              dm->addInnerCompound(nd);
+            }
+            nd->setOuterScope(d);
+            // in case of d is an inline namespace, alias insert nd in the part scope of d.
+            while (d->definitionType()==Definition::TypeNamespace)
+            {
+              NamespaceDef *pnd = toNamespaceDef(d);
+              if (pnd && pnd->isInline())
               {
-                dm = toDefinitionMutable(d);
-                if (dm)
+                d = d->getOuterScope();
+                if (d)
+                {
+                  dm = toDefinitionMutable(d);
+                  if (dm)
+                  {
+                    NamespaceDef *aliasNd = createNamespaceDefAlias(d,nd);
+                    dm->addInnerCompound(aliasNd);
+                    QCString aliasName = aliasNd->name();
+                    //printf("adding alias %s (%p) to %s\n",qPrint(aliasName),aliasNd,qPrint(d->name()));
+                    Doxygen::namespaceLinkedMap->add(
+                        aliasName,std::unique_ptr<NamespaceDef>(aliasNd));
+                  }
+                }
+                else
                 {
-                  NamespaceDef *aliasNd = createNamespaceDefAlias(d,nd);
-                  //printf("adding %s to %s\n",qPrint(aliasNd->name()),qPrint(d->name()));
-                  dm->addInnerCompound(aliasNd);
-                  QCString aliasName = aliasNd->name();
-                  Doxygen::namespaceLinkedMap->add(
-                      aliasName,std::unique_ptr<NamespaceDef>(aliasNd));
+                  break;
                 }
               }
-            }
-            else
-            {
-              break;
+              else
+              {
+                break;
+              }
             }
           }
         }
@@ -1767,38 +1804,41 @@ static void findUsingDirectives(const Entry *root)
             Doxygen::namespaceLinkedMap->add(name,
               std::unique_ptr<NamespaceDef>(
                  createNamespaceDef(root->fileName,root->startLine,root->startColumn,name))));
-        nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
-        nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
-        nd->addSectionsToDefinition(root->anchors);
-        //printf("** Adding namespace %s hidden=%d\n",name.data(),root->hidden);
-        nd->setHidden(root->hidden);
-        nd->setArtificial(TRUE);
-        nd->setLanguage(root->lang);
-        nd->setId(root->id);
-        nd->setMetaData(root->metaData);
-        nd->setInline((root->spec&Entry::Inline)!=0);
-
-        //QListIterator<Grouping> gli(*root->groups);
-        //Grouping *g;
-        //for (;(g=gli.current());++gli)
-        for (const Grouping &g : root->groups)
-        {
-          GroupDef *gd=0;
-          if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname)))
-            gd->addNamespace(nd);
-        }
-
-        // insert the namespace in the file definition
-        if (fd)
+        if (nd)
         {
-          fd->insertNamespace(nd);
-          fd->addUsingDirective(nd);
-        }
+          nd->setDocumentation(root->doc,root->docFile,root->docLine); // copy docs to definition
+          nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+          nd->addSectionsToDefinition(root->anchors);
+          //printf("** Adding namespace %s hidden=%d\n",name.data(),root->hidden);
+          nd->setHidden(root->hidden);
+          nd->setArtificial(TRUE);
+          nd->setLanguage(root->lang);
+          nd->setId(root->id);
+          nd->setMetaData(root->metaData);
+          nd->setInline((root->spec&Entry::Inline)!=0);
+
+          //QListIterator<Grouping> gli(*root->groups);
+          //Grouping *g;
+          //for (;(g=gli.current());++gli)
+          for (const Grouping &g : root->groups)
+          {
+            GroupDef *gd=0;
+            if (!g.groupname.isEmpty() && (gd=Doxygen::groupLinkedMap->find(g.groupname)))
+              gd->addNamespace(nd);
+          }
+
+          // insert the namespace in the file definition
+          if (fd)
+          {
+            fd->insertNamespace(nd);
+            fd->addUsingDirective(nd);
+          }
 
-        // the empty string test is needed for extract all case
-        nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
-        nd->insertUsedFile(fd);
-        nd->setRefItems(root->sli);
+          // the empty string test is needed for extract all case
+          nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
+          nd->insertUsedFile(fd);
+          nd->setRefItems(root->sli);
+        }
       }
     }
   }
@@ -1884,8 +1924,11 @@ static void findUsingDeclarations(const Entry *root)
              Doxygen::hiddenClassLinkedMap->add(name,
                std::unique_ptr<ClassDef>(
                  createClassDef( "<using>",1,1, name, ClassDef::Class))));
-        usingCd->setArtificial(TRUE);
-        usingCd->setLanguage(root->lang);
+        if (usingCd)
+        {
+          usingCd->setArtificial(TRUE);
+          usingCd->setLanguage(root->lang);
+        }
       }
       else
       {
@@ -3471,7 +3514,7 @@ static void buildFunctionList(const Entry *root)
                 GroupDef *gd=0;
                 if (!root->groups.empty() && !root->groups.front().groupname.isEmpty())
                 {
-                  gd = Doxygen::groupSDict->find(root->groups.front().groupname);
+                  gd = Doxygen::groupLinkedMap->find(root->groups.front().groupname);
                 }
                 //printf("match!\n");
                 //printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,nsName.data(),rnsName.data());
@@ -3958,13 +4001,13 @@ static void findUsedClassesForClass(const Entry *root,
           {
             if (arg.name==usedName) // type is a template argument
             {
-              found=TRUE;
               Debug::print(Debug::Classes,0,"    New used class '%s'\n", qPrint(usedName));
 
-              ClassDefMutable *usedCd = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(usedName));
+              ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(usedName);
+              ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
               if (usedCd==0)
               {
-                usedCd = toClassDefMutable(
+                usedCdm = toClassDefMutable(
                     Doxygen::hiddenClassLinkedMap->add(usedName,
                       std::unique_ptr<ClassDef>(
                         createClassDef(
@@ -3972,21 +4015,32 @@ static void findUsedClassesForClass(const Entry *root,
                           masterCd->getDefColumn(),
                           usedName,
                           ClassDef::Class))));
-                //printf("making %s a template argument!!!\n",usedCd->name().data());
-                usedCd->makeTemplateArgument();
-                usedCd->setUsedOnly(TRUE);
-                usedCd->setLanguage(masterCd->getLanguage());
+                if (usedCdm)
+                {
+                  //printf("making %s a template argument!!!\n",usedCd->name().data());
+                  usedCdm->makeTemplateArgument();
+                  usedCdm->setUsedOnly(TRUE);
+                  usedCdm->setLanguage(masterCd->getLanguage());
+                  usedCd = usedCdm;
+                }
+              }
+              if (usedCd)
+              {
+                found=TRUE;
+                Debug::print(Debug::Classes,0,"      Adding used class '%s' (1)\n", qPrint(usedCd->name()));
+                instanceCd->addUsedClass(usedCd,md->name(),md->protection());
+                if (usedCdm)
+                {
+                  if (isArtificial) usedCdm->setArtificial(TRUE);
+                  usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
+                }
               }
-              if (isArtificial) usedCd->setArtificial(TRUE);
-              Debug::print(Debug::Classes,0,"      Adding used class '%s' (1)\n", qPrint(usedCd->name()));
-              instanceCd->addUsedClass(usedCd,md->name(),md->protection());
-              usedCd->addUsedByClass(instanceCd,md->name(),md->protection());
             }
           }
 
           if (!found)
           {
-            ClassDefMutable *usedCd=toClassDefMutable(findClassWithinClassContext(context,masterCd,usedName));
+            ClassDef *usedCd=findClassWithinClassContext(context,masterCd,usedName);
             //printf("Looking for used class %s: result=%s master=%s\n",
             //    usedName.data(),usedCd?usedCd->name().data():"<none>",masterCd?masterCd->name().data():"<none>");
 
@@ -3995,7 +4049,11 @@ static void findUsedClassesForClass(const Entry *root,
               found=TRUE;
               Debug::print(Debug::Classes,0,"    Adding used class '%s' (2)\n", qPrint(usedCd->name()));
               instanceCd->addUsedClass(usedCd,md->name(),md->protection()); // class exists
-              usedCd->addUsedByClass(instanceCd,md->name(),md->protection());
+              ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
+              if (usedCdm)
+              {
+                usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
+              }
             }
           }
           if (delTempNames)
@@ -4006,7 +4064,8 @@ static void findUsedClassesForClass(const Entry *root,
         }
         if (!found && !type.isEmpty()) // used class is not documented in any scope
         {
-          ClassDefMutable *usedCd = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(type));
+          ClassDef *usedCd = Doxygen::hiddenClassLinkedMap->find(type);
+          ClassDefMutable *usedCdm = toClassDefMutable(usedCd);
           if (usedCd==0 && !Config_getBool(HIDE_UNDOC_RELATIONS))
           {
             if (type.right(2)=="(*" || type.right(2)=="(^") // type is a function pointer
@@ -4014,22 +4073,29 @@ static void findUsedClassesForClass(const Entry *root,
               type+=md->argsString();
             }
             Debug::print(Debug::Classes,0,"  New undocumented used class '%s'\n", qPrint(type));
-            usedCd = toClassDefMutable(
+            usedCdm = toClassDefMutable(
                        Doxygen::hiddenClassLinkedMap->add(type,
                          std::unique_ptr<ClassDef>(
                            createClassDef(
                              masterCd->getDefFileName(),masterCd->getDefLine(),
                              masterCd->getDefColumn(),
                              type,ClassDef::Class))));
-            usedCd->setUsedOnly(TRUE);
-            usedCd->setLanguage(masterCd->getLanguage());
+            if (usedCdm)
+            {
+              usedCdm->setUsedOnly(TRUE);
+              usedCdm->setLanguage(masterCd->getLanguage());
+              usedCd = usedCdm;
+            }
           }
           if (usedCd)
           {
-            if (isArtificial) usedCd->setArtificial(TRUE);
             Debug::print(Debug::Classes,0,"    Adding used class '%s' (3)\n", qPrint(usedCd->name()));
             instanceCd->addUsedClass(usedCd,md->name(),md->protection());
-            usedCd->addUsedByClass(instanceCd,md->name(),md->protection());
+            if (usedCdm)
+            {
+              if (isArtificial) usedCdm->setArtificial(TRUE);
+              usedCdm->addUsedByClass(instanceCd,md->name(),md->protection());
+            }
           }
         }
       }
@@ -4093,14 +4159,14 @@ static void findBaseClassesForClass(
 
 //----------------------------------------------------------------------
 
-static bool findTemplateInstanceRelation(const Entry *root,
+static void findTemplateInstanceRelation(const Entry *root,
             Definition *context,
             ClassDefMutable *templateClass,const QCString &templSpec,
             QDict<int> *templateNames,
             bool isArtificial)
 {
-  Debug::print(Debug::Classes,0,"    derived from template %s with parameters %s\n",
-         qPrint(templateClass->name()),qPrint(templSpec));
+  Debug::print(Debug::Classes,0,"    derived from template %s with parameters %s isArtificial=%d\n",
+         qPrint(templateClass->name()),qPrint(templSpec),isArtificial);
   //printf("findTemplateInstanceRelation(base=%s templSpec=%s templateNames=",
   //    templateClass->name().data(),templSpec.data());
   //if (templateNames)
@@ -4117,44 +4183,49 @@ static bool findTemplateInstanceRelation(const Entry *root,
   bool existingClass = (templSpec ==
                         tempArgListToString(templateClass->templateArguments(),root->lang,false)
                        );
-  if (existingClass) return TRUE;
+  if (existingClass) return;
 
   bool freshInstance=FALSE;
   ClassDefMutable *instanceClass = toClassDefMutable(
                      templateClass->insertTemplateInstance(
                      root->fileName,root->startLine,root->startColumn,templSpec,freshInstance));
-  if (isArtificial) instanceClass->setArtificial(TRUE);
-  instanceClass->setLanguage(root->lang);
-
-  if (freshInstance)
+  if (instanceClass)
   {
-    Debug::print(Debug::Classes,0,"      found fresh instance '%s'!\n",qPrint(instanceClass->name()));
-    instanceClass->setTemplateBaseClassNames(templateNames);
+    if (isArtificial)
+    {
+      instanceClass->setArtificial(TRUE);
+    }
+    instanceClass->setLanguage(root->lang);
 
-    // search for new template instances caused by base classes of
-    // instanceClass
-    auto it_pair = g_classEntries.equal_range(templateClass->name().data());
-    for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
+    if (freshInstance)
     {
-      const Entry *templateRoot = it->second;
-      Debug::print(Debug::Classes,0,"        template root found %s templSpec=%s!\n",
-          qPrint(templateRoot->name),qPrint(templSpec));
-      std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
-      findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
-          TemplateInstances,isArtificial,templArgs,templateNames);
+      Debug::print(Debug::Classes,0,"      found fresh instance '%s'!\n",qPrint(instanceClass->name()));
+      instanceClass->setTemplateBaseClassNames(templateNames);
 
-      findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
-          isArtificial,templArgs,templateNames);
-    }
+      // search for new template instances caused by base classes of
+      // instanceClass
+      auto it_pair = g_classEntries.equal_range(templateClass->name().data());
+      for (auto it=it_pair.first ; it!=it_pair.second ; ++it)
+      {
+        const Entry *templateRoot = it->second;
+        Debug::print(Debug::Classes,0,"        template root found %s templSpec=%s!\n",
+            qPrint(templateRoot->name),qPrint(templSpec));
+        std::unique_ptr<ArgumentList> templArgs = stringToArgumentList(root->lang,templSpec);
+        findBaseClassesForClass(templateRoot,context,templateClass,instanceClass,
+            TemplateInstances,isArtificial,templArgs,templateNames);
 
-    //Debug::print(Debug::Classes,0,"    Template instance %s : \n",instanceClass->name().data());
-    //ArgumentList *tl = templateClass->templateArguments();
-  }
-  else
-  {
-    Debug::print(Debug::Classes,0,"      instance already exists!\n");
+        findUsedClassesForClass(templateRoot,context,templateClass,instanceClass,
+            isArtificial,templArgs,templateNames);
+      }
+
+      //Debug::print(Debug::Classes,0,"    Template instance %s : \n",instanceClass->name().data());
+      //ArgumentList *tl = templateClass->templateArguments();
+    }
+    else
+    {
+      Debug::print(Debug::Classes,0,"      instance already exists!\n");
+    }
   }
-  return TRUE;
 }
 
 static bool isRecursiveBaseClass(const QCString &scope,const QCString &name)
@@ -4517,8 +4588,8 @@ static bool findClassRelation(
           baseClass=0;
           if (isATemplateArgument)
           {
-            baseClass=toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(baseClassName));
-            if (baseClass==0)
+            baseClass = toClassDefMutable(Doxygen::hiddenClassLinkedMap->find(baseClassName));
+            if (baseClass==0) // not found (or alias)
             {
               baseClass= toClassDefMutable(
                 Doxygen::hiddenClassLinkedMap->add(baseClassName,
@@ -4526,17 +4597,19 @@ static bool findClassRelation(
                     createClassDef(root->fileName,root->startLine,root->startColumn,
                                  baseClassName,
                                  ClassDef::Class))));
-              if (isArtificial) baseClass->setArtificial(TRUE);
-              baseClass->setLanguage(root->lang);
-
+              if (baseClass) // really added (not alias)
+              {
+                if (isArtificial) baseClass->setArtificial(TRUE);
+                baseClass->setLanguage(root->lang);
+              }
             }
           }
           else
           {
-            baseClass=toClassDefMutable(Doxygen::classLinkedMap->find(baseClassName));
+            baseClass = toClassDefMutable(Doxygen::classLinkedMap->find(baseClassName));
             //printf("*** classDDict->find(%s)=%p biName=%s templSpec=%s\n",
             //    baseClassName.data(),baseClass,biName.data(),templSpec.data());
-            if (baseClass==0)
+            if (baseClass==0) // not found (or alias)
             {
               baseClass = toClassDefMutable(
                   Doxygen::classLinkedMap->add(baseClassName,
@@ -4544,41 +4617,51 @@ static bool findClassRelation(
                       createClassDef(root->fileName,root->startLine,root->startColumn,
                         baseClassName,
                         ClassDef::Class))));
-              if (isArtificial) baseClass->setArtificial(TRUE);
-              baseClass->setLanguage(root->lang);
-              si = baseClassName.findRev("::");
-              if (si!=-1) // class is nested
+              if (baseClass) // really added (not alias)
               {
-                Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo());
-                if (sd==0 || sd==Doxygen::globalScope) // outer scope not found
+                if (isArtificial) baseClass->setArtificial(TRUE);
+                baseClass->setLanguage(root->lang);
+                si = baseClassName.findRev("::");
+                if (si!=-1) // class is nested
                 {
-                  baseClass->setArtificial(TRUE); // see bug678139
+                  Definition *sd = findScopeFromQualifiedName(Doxygen::globalScope,baseClassName.left(si),0,root->tagInfo());
+                  if (sd==0 || sd==Doxygen::globalScope) // outer scope not found
+                  {
+                    baseClass->setArtificial(TRUE); // see bug678139
+                  }
                 }
               }
             }
           }
-          if (biName.right(2)=="-p")
+          if (baseClass)
           {
-            biName="<"+biName.left(biName.length()-2)+">";
-          }
-          // add base class to this class
-          cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
-          // add this class as super class to the base class
-          baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
-          // the undocumented base was found in this file
-          baseClass->insertUsedFile(root->fileDef());
-
-          Definition *scope = buildScopeFromQualifiedName(baseClass->name(),root->lang,0);
-          if (scope!=baseClass)
-          {
-            baseClass->setOuterScope(scope);
-          }
+            if (biName.right(2)=="-p")
+            {
+              biName="<"+biName.left(biName.length()-2)+">";
+            }
+            // add base class to this class
+            cd->insertBaseClass(baseClass,biName,bi->prot,bi->virt,templSpec);
+            // add this class as super class to the base class
+            baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
+            // the undocumented base was found in this file
+            baseClass->insertUsedFile(root->fileDef());
+
+            Definition *scope = buildScopeFromQualifiedName(baseClass->name(),root->lang,0);
+            if (scope!=baseClass)
+            {
+              baseClass->setOuterScope(scope);
+            }
 
-          if (baseClassName.right(2)=="-p")
+            if (baseClassName.right(2)=="-p")
+            {
+              baseClass->setCompoundType(ClassDef::Protocol);
+            }
+            return TRUE;
+          }
+          else
           {
-            baseClass->setCompoundType(ClassDef::Protocol);
+            Debug::print(Debug::Classes,0,"    Base class '%s' not created (alias?)\n",qPrint(biName));
           }
-          return TRUE;
         }
         else
         {
@@ -4853,9 +4936,7 @@ static void computeMemberReferences()
       ndm->computeAnchors();
     }
   }
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     gd->computeAnchors();
   }
@@ -4891,16 +4972,12 @@ static void addListReferences()
     }
   }
 
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     gd->addListReferences();
   }
 
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
     QCString name = pd->getOutputFileBase();
     if (pd->getGroupDef())
@@ -4916,9 +4993,7 @@ static void addListReferences()
     }
   }
 
-  DirSDict::Iterator ddi(*Doxygen::directories);
-  DirDef *dd = 0;
-  for (ddi.toFirst();(dd=ddi.current());++ddi)
+  for (const auto &dd : *Doxygen::dirLinkedMap)
   {
     QCString name = dd->getOutputFileBase();
     //if (dd->getGroupDef())
@@ -4955,6 +5030,7 @@ static void addMemberDocs(const Entry *root,
                    uint64 spec
                   )
 {
+  if (md==0) return;
   //printf("addMemberDocs: '%s'::'%s' '%s' funcDecl='%s' mSpec=%lld\n",
   //     root->parent()->name.data(),md->name().data(),md->argsString(),funcDecl,spec);
   QCString fDecl=funcDecl;
@@ -5536,10 +5612,11 @@ static void addMemberFunction(const Entry *root,
     MemberDefMutable *md = toMemberDefMutable(imd.get());
     if (md==0) continue;
     ClassDefMutable *cd=md->getClassDefMutable();
+    if (cd==0) continue;
     Debug::print(Debug::FindMembers,0,
         "3. member definition found, "
         "scope needed='%s' scope='%s' args='%s' fileName=%s\n",
-        qPrint(scopeName),cd ? qPrint(cd->name()) : "<none>",
+        qPrint(scopeName),qPrint(cd->name()),
         qPrint(md->argsString()),
         qPrint(root->fileName));
     //printf("Member %s (member scopeName=%s) (this scopeName=%s) isEnumValue()=%d\n",
@@ -7330,7 +7407,7 @@ static void findEnumDocumentation(const Entry *root)
             const ClassDef *mcd = md->getClassDef();
             const NamespaceDef *mnd = md->getNamespaceDef();
             const FileDef *mfd = md->getFileDef();
-            if (mcd==cd)
+            if (cd && mcd==cd)
             {
               Debug::print(Debug::FindMembers,0,"2. Match found for class scope\n");
               addEnumDocs(root,md);
@@ -7423,22 +7500,19 @@ static void addMembersToIndex()
   for (const auto &mn : *Doxygen::functionNameLinkedMap)
   {
     // for each member definition
-    for (const auto &imd : *mn)
+    for (const auto &md : *mn)
     {
-      MemberDefMutable *md = toMemberDefMutable(imd.get());
-      if (md)
+      if (md->getNamespaceDef())
       {
-        if (md->getNamespaceDef())
-        {
-          addNamespaceMemberNameToIndex(md);
-        }
-        else
-        {
-          addFileMemberNameToIndex(md);
-        }
+        addNamespaceMemberNameToIndex(md.get());
+      }
+      else
+      {
+        addFileMemberNameToIndex(md.get());
       }
     }
   }
+  sortMemberIndexLists();
 }
 
 //----------------------------------------------------------------------
@@ -7992,9 +8066,7 @@ static void sortMemberLists()
   }
 
   // sort group member lists
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     gd->sortMemberLists();
   }
@@ -8065,9 +8137,7 @@ static void countMembers()
     }
   }
 
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     gd->countMembers();
   }
@@ -8202,9 +8272,7 @@ static void addMembersToMemberGroup()
     }
   }
   // for each group
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     gd->addMembersToMemberGroup();
   }
@@ -8241,9 +8309,7 @@ static void distributeMemberGroupDocumentation()
     }
   }
   // for each group
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     gd->distributeMemberGroupDocumentation();
   }
@@ -8280,16 +8346,12 @@ static void findSectionsInDocumentation()
     }
   }
   // for each group
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     gd->findSectionsInDocumentation();
   }
   // for each page
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
     pd->findSectionsInDocumentation();
   }
@@ -8548,9 +8610,8 @@ static void findDirDocumentation(const Entry *root)
     {
       normalizedName+='/';
     }
-    DirDef *dir,*matchingDir=0;
-    SDict<DirDef>::Iterator sdi(*Doxygen::directories);
-    for (sdi.toFirst();(dir=sdi.current());++sdi)
+    DirDef *matchingDir=0;
+    for (const auto &dir : *Doxygen::dirLinkedMap)
     {
       //printf("Dir: %s<->%s\n",dir->name().data(),normalizedName.data());
       if (dir->name().right(normalizedName.length())==normalizedName)
@@ -8566,7 +8627,7 @@ static void findDirDocumentation(const Entry *root)
         }
         else
         {
-          matchingDir=dir;
+          matchingDir=dir.get();
         }
       }
     }
@@ -8629,14 +8690,14 @@ static void findMainPage(Entry *root)
       QCString title=root->args.stripWhiteSpace();
       //QCString indexName=Config_getBool(GENERATE_TREEVIEW)?"main":"index";
       QCString indexName="index";
-      Doxygen::mainPage = createPageDef(root->docFile,root->docLine,
-                              indexName, root->brief+root->doc+root->inbodyDocs,title);
+      Doxygen::mainPage.reset(createPageDef(root->docFile,root->docLine,
+                              indexName, root->brief+root->doc+root->inbodyDocs,title));
       //setFileNameForSections(root->anchors,"index",Doxygen::mainPage);
       Doxygen::mainPage->setBriefDescription(root->brief,root->briefFile,root->briefLine);
       Doxygen::mainPage->setBodySegment(root->startLine,root->startLine,-1);
       Doxygen::mainPage->setFileName(indexName);
       Doxygen::mainPage->setLocalToc(root->localToc);
-      addPageToContext(Doxygen::mainPage,root);
+      addPageToContext(Doxygen::mainPage.get(),root);
 
       const SectionInfo *si = SectionManager::instance().find(Doxygen::mainPage->name());
       if (si)
@@ -8697,13 +8758,13 @@ static void computePageRelations(Entry *root)
      )
   {
     PageDef *pd = root->section==Entry::PAGEDOC_SEC ?
-                    Doxygen::pageSDict->find(root->name) :
-                    Doxygen::mainPage;
+                    Doxygen::pageLinkedMap->find(root->name) :
+                    Doxygen::mainPage.get();
     if (pd)
     {
       for (const BaseInfo &bi : root->extends)
       {
-        PageDef *subPd = Doxygen::pageSDict->find(bi.name);
+        PageDef *subPd = Doxygen::pageLinkedMap->find(bi.name);
         if (pd==subPd)
         {
          term("page defined at line %d of file %s with label %s is a direct "
@@ -8724,14 +8785,12 @@ static void computePageRelations(Entry *root)
 
 static void checkPageRelations()
 {
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
     Definition *ppd = pd->getOuterScope();
     while (ppd)
     {
-      if (ppd==pd)
+      if (ppd==pd.get())
       {
         term("page defined at line %d of file %s with label %s is a subpage "
             "of itself! Please remove this cyclic dependency.\n",
@@ -8775,7 +8834,7 @@ static void resolveUserReferences()
       // if this section is in a page and the page is in a group, then we
       // have to adjust the link file name to point to the group.
       if (!si->fileName().isEmpty() &&
-          (pd=Doxygen::pageSDict->find(si->fileName())) &&
+          (pd=Doxygen::pageLinkedMap->find(si->fileName())) &&
           pd->getGroupDef())
       {
         si->setFileName(pd->getGroupDef()->getOutputFileBase());
@@ -8814,11 +8873,9 @@ static void resolveUserReferences()
 
 static void generatePageDocs()
 {
-  //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageSDict->count());
+  //printf("documentedPages=%d real=%d\n",documentedPages,Doxygen::pageLinkedMap->count());
   if (documentedPages==0) return;
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
     if (!pd->getGroupDef() && !pd->isReference())
     {
@@ -8837,7 +8894,7 @@ static void buildExampleList(Entry *root)
 {
   if ((root->section==Entry::EXAMPLE_SEC || root->section==Entry::EXAMPLE_LINENO_SEC) && !root->name.isEmpty())
   {
-    if (Doxygen::exampleSDict->find(root->name))
+    if (Doxygen::exampleLinkedMap->find(root->name))
     {
       warn(root->fileName,root->startLine,
           "Example %s was already documented. Ignoring "
@@ -8847,15 +8904,16 @@ static void buildExampleList(Entry *root)
     }
     else
     {
-      PageDef *pd=createPageDef(root->fileName,root->startLine,
-          root->name,root->brief+root->doc+root->inbodyDocs,root->args);
+      PageDef *pd = Doxygen::exampleLinkedMap->add(root->name,
+             std::unique_ptr<PageDef>(
+               createPageDef(root->fileName,root->startLine,
+                 root->name,root->brief+root->doc+root->inbodyDocs,root->args)));
       pd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
       pd->setFileName(convertNameToFile(pd->name()+"-example",FALSE,TRUE));
       pd->addSectionsToDefinition(root->anchors);
       pd->setLanguage(root->lang);
       pd->setShowLineNo(root->section==Entry::EXAMPLE_LINENO_SEC);
 
-      Doxygen::exampleSDict->inSort(root->name,pd);
       //we don't add example to groups
       //addExampleToGroups(root,pd);
     }
@@ -8887,9 +8945,7 @@ void printNavTree(Entry *root,int indent)
 static void generateExampleDocs()
 {
   g_outputList->disable(OutputGenerator::Man);
-  PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::exampleLinkedMap)
   {
     msg("Generating docs for example %s...\n",pd->name().data());
     auto intf = Doxygen::parserManager->getCodeParser(".c"); // TODO: do this on code type
@@ -8905,9 +8961,9 @@ static void generateExampleDocs()
     {
       lineNoOptStr="{lineno}";
     }
-    g_outputList->generateDoc(pd->docFile(),                            // file
+    g_outputList->generateDoc(pd->docFile(),                       // file
                          pd->docLine(),                            // startLine
-                         pd,                                       // context
+                         pd.get(),                                 // context
                          0,                                        // memberDef
                          pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
                          TRUE,                                     // index words
@@ -8927,9 +8983,7 @@ static void generateExampleDocs()
 
 static void generateGroupDocs()
 {
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     if (!gd->isReference())
     {
@@ -9296,11 +9350,22 @@ static void generateDiskNames()
       int first_path_size = static_cast<int>(first.path.size())-1; // -1 to skip trailing slash
       int last_path_size  = static_cast<int>(last.path.size())-1;  // -1 to skip trailing slash
       int j=0;
-      for (int i=0;i<first_path_size && i<last_path_size;i++)
+      int i=0;
+      for (i=0;i<first_path_size && i<last_path_size;i++)
       {
         if (first.path[i]=='/') j=i;
         if (first.path[i]!=last.path[i]) break;
       }
+      if (i==first_path_size && i<last_path_size && last.path[i]=='/')
+      {
+        // case first='some/path' and last='some/path/more' => match is 'some/path'
+        j=first_path_size;
+      }
+      else if (i==last_path_size && i<first_path_size && first.path[i]=='/')
+      {
+        // case first='some/path/more' and last='some/path' => match is 'some/path'
+        j=last_path_size;
+      }
 
       // add non-common part of the path to the name
       for (auto &fileEntry : fileEntries)
@@ -10023,7 +10088,7 @@ static void devUsage()
 
 static void usage(const char *name,const char *versionString)
 {
-  msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2019\n\n",versionString);
+  msg("Doxygen version %s\nCopyright Dimitri van Heesch 1997-2021\n\n",versionString);
   msg("You can use doxygen in a number of ways:\n\n");
   msg("1) Use doxygen to generate a template configuration file:\n");
   msg("    %s [-s] -g [configName]\n\n",name);
@@ -10127,24 +10192,18 @@ void initDoxygen()
   initFileMemberIndices();
 
 #ifdef USE_LIBCLANG
-  Doxygen::clangUsrMap   = new QDict<Definition>(50177);
+  Doxygen::clangUsrMap   = new ClangUsrMap;
 #endif
   Doxygen::memberNameLinkedMap = new MemberNameLinkedMap;
   Doxygen::functionNameLinkedMap = new MemberNameLinkedMap;
-  Doxygen::groupSDict = new GroupSDict(17);
-  Doxygen::groupSDict->setAutoDelete(TRUE);
+  Doxygen::groupLinkedMap = new GroupLinkedMap;
   Doxygen::namespaceLinkedMap = new NamespaceLinkedMap;
   Doxygen::classLinkedMap = new ClassLinkedMap;
   Doxygen::hiddenClassLinkedMap = new ClassLinkedMap;
-  Doxygen::directories = new DirSDict(17);
-  Doxygen::directories->setAutoDelete(TRUE);
-  Doxygen::pageSDict = new PageSDict(1009);          // all doc pages
-  Doxygen::pageSDict->setAutoDelete(TRUE);
-  Doxygen::exampleSDict = new PageSDict(1009);       // all examples
-  Doxygen::exampleSDict->setAutoDelete(TRUE);
-  Doxygen::memGrpInfoDict.setAutoDelete(TRUE);
+  Doxygen::dirLinkedMap = new DirLinkedMap;
+  Doxygen::pageLinkedMap = new PageLinkedMap;          // all doc pages
+  Doxygen::exampleLinkedMap = new PageLinkedMap;       // all examples
   Doxygen::tagDestinationDict.setAutoDelete(TRUE);
-  Doxygen::dirRelations.setAutoDelete(TRUE);
   Doxygen::indexList = new IndexList;
 
   // initialisation of these globals depends on
@@ -10184,9 +10243,9 @@ void cleanUpDoxygen()
   delete Doxygen::dotFileNameLinkedMap;
   delete Doxygen::mscFileNameLinkedMap;
   delete Doxygen::diaFileNameLinkedMap;
-  delete Doxygen::mainPage;
-  delete Doxygen::pageSDict;
-  delete Doxygen::exampleSDict;
+  Doxygen::mainPage.reset();
+  delete Doxygen::pageLinkedMap;
+  delete Doxygen::exampleLinkedMap;
   delete Doxygen::globalScope;
   delete Doxygen::parserManager;
   delete theTranslator;
@@ -10195,9 +10254,9 @@ void cleanUpDoxygen()
 
   delete Doxygen::memberNameLinkedMap;
   delete Doxygen::functionNameLinkedMap;
-  delete Doxygen::groupSDict;
+  delete Doxygen::groupLinkedMap;
   delete Doxygen::namespaceLinkedMap;
-  delete Doxygen::directories;
+  delete Doxygen::dirLinkedMap;
 
   DotManager::deleteInstance();
 }
@@ -10691,14 +10750,6 @@ static void stopDoxygen(int)
 {
   QDir thisDir;
   msg("Cleaning up...\n");
-  if (!Doxygen::entryDBFileName.isEmpty())
-  {
-    thisDir.remove(Doxygen::entryDBFileName);
-  }
-  if (!Doxygen::objDBFileName.isEmpty())
-  {
-    thisDir.remove(Doxygen::objDBFileName);
-  }
   if (!Doxygen::filterDBFileName.isEmpty())
   {
     thisDir.remove(Doxygen::filterDBFileName);
@@ -10757,16 +10808,12 @@ static void writeTagFile()
     }
   }
   // for each group
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     if (gd->isLinkableInProject()) gd->writeTagFile(tagFile);
   }
   // for each page
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
     if (pd->isLinkableInProject()) pd->writeTagFile(tagFile);
   }
@@ -10801,14 +10848,6 @@ static void exitDoxygen()
   {
     QDir thisDir;
     msg("Exiting...\n");
-    if (!Doxygen::entryDBFileName.isEmpty())
-    {
-      thisDir.remove(Doxygen::entryDBFileName);
-    }
-    if (!Doxygen::objDBFileName.isEmpty())
-    {
-      thisDir.remove(Doxygen::objDBFileName);
-    }
     if (!Doxygen::filterDBFileName.isEmpty())
     {
       thisDir.remove(Doxygen::filterDBFileName);
@@ -11095,10 +11134,6 @@ void parseInput()
 #endif
 
   uint pid = Portable::pid();
-  Doxygen::objDBFileName.sprintf("doxygen_objdb_%d.tmp",pid);
-  Doxygen::objDBFileName.prepend(outputDirectory+"/");
-  Doxygen::entryDBFileName.sprintf("doxygen_entrydb_%d.tmp",pid);
-  Doxygen::entryDBFileName.prepend(outputDirectory+"/");
   Doxygen::filterDBFileName.sprintf("doxygen_filterdb_%d.tmp",pid);
   Doxygen::filterDBFileName.prepend(outputDirectory+"/");
 
@@ -11499,7 +11534,6 @@ void parseInput()
   g_s.end();
 
   QDir thisDir;
-  thisDir.remove(Doxygen::entryDBFileName);
 
   g_s.begin("Determining which enums are documented\n");
   findDocumentedEnumValues();
@@ -11608,10 +11642,12 @@ void parseInput()
 
   if (Config_getBool(SORT_GROUP_NAMES))
   {
-    Doxygen::groupSDict->sort();
-    GroupSDict::Iterator gli(*Doxygen::groupSDict);
-    GroupDef *gd;
-    for (gli.toFirst();(gd=gli.current());++gli)
+    std::sort(Doxygen::groupLinkedMap->begin(),
+              Doxygen::groupLinkedMap->end(),
+              [](const auto &g1,const auto &g2)
+              { return qstrcmp(g1->groupTitle(),g2->groupTitle())<0; });
+
+    for (const auto &gd : *Doxygen::groupLinkedMap)
     {
       gd->sortSubGroups();
     }
@@ -11990,7 +12026,6 @@ void generateOutput()
 
   finalizeSearchIndexer();
   QDir thisDir;
-  thisDir.remove(Doxygen::objDBFileName);
   thisDir.remove(Doxygen::filterDBFileName);
   finishWarnExit();
   Config::deinit();
index fb984f6..1886c0e 100644 (file)
@@ -36,8 +36,7 @@
 #define AtomicBool   std::atomic_bool
 
 class RefList;
-class PageSList;
-class PageSDict;
+class PageLinkedMap;
 class PageDef;
 class SearchIndexIntf;
 class ParserManager;
@@ -46,17 +45,15 @@ class BufStr;
 class CiteDict;
 class MemberDef;
 class GroupDef;
-class GroupSDict;
+class GroupLinkedMap;
 class FileDef;
 class ClassDef;
 class ClassLinkedMap;
-class GenericsSDict;
 class MemberNameLinkedMap;
 class FileNameLinkedMap;
 class NamespaceLinkedMap;
 class NamespaceDef;
-class DirSDict;
-class DirRelation;
+class DirRelationLinkedMap;
 class IndexList;
 class FormulaList;
 class FormulaDict;
@@ -86,7 +83,7 @@ struct LookupInfo
   QCString   resolvedType;
 };
 
-extern QCString g_spaces;
+using ClangUsrMap = std::unordered_map<std::string,const Definition *>;
 
 /*! \brief This class serves as a namespace for global variables used by doxygen.
  *
@@ -97,9 +94,9 @@ class Doxygen
   public:
     static ClassLinkedMap           *classLinkedMap;
     static ClassLinkedMap           *hiddenClassLinkedMap;
-    static PageSDict                *exampleSDict;
-    static PageSDict                *pageSDict;
-    static PageDef                  *mainPage;
+    static PageLinkedMap            *exampleLinkedMap;
+    static PageLinkedMap            *pageLinkedMap;
+    static std::unique_ptr<PageDef>  mainPage;
     static bool                      insideMainPage;
     static FileNameLinkedMap        *includeNameLinkedMap;
     static FileNameLinkedMap        *exampleNameLinkedMap;
@@ -112,27 +109,24 @@ class Doxygen
     static MemberNameLinkedMap      *memberNameLinkedMap;
     static MemberNameLinkedMap      *functionNameLinkedMap;
     static StringUnorderedMap        namespaceAliasMap;
-    static GroupSDict               *groupSDict;
+    static GroupLinkedMap           *groupLinkedMap;
     static NamespaceLinkedMap       *namespaceLinkedMap;
     static StringDict                tagDestinationDict;
     static StringDict                aliasDict;
-    static QIntDict<MemberGroupInfo> memGrpInfoDict;
+    static MemberGroupInfoMap        memberGroupInfoMap;
     static StringUnorderedSet        expandAsDefinedSet;
     static NamespaceDefMutable      *globalScope;
     static QCString                  htmlFileExtension;
     static bool                      parseSourcesNeeded;
     static SearchIndexIntf          *searchIndex;
     static SymbolMap<Definition>     symbolMap;
-    static QDict<Definition>        *clangUsrMap;
+    static ClangUsrMap              *clangUsrMap;
     static bool                      outputToWizard;
-    static QDict<int>               *htmlDirMap;
     static Cache<std::string,LookupInfo> *lookupCache;
-    static DirSDict                 *directories;
-    static SDict<DirRelation>        dirRelations;
+    static DirLinkedMap             *dirLinkedMap;
+    static DirRelationLinkedMap      dirRelations;
     static ParserManager            *parserManager;
     static bool                      suppressDocWarnings;
-    static QCString                  objDBFileName;
-    static QCString                  entryDBFileName;
     static QCString                  filterDBFileName;
     static bool                      userComments;
     static IndexList                *indexList;
index 2af06ba..7929c24 100644 (file)
@@ -1,12 +1,10 @@
 /******************************************************************************
  *
- * 
- *
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
+ * Copyright (C) 1997-2021 by Dimitri van Heesch.
  *
  * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby 
- * granted. No representations are made about the suitability of this software 
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
  * for any purpose. It is provided "as is" without express or implied warranty.
  * See the GNU General Public License for more details.
  *
 #ifndef EXAMPLE_H
 #define EXAMPLE_H
 
+#include <algorithm>
+#include <vector>
+
 #include <qcstring.h>
-#include "sortdict.h"
 
 class ClassDef;
 class MemberName;
@@ -27,21 +27,27 @@ class MemberName;
 /** Data associated with an example. */
 struct Example
 {
+  Example(const QCString &a,const QCString &n,const QCString &f) : anchor(a), name(n), file(f) {}
   QCString anchor;
   QCString name;
   QCString file;
 };
 
-/** A sorted dictionary of Example objects. */
-class ExampleSDict : public SDict<Example>
+class ExampleList : public std::vector<Example>
 {
   public:
-    ExampleSDict(uint size=17) : SDict<Example>(size) { setAutoDelete(TRUE); }
-   ~ExampleSDict() {}
-  private:
-    int compareValues(const Example *item1,const Example *item2) const
+    bool inSort( const Example& ex )
     {
-      return qstricmp(item1->name,item2->name);
+      auto it = std::find_if(begin(),end(),[&ex](const Example &e) { return e.name==ex.name; });
+      if (it==end())
+      {
+        insert( std::upper_bound( begin(), end(), ex,
+                 [](const auto &e1,const auto &e2) { return e1.name < e2.name; }
+                ), ex
+              );
+        return true;
+      }
+      return false;
     }
 };
 
index e8d6066..2fb2af7 100644 (file)
@@ -48,6 +48,9 @@
 
 //---------------------------------------------------------------------------
 
+using DefinitionLineMap = std::unordered_map<int,const Definition *>;
+using MemberDefLineMap  = std::unordered_map<int,const MemberDef *>;
+
 class FileDefImpl : public DefinitionMixin<FileDef>
 {
   public:
@@ -69,8 +72,8 @@ class FileDefImpl : public DefinitionMixin<FileDef>
     virtual const QCString &docName() const { return m_docname; }
     virtual bool isSource() const { return m_isSource; }
     virtual bool isDocumentationFile() const;
-    virtual Definition *getSourceDefinition(int lineNr) const;
-    virtual MemberDef *getSourceMember(int lineNr) const;
+    virtual const Definition *getSourceDefinition(int lineNr) const;
+    virtual const MemberDef *getSourceMember(int lineNr) const;
     virtual QCString getPath() const { return m_path; }
     virtual QCString getVersion() const { return m_fileVersion; }
     virtual bool isLinkableInProject() const;
@@ -84,8 +87,8 @@ class FileDefImpl : public DefinitionMixin<FileDef>
     virtual QList<IncludeInfo> *includedByFileList() const { return m_includedByList; }
     virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const;
     virtual MemberList *getMemberList(MemberListType lt) const;
-    virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; }
-    virtual MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; }
+    virtual const MemberLists &getMemberLists() const { return m_memberLists; }
+    virtual const MemberGroupList &getMemberGroups() const  { return m_memberGroups; }
     virtual NamespaceLinkedRefMap getNamespaces() const     { return m_namespaces; }
     virtual ClassLinkedRefMap getClasses() const   { return m_classes; }
     virtual QCString title() const;
@@ -95,7 +98,7 @@ class FileDefImpl : public DefinitionMixin<FileDef>
     virtual void countMembers();
     virtual int numDocMembers() const;
     virtual int numDecMembers() const;
-    virtual void addSourceRef(int line,Definition *d,MemberDef *md);
+    virtual void addSourceRef(int line,const Definition *d,const MemberDef *md);
     virtual void writeDocumentation(OutputList &ol);
     virtual void writeMemberPages(OutputList &ol);
     virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const;
@@ -127,7 +130,6 @@ class FileDefImpl : public DefinitionMixin<FileDef>
 
   private:
     void acquireFileVersion();
-    MemberList *createMemberList(MemberListType lt);
     void addMemberToList(MemberListType lt,MemberDef *md);
     void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title);
     void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title);
@@ -162,14 +164,14 @@ class FileDefImpl : public DefinitionMixin<FileDef>
     QCString              m_outputDiskName;
     QCString              m_fileName;
     QCString              m_docname;
-    QIntDict<Definition> *m_srcDefDict;
-    QIntDict<MemberDef>  *m_srcMemberDict;
+    DefinitionLineMap     m_srcDefMap;
+    MemberDefLineMap      m_srcMemberMap;
     bool                  m_isSource;
     QCString              m_fileVersion;
     PackageDef           *m_package;
     DirDef               *m_dir;
-    QList<MemberList>     m_memberLists;
-    MemberGroupSDict     *m_memberGroupSDict;
+    MemberLists           m_memberLists;
+    MemberGroupList       m_memberGroups;
     NamespaceLinkedRefMap m_namespaces;
     ClassLinkedRefMap     m_classes;
     ClassLinkedRefMap     m_interfaces;
@@ -230,8 +232,6 @@ FileDefImpl::FileDefImpl(const char *p,const char *nm,
   m_includeDict       = 0;
   m_includedByList    = 0;
   m_includedByDict    = 0;
-  m_srcDefDict        = 0;
-  m_srcMemberDict     = 0;
   m_package           = 0;
   m_isSource          = guessSection(nm)==Entry::SOURCE_SEC;
   m_docname           = nm;
@@ -241,7 +241,6 @@ FileDefImpl::FileDefImpl(const char *p,const char *nm,
     m_docname.prepend(stripFromPath(m_path.copy()));
   }
   setLanguage(getLanguageFromFileName(name()));
-  m_memberGroupSDict = 0;
   acquireFileVersion();
   m_subGrouping=Config_getBool(SUBGROUPING);
 }
@@ -253,9 +252,6 @@ FileDefImpl::~FileDefImpl()
   delete m_includeList;
   delete m_includedByDict;
   delete m_includedByList;
-  delete m_srcDefDict;
-  delete m_srcMemberDict;
-  delete m_memberGroupSDict;
 }
 
 void FileDefImpl::setDiskName(const QCString &name)
@@ -284,14 +280,9 @@ void FileDefImpl::computeAnchors()
 void FileDefImpl::distributeMemberGroupDocumentation()
 {
   //printf("FileDefImpl::distributeMemberGroupDocumentation()\n");
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->distributeMemberGroupDocumentation();
-    }
+    mg->distributeMemberGroupDocumentation();
   }
 }
 
@@ -299,19 +290,12 @@ void FileDefImpl::findSectionsInDocumentation()
 {
   docFindSections(briefDescription(),this,docFile());
   docFindSections(documentation(),this,docFile());
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->findSectionsInDocumentation(this);
-    }
+    mg->findSectionsInDocumentation(this);
   }
 
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_declarationLists)
     {
@@ -411,14 +395,9 @@ void FileDefImpl::writeTagFile(FTextStream &tagFile)
         break;
       case LayoutDocEntry::MemberGroups:
         {
-          if (m_memberGroupSDict)
+          for (const auto &mg : m_memberGroups)
           {
-            MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-            MemberGroup *mg;
-            for (;(mg=mgli.current());++mgli)
-            {
-              mg->writeTagFile(tagFile);
-            }
+            mg->writeTagFile(tagFile);
           }
         }
         break;
@@ -751,18 +730,12 @@ void FileDefImpl::endMemberDocumentation(OutputList &ol)
 void FileDefImpl::writeMemberGroups(OutputList &ol)
 {
   /* write user defined member groups */
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    m_memberGroupSDict->sort();
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    if ((!mg->allMembersInSameSection() || !m_subGrouping)
+        && mg->header()!="[NOHEADER]")
     {
-      if ((!mg->allMembersInSameSection() || !m_subGrouping)
-          && mg->header()!="[NOHEADER]")
-      {
-        mg->writeDeclarations(ol,0,0,this,0);
-      }
+      mg->writeDeclarations(ol,0,0,this,0);
     }
   }
 }
@@ -1068,9 +1041,7 @@ void FileDefImpl::writeMemberPages(OutputList &ol)
   ol.pushGeneratorState();
   ol.disableAllBut(OutputGenerator::Html);
 
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_documentationLists)
     {
@@ -1267,28 +1238,21 @@ void FileDefImpl::parseSource(ClangTUParser *clangParser)
 
 void FileDefImpl::addMembersToMemberGroup()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_declarationLists)
     {
-      ::addMembersToMemberGroup(ml,&m_memberGroupSDict,this);
+      ::addMembersToMemberGroup(ml.get(),&m_memberGroups,this);
     }
   }
 
   // add members inside sections to their groups
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    if (mg->allMembersInSameSection() && m_subGrouping)
     {
-      if (mg->allMembersInSameSection() && m_subGrouping)
-      {
-        //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
-        mg->addToDeclarationSection();
-      }
+      //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
+      mg->addToDeclarationSection();
     }
   }
 }
@@ -1307,8 +1271,8 @@ void FileDefImpl::insertMember(MemberDef *md)
 
   if (allMemberList==0)
   {
-    allMemberList = new MemberList(MemberListType_allMembersList);
-    m_memberLists.append(allMemberList);
+    m_memberLists.emplace_back(std::make_unique<MemberList>(MemberListType_allMembersList));
+    allMemberList = m_memberLists.back().get();
   }
   allMemberList->append(md);
   //::addFileMemberNameToIndex(md);
@@ -1396,40 +1360,30 @@ QCString FileDefImpl::name() const
     return DefinitionMixin::name();
 }
 
-void FileDefImpl::addSourceRef(int line,Definition *d,MemberDef *md)
+void FileDefImpl::addSourceRef(int line,const Definition *d,const MemberDef *md)
 {
   //printf("FileDefImpl::addSourceDef(%d,%p,%p)\n",line,d,md);
   if (d)
   {
-    if (m_srcDefDict==0)    m_srcDefDict    = new QIntDict<Definition>(257);
-    if (m_srcMemberDict==0) m_srcMemberDict = new QIntDict<MemberDef>(257);
-    m_srcDefDict->insert(line,d);
-    if (md) m_srcMemberDict->insert(line,md);
+    m_srcDefMap.insert(std::make_pair(line,d));
+    if (md) m_srcMemberMap.insert(std::make_pair(line,md));
     //printf("Adding member %s with anchor %s at line %d to file %s\n",
     //    md?md->name().data():"<none>",md?md->anchor().data():"<none>",line,name().data());
   }
 }
 
-Definition *FileDefImpl::getSourceDefinition(int lineNr) const
+const Definition *FileDefImpl::getSourceDefinition(int lineNr) const
 {
-  Definition *result=0;
-  if (m_srcDefDict)
-  {
-    result = m_srcDefDict->find(lineNr);
-  }
-  //printf("%s::getSourceDefinition(%d)=%s\n",name().data(),lineNr,result?result->name().data():"none");
-  return result;
+  auto it = m_srcDefMap.find(lineNr);
+  //printf("%s::getSourceDefinition(%d)=%s\n",name().data(),lineNr,it!=m_srcDefMap.end()?it->second->name().data():"none");
+  return it!=m_srcDefMap.end() ? it->second : 0;
 }
 
-MemberDef *FileDefImpl::getSourceMember(int lineNr) const
+const MemberDef *FileDefImpl::getSourceMember(int lineNr) const
 {
-  MemberDef *result=0;
-  if (m_srcMemberDict)
-  {
-    result = m_srcMemberDict->find(lineNr);
-  }
-  //printf("%s::getSourceMember(%d)=%s\n",name().data(),lineNr,result?result->name().data():"none");
-  return result;
+  auto it = m_srcMemberMap.find(lineNr);
+  //printf("%s::getSourceMember(%d)=%s\n",name().data(),lineNr,it!=m_srcMemberMap.end()?it->second->name().data():"none");
+  return it!=m_srcMemberMap.end() ? it->second : 0;
 }
 
 
@@ -1575,18 +1529,11 @@ void FileDefImpl::addListReferences()
                0
               );
   }
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->addListReferences(this);
-    }
+    mg->addListReferences(this);
   }
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_documentationLists)
     {
@@ -1791,20 +1738,18 @@ static void addDirsAsGroups(Directory *root,GroupDef *parent,int level)
   GroupDef *gd=0;
   if (root->kind()==DirEntry::Dir)
   {
-    gd = createGroupDef("[generated]",
+    gd = Doxygen::groupLinkedMap->add(root->path(),
+           std::unique_ptr<GroupDef>(
+              createGroupDef("[generated]",
                       1,
                       root->path(), // name
                       root->name()  // title
-                     );
+                     )));
     if (parent)
     {
       parent->addGroup(gd);
       gd->makePartOfGroup(parent);
     }
-    else
-    {
-      Doxygen::groupSDict->append(root->path(),gd);
-    }
   }
   QListIterator<DirEntry> dli(root->children());
   DirEntry *de;
@@ -1932,29 +1877,11 @@ QCString FileDefImpl::includeName() const
   return getSourceFileBase();
 }
 
-MemberList *FileDefImpl::createMemberList(MemberListType lt)
-{
-  m_memberLists.setAutoDelete(TRUE);
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
-  {
-    if (ml->listType()==lt)
-    {
-      return ml;
-    }
-  }
-  // not found, create a new member list
-  ml = new MemberList(lt);
-  m_memberLists.append(ml);
-  return ml;
-}
-
 void FileDefImpl::addMemberToList(MemberListType lt,MemberDef *md)
 {
   static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
   static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
-  MemberList *ml = createMemberList(lt);
+  const auto &ml = m_memberLists.get(lt);
   ml->setNeedsSorting(
        ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) ||
        ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs));
@@ -1968,29 +1895,22 @@ void FileDefImpl::addMemberToList(MemberListType lt,MemberDef *md)
     MemberDefMutable *mdm = toMemberDefMutable(md);
     if (mdm)
     {
-      mdm->setSectionList(this,ml);
+      mdm->setSectionList(this,ml.get());
     }
   }
 }
 
 void FileDefImpl::sortMemberLists()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
   }
 
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      MemberList *mlg = mg->members();
-      if (mlg->needsSorting()) { mlg->sort(); mlg->setNeedsSorting(FALSE); }
-    }
+    MemberList *mlg = mg->members();
+    if (mlg->needsSorting()) { mlg->sort(); mlg->setNeedsSorting(FALSE); }
   }
 
   if (Config_getBool(SORT_BRIEF_DOCS))
@@ -2018,13 +1938,11 @@ void FileDefImpl::sortMemberLists()
 
 MemberList *FileDefImpl::getMemberList(MemberListType lt) const
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()==lt)
     {
-      return ml;
+      return ml.get();
     }
   }
   return 0;
@@ -2109,22 +2027,15 @@ QCString FileDefImpl::includedByDependencyGraphFileName() const
 
 void FileDefImpl::countMembers()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     ml->countDecMembers();
     ml->countDocMembers();
   }
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->countDecMembers();
-      mg->countDocMembers();
-    }
+    mg->countDecMembers();
+    mg->countDocMembers();
   }
 }
 
index 26e5de5..ba18c2b 100644 (file)
@@ -34,12 +34,10 @@ class MemberList;
 class FileDef;
 class FileList;
 class ClassDef;
-class ClassList;
 class MemberDef;
 class OutputList;
 class NamespaceDef;
 class NamespaceLinkedRefMap;
-class MemberGroupSDict;
 class PackageDef;
 class DirDef;
 class FTextStream;
@@ -106,8 +104,8 @@ class FileDef : public DefinitionMutable, public Definition
 
     virtual bool isDocumentationFile() const = 0;
 
-    virtual Definition *getSourceDefinition(int lineNr) const = 0;
-    virtual MemberDef *getSourceMember(int lineNr) const = 0;
+    virtual const Definition *getSourceDefinition(int lineNr) const = 0;
+    virtual const MemberDef *getSourceMember(int lineNr) const = 0;
 
     /*! Returns the absolute path of this file. */
     virtual QCString getPath() const = 0;
@@ -129,10 +127,10 @@ class FileDef : public DefinitionMutable, public Definition
     virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const = 0;
 
     virtual MemberList *getMemberList(MemberListType lt) const = 0;
-    virtual const QList<MemberList> &getMemberLists() const = 0;
+    virtual const MemberLists &getMemberLists() const = 0;
 
     /* user defined member groups */
-    virtual MemberGroupSDict *getMemberGroupSDict() const = 0;
+    virtual const MemberGroupList &getMemberGroups() const = 0;
     virtual NamespaceLinkedRefMap getNamespaces() const = 0;
     virtual ClassLinkedRefMap getClasses() const = 0;
 
@@ -148,7 +146,7 @@ class FileDef : public DefinitionMutable, public Definition
 
     //---------------------------------
 
-    virtual void addSourceRef(int line,Definition *d,MemberDef *md) = 0;
+    virtual void addSourceRef(int line,const Definition *d,const MemberDef *md) = 0;
 
     virtual void writeDocumentation(OutputList &ol) = 0;
     virtual void writeMemberPages(OutputList &ol) = 0;
index 0ddddd1..df6acf4 100644 (file)
@@ -159,8 +159,8 @@ struct fortrancodeYY_state
   QCString      exampleFile;
 
   FileDef *     sourceFileDef = 0;
-  Definition *  currentDefinition = 0;
-  MemberDef *   currentMemberDef = 0;
+  const Definition * currentDefinition = 0;
+  const MemberDef *  currentMemberDef = 0;
   bool          includeCodeFragment = false;
 
   char          stringStartSymbol = '\0'; // single or double quote
@@ -923,7 +923,7 @@ static void startCodeLine(yyscan_t yyscanner)
     //lineNumber.sprintf("%05d",yyextra->yyLineNr);
     //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
 
-    Definition *d   = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
+    const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
     //printf("startCodeLine %d d=%s\n", yyextra->yyLineNr,d ? d->name().data() : "<null>");
     if (!yyextra->includeCodeFragment && d)
     {
index e0d60bd..d8526d9 100644 (file)
@@ -66,7 +66,7 @@ class GroupDefImpl : public DefinitionMixin<GroupDef>
     virtual bool addClass(const ClassDef *def);
     virtual bool addNamespace(const NamespaceDef *def);
     virtual void addGroup(const GroupDef *def);
-    virtual void addPage(PageDef *def);
+    virtual void addPage(const PageDef *def);
     virtual void addExample(const PageDef *def);
     virtual void addDir(DirDef *dd);
     virtual bool insertMember(MemberDef *def,bool docOnly=FALSE);
@@ -95,24 +95,23 @@ class GroupDefImpl : public DefinitionMixin<GroupDef>
     virtual Definition *getGroupScope() const { return m_groupScope; }
 
     virtual MemberList *getMemberList(MemberListType lt) const;
-    virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; }
+    virtual const MemberLists &getMemberLists() const { return m_memberLists; }
 
     /* user defined member groups */
-    virtual MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; }
+    virtual const MemberGroupList &getMemberGroups() const { return m_memberGroups; }
 
     virtual FileList *      getFiles() const        { return m_fileList; }
-    virtual ClassLinkedRefMap getClasses() const    { return m_classes; }
-    virtual NamespaceLinkedRefMap getNamespaces() const  { return m_namespaces; }
-    virtual GroupList *     getSubGroups() const    { return m_groupList; }
-    virtual PageSDict *     getPages() const        { return m_pageDict; }
-    virtual const DirList & getDirs() const         { return m_dirList; }
-    virtual PageSDict *     getExamples() const     { return m_exampleDict; }
+    virtual const ClassLinkedRefMap &getClasses() const         { return m_classes; }
+    virtual const NamespaceLinkedRefMap &getNamespaces() const  { return m_namespaces; }
+    virtual const GroupList &getSubGroups() const               { return m_groups; }
+    virtual const PageLinkedRefMap &getPages() const            { return m_pages; }
+    virtual const DirList & getDirs() const                     { return m_dirList; }
+    virtual const PageLinkedRefMap &getExamples() const         { return m_examples; }
     virtual bool hasDetailedDescription() const;
     virtual void sortSubGroups();
 
   private:
     void addMemberListToGroup(MemberList *,bool (MemberDef::*)() const);
-    MemberList *createMemberList(MemberListType lt);
     void addMemberToList(MemberListType lt,MemberDef *md);
     void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title);
     void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title);
@@ -142,15 +141,15 @@ class GroupDefImpl : public DefinitionMixin<GroupDef>
     FileList *           m_fileList;            // list of files in the group
     ClassLinkedRefMap    m_classes;             // list of classes in the group
     NamespaceLinkedRefMap m_namespaces;         // list of namespaces in the group
-    GroupList *          m_groupList;           // list of sub groups.
-    PageSDict *          m_pageDict;            // list of pages in the group
-    PageSDict *          m_exampleDict;         // list of examples in the group
+    GroupList            m_groups;              // list of sub groups.
+    PageLinkedRefMap     m_pages;               // list of pages in the group
+    PageLinkedRefMap     m_examples;            // list of examples in the group
     DirList              m_dirList;             // list of directories in the group
     MemberList *         m_allMemberList;
     MemberNameInfoLinkedMap m_allMemberNameInfoLinkedMap;
     Definition *         m_groupScope;
-    QList<MemberList>    m_memberLists;
-    MemberGroupSDict *   m_memberGroupSDict;
+    MemberLists          m_memberLists;
+    MemberGroupList      m_memberGroups;
     bool                 m_subGrouping;
 
 };
@@ -168,9 +167,6 @@ GroupDefImpl::GroupDefImpl(const char *df,int dl,const char *na,const char *t,
                    const char *refFileName) : DefinitionMixin(df,dl,1,na)
 {
   m_fileList = new FileList;
-  m_groupList = new GroupList;
-  m_pageDict = new PageSDict(17);
-  m_exampleDict = new PageSDict(17);
   if (refFileName)
   {
     m_fileName=stripExtension(refFileName);
@@ -180,8 +176,6 @@ GroupDefImpl::GroupDefImpl(const char *df,int dl,const char *na,const char *t,
     m_fileName = convertNameToFile(QCString("group_")+na);
   }
   setGroupTitle( t );
-  m_memberGroupSDict = new MemberGroupSDict;
-  m_memberGroupSDict->setAutoDelete(TRUE);
 
   m_allMemberList = new MemberList(MemberListType_allMembersList);
 
@@ -193,11 +187,7 @@ GroupDefImpl::GroupDefImpl(const char *df,int dl,const char *na,const char *t,
 GroupDefImpl::~GroupDefImpl()
 {
   delete m_fileList;
-  delete m_groupList;
-  delete m_pageDict;
-  delete m_exampleDict;
   delete m_allMemberList;
-  delete m_memberGroupSDict;
 }
 
 void GroupDefImpl::setGroupTitle( const char *t )
@@ -218,9 +208,7 @@ void GroupDefImpl::setGroupTitle( const char *t )
 
 void GroupDefImpl::distributeMemberGroupDocumentation()
 {
-  MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-  MemberGroup *mg;
-  for (;(mg=mgli.current());++mgli)
+  for (const auto &mg : m_memberGroups)
   {
     mg->distributeMemberGroupDocumentation();
   }
@@ -230,16 +218,13 @@ void GroupDefImpl::findSectionsInDocumentation()
 {
   docFindSections(briefDescription(),this,docFile());
   docFindSections(documentation(),this,docFile());
-  MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-  MemberGroup *mg;
-  for (;(mg=mgli.current());++mgli)
+
+  for (const auto &mg : m_memberGroups)
   {
     mg->findSectionsInDocumentation(this);
   }
 
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_declarationLists)
     {
@@ -290,37 +275,33 @@ void GroupDefImpl::addDir(DirDef *def)
   m_dirList.push_back(def);
 }
 
-void GroupDefImpl::addPage(PageDef *def)
+void GroupDefImpl::addPage(const PageDef *def)
 {
   if (def->isHidden()) return;
   //printf("Making page %s part of a group\n",def->name.data());
-  m_pageDict->append(def->name(),def);
-  def->makePartOfGroup(this);
+  m_pages.add(def->name(),def);
+  const_cast<PageDef*>(def)->makePartOfGroup(this);
 }
 
 void GroupDefImpl::addExample(const PageDef *def)
 {
   if (def->isHidden()) return;
-  m_exampleDict->append(def->name(),def);
+  m_examples.add(def->name(),def);
 }
 
 
 void GroupDefImpl::addMembersToMemberGroup()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_declarationLists)
     {
-      ::addMembersToMemberGroup(ml,&m_memberGroupSDict,this);
+      ::addMembersToMemberGroup(ml.get(),&m_memberGroups,this);
     }
   }
 
   //printf("GroupDefImpl::addMembersToMemberGroup() memberGroupList=%d\n",memberGroupList->count());
-  MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-  MemberGroup *mg;
-  for (;(mg=mgli.current());++mgli)
+  for (const auto &mg : m_memberGroups)
   {
     mg->setInGroup(TRUE);
   }
@@ -560,16 +541,11 @@ bool GroupDefImpl::findGroup(const GroupDef *def) const
   {
     return TRUE;
   }
-  else if (m_groupList)
+  for (const auto &gd : m_groups)
   {
-    GroupListIterator it(*m_groupList);
-    GroupDef *gd;
-    for (;(gd=it.current());++it)
+    if (gd->findGroup(def))
     {
-      if (gd->findGroup(def))
-      {
-        return TRUE;
-      }
+      return TRUE;
     }
   }
   return FALSE;
@@ -581,33 +557,25 @@ void GroupDefImpl::addGroup(const GroupDef *def)
   //if (Config_getBool(SORT_MEMBER_DOCS))
   //  groupList->inSort(def);
   //else
-  m_groupList->append(def);
+  m_groups.push_back(def);
 }
 
 bool GroupDefImpl::isASubGroup() const
 {
-  GroupList *groups = partOfGroups();
-  return groups!=0 && groups->count()!=0;
+  return !partOfGroups().empty();
 }
 
 void GroupDefImpl::countMembers()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     ml->countDecMembers();
     ml->countDocMembers();
   }
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->countDecMembers();
-      mg->countDocMembers();
-    }
+    mg->countDecMembers();
+    mg->countDocMembers();
   }
 }
 
@@ -616,10 +584,10 @@ size_t GroupDefImpl::numDocMembers() const
   return m_fileList->count()+
          m_classes.size()+
          m_namespaces.size()+
-         m_groupList->count()+
+         m_groups.size()+
          m_allMemberList->count()+
-         m_pageDict->count()+
-         m_exampleDict->count();
+         m_pages.size()+
+         m_examples.size();
 }
 
 /*! Compute the HTML anchor names for all members in the group */
@@ -684,24 +652,19 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile)
         break;
       case LayoutDocEntry::GroupPageDocs:
         {
-          if (m_pageDict)
+          for (const auto &pd : m_pages)
           {
-            PageSDict::Iterator pdi(*m_pageDict);
-            PageDef *pd=0;
-            for (pdi.toFirst();(pd=pdi.current());++pdi)
+            QCString pageName = pd->getOutputFileBase();
+            if (pd->isLinkableInProject())
             {
-              QCString pageName = pd->getOutputFileBase();
-              if (pd->isLinkableInProject())
-              {
-                tagFile << "    <page>" << convertToXML(pageName) << "</page>" << endl;
-              }
+              tagFile << "    <page>" << convertToXML(pageName) << "</page>" << endl;
             }
           }
         }
         break;
       case LayoutDocEntry::GroupDirs:
         {
-          for(const auto dd : m_dirList)
+          for (const auto &dd : m_dirList)
           {
             if (dd->isLinkableInProject())
             {
@@ -712,16 +675,11 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile)
         break;
       case LayoutDocEntry::GroupNestedGroups:
         {
-          if (m_groupList)
+          for (const auto &gd : m_groups)
           {
-            QListIterator<GroupDef> it(*m_groupList);
-            GroupDef *gd;
-            for (;(gd=it.current());++it)
+            if (gd->isVisible())
             {
-              if (gd->isVisible())
-              {
-                tagFile << "    <subgroup>" << convertToXML(gd->name()) << "</subgroup>" << endl;
-              }
+              tagFile << "    <subgroup>" << convertToXML(gd->name()) << "</subgroup>" << endl;
             }
           }
         }
@@ -738,14 +696,9 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile)
         break;
       case LayoutDocEntry::MemberGroups:
         {
-          if (m_memberGroupSDict)
+          for (const auto &mg : m_memberGroups)
           {
-            MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-            MemberGroup *mg;
-            for (;(mg=mgli.current());++mgli)
-            {
-              mg->writeTagFile(tagFile);
-            }
+            mg->writeTagFile(tagFile);
           }
         }
         break;
@@ -764,7 +717,7 @@ void GroupDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title
      )
   {
     ol.pushGeneratorState();
-    if (m_pageDict->count()!=numDocMembers()) // not only pages -> classical layout
+    if (m_pages.size()!=numDocMembers()) // not only pages -> classical layout
     {
       ol.pushGeneratorState();
         ol.disable(OutputGenerator::Html);
@@ -919,14 +872,9 @@ void GroupDefImpl::writeNestedGroups(OutputList &ol,const QCString &title)
 {
   // write list of groups
   int count=0;
-  if (m_groupList->count()>0)
+  for (const auto &gd : m_groups)
   {
-    QListIterator<GroupDef> it(*m_groupList);
-    GroupDef *gd;
-    for (;(gd=it.current());++it)
-    {
-      if (gd->isVisible()) count++;
-    }
+    if (gd->isVisible()) count++;
   }
   if (count>0)
   {
@@ -934,13 +882,7 @@ void GroupDefImpl::writeNestedGroups(OutputList &ol,const QCString &title)
     ol.parseText(title);
     ol.endMemberHeader();
     ol.startMemberList();
-    if (Config_getBool(SORT_GROUP_NAMES))
-    {
-      m_groupList->sort();
-    }
-    QListIterator<GroupDef> it(*m_groupList);
-    GroupDef *gd;
-    for (;(gd=it.current());++it)
+    for (const auto &gd : m_groups)
     {
       if (gd->isVisible())
       {
@@ -1011,9 +953,7 @@ void GroupDefImpl::writeInlineClasses(OutputList &ol)
 
 void GroupDefImpl::writePageDocumentation(OutputList &ol)
 {
-  PageDef *pd=0;
-  PageSDict::Iterator pdi(*m_pageDict);
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto *pd : m_pages)
   {
     if (!pd->isReference())
     {
@@ -1036,16 +976,9 @@ void GroupDefImpl::writePageDocumentation(OutputList &ol)
 void GroupDefImpl::writeMemberGroups(OutputList &ol)
 {
   /* write user defined member groups */
-  if (m_memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    m_memberGroupSDict->sort();
-    /* write user defined member groups */
-    MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->writeDeclarations(ol,0,0,0,this);
-    }
+    mg->writeDeclarations(ol,0,0,0,this);
   }
 }
 
@@ -1106,7 +1039,7 @@ void GroupDefImpl::writeSummaryLinks(OutputList &ol) const
     if ((lde->kind()==LayoutDocEntry::GroupClasses && m_classes.declVisible()) ||
         (lde->kind()==LayoutDocEntry::GroupNamespaces && m_namespaces.declVisible()) ||
         (lde->kind()==LayoutDocEntry::GroupFiles && m_fileList->count()>0) ||
-        (lde->kind()==LayoutDocEntry::GroupNestedGroups && m_groupList->count()>0) ||
+        (lde->kind()==LayoutDocEntry::GroupNestedGroups && !m_groups.empty()) ||
         (lde->kind()==LayoutDocEntry::GroupDirs && !m_dirList.empty())
        )
     {
@@ -1324,9 +1257,7 @@ void GroupDefImpl::writeMemberPages(OutputList &ol)
   ol.pushGeneratorState();
   ol.disableAllBut(OutputGenerator::Html);
 
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_documentationLists)
     {
@@ -1371,7 +1302,6 @@ void GroupDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *current
       }
     }
   }
-
   ol.writeString("        </table>\n");
   ol.writeString("      </div>\n");
 }
@@ -1384,11 +1314,11 @@ void addClassToGroups(const Entry *root,ClassDef *cd)
 {
   for (const Grouping &g : root->groups)
   {
-    GroupDef *gd=0;
-    if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname)))
+    GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
+    if (gd && gd->addClass(cd))
     {
       ClassDefMutable *cdm = toClassDefMutable(cd);
-      if (cdm && gd->addClass(cdm))
+      if (cdm)
       {
         cdm->makePartOfGroup(gd);
       }
@@ -1402,17 +1332,14 @@ void addNamespaceToGroups(const Entry *root,NamespaceDef *nd)
   //printf("root->groups.size()=%d\n",root->groups.size());
   for (const Grouping &g : root->groups)
   {
-    GroupDef *gd=0;
+    GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
     //printf("group '%s'\n",s->data());
-    if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname)))
+    if (gd && gd->addNamespace(nd))
     {
-      if (gd->addNamespace(nd))
+      NamespaceDefMutable *ndm = toNamespaceDefMutable(nd);
+      if (ndm)
       {
-        NamespaceDefMutable *ndm = toNamespaceDefMutable(nd);
-        if (ndm)
-        {
-          ndm->makePartOfGroup(gd);
-        }
+        ndm->makePartOfGroup(gd);
       }
       //printf("Namespace %s: in group %s\n",nd->name().data(),s->data());
     }
@@ -1424,9 +1351,9 @@ void addDirToGroups(const Entry *root,DirDef *dd)
   //printf("*** root->groups.size()=%d\n",root->groups.size());
   for (const Grouping &g : root->groups)
   {
-    GroupDef *gd=0;
+    GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
     //printf("group '%s'\n",g->groupname.data());
-    if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname)))
+    if (gd)
     {
       gd->addDir(dd);
       dd->makePartOfGroup(gd);
@@ -1440,8 +1367,8 @@ void addGroupToGroups(const Entry *root,GroupDef *subGroup)
   //printf("addGroupToGroups for %s groups=%d\n",root->name.data(),root->groups.size());
   for (const Grouping &g : root->groups)
   {
-    GroupDef *gd=0;
-    if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname)))
+    GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
+    if (gd)
     {
       if (gd==subGroup)
       {
@@ -1475,7 +1402,7 @@ void addMemberToGroups(const Entry *root,MemberDef *md)
   {
     GroupDef *gd=0;
     if (!g.groupname.isEmpty() &&
-        (gd=Doxygen::groupSDict->find(g.groupname)) &&
+        (gd=Doxygen::groupLinkedMap->find(g.groupname)) &&
         g.pri >= pri)
     {
       if (fgd && gd!=fgd && g.pri==pri)
@@ -1558,11 +1485,11 @@ void addMemberToGroups(const Entry *root,MemberDef *md)
         {
           //printf("insertMember successful\n");
           mdm->setGroupDef(fgd,pri,root->fileName,root->startLine,!root->doc.isEmpty());
-        }
-        ClassDefMutable *cdm = toClassDefMutable(mdm->getClassDefOfAnonymousType());
-        if (cdm)
-        {
-          cdm->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0);
+          ClassDefMutable *cdm = toClassDefMutable(mdm->getClassDefOfAnonymousType());
+          if (cdm)
+          {
+            cdm->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0);
+          }
         }
       }
     }
@@ -1574,8 +1501,8 @@ void addExampleToGroups(const Entry *root,PageDef *eg)
 {
   for (const Grouping &g : root->groups)
   {
-    GroupDef *gd=0;
-    if (!g.groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g.groupname)))
+    GroupDef *gd = Doxygen::groupLinkedMap->find(g.groupname);
+    if (gd)
     {
       gd->addExample(eg);
       eg->makePartOfGroup(gd);
@@ -1601,15 +1528,11 @@ void GroupDefImpl::addListReferences()
              0
             );
   }
-  MemberGroupSDict::Iterator mgli(*m_memberGroupSDict);
-  MemberGroup *mg;
-  for (;(mg=mgli.current());++mgli)
+  for (const auto &mg : m_memberGroups)
   {
     mg->addListReferences(this);
   }
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_documentationLists)
     {
@@ -1618,30 +1541,12 @@ void GroupDefImpl::addListReferences()
   }
 }
 
-MemberList *GroupDefImpl::createMemberList(MemberListType lt)
-{
-  m_memberLists.setAutoDelete(TRUE);
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
-  {
-    if (ml->listType()==lt)
-    {
-      return ml;
-    }
-  }
-  // not found, create a new member list
-  ml = new MemberList(lt);
-  m_memberLists.append(ml);
-  ml->setInGroup(TRUE);
-  return ml;
-}
-
 void GroupDefImpl::addMemberToList(MemberListType lt,MemberDef *md)
 {
   static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
   static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
-  MemberList *ml = createMemberList(lt);
+  const auto &ml = m_memberLists.get(lt);
+  ml->setInGroup(true);
   ml->setNeedsSorting(
       ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) ||
       ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs));
@@ -1679,7 +1584,6 @@ static void groupClassesWithSameScope(Vec &vec)
               idx = k;
               k++;
             }
-            idx = std::distance(vec.begin(),it);
             // swap the items such that i is inserted after idx
             for (size_t j=i; j<idx; j++)
             {
@@ -1711,9 +1615,7 @@ static void groupClassesWithSameScope(Vec &vec)
 
 void GroupDefImpl::sortMemberLists()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
   }
@@ -1745,13 +1647,11 @@ void GroupDefImpl::sortMemberLists()
 
 MemberList *GroupDefImpl::getMemberList(MemberListType lt) const
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (;(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()==lt)
     {
-      return ml;
+      return ml.get();
     }
   }
   return 0;
@@ -1787,7 +1687,10 @@ void GroupDefImpl::removeMemberFromList(MemberListType lt,MemberDef *md)
 
 void GroupDefImpl::sortSubGroups()
 {
-  m_groupList->sort();
+  std::sort(m_groups.begin(),
+            m_groups.end(),
+            [](const auto &g1,const auto &g2)
+            { return qstrcmp(g1->groupTitle(),g2->groupTitle())<0; });
 }
 
 bool GroupDefImpl::isLinkableInProject() const
@@ -1813,8 +1716,10 @@ void GroupDefImpl::updateLanguage(const Definition *d)
 bool GroupDefImpl::hasDetailedDescription() const
 {
   static bool repeatBrief = Config_getBool(REPEAT_BRIEF);
-  return ((!briefDescription().isEmpty() && repeatBrief) || !documentation().isEmpty() || !inbodyDocumentation().isEmpty()) &&
-         (m_pageDict->count()!=numDocMembers());
+  return ((!briefDescription().isEmpty() && repeatBrief) ||
+         !documentation().isEmpty() ||
+         !inbodyDocumentation().isEmpty()) &&
+         (m_pages.size()!=numDocMembers());
 }
 
 // --- Cast functions
index 0b682c2..624a680 100644 (file)
 #include "definition.h"
 #include "dirdef.h"
 #include "layout.h"
+#include "membergroup.h"
+#include "linkedmap.h"
 
 class MemberList;
+class MemberLists;
 class FileList;
 class ClassLinkedRefMap;
 class NamespaceLinkedRefMap;
@@ -35,8 +38,7 @@ class NamespaceDef;
 class GroupList;
 class OutputList;
 class NamespaceSDict;
-class MemberGroupSDict;
-class PageSDict;
+class PageLinkedRefMap;
 class PageDef;
 class DirDef;
 class FTVHelp;
@@ -61,7 +63,7 @@ class GroupDef : public DefinitionMutable, public Definition
     virtual bool addClass(const ClassDef *def) = 0;
     virtual bool addNamespace(const NamespaceDef *def) = 0;
     virtual void addGroup(const GroupDef *def) = 0;
-    virtual void addPage(PageDef *def) = 0;
+    virtual void addPage(const PageDef *def) = 0;
     virtual void addExample(const PageDef *def) = 0;
     virtual void addDir(DirDef *dd) = 0;
     virtual bool insertMember(MemberDef *def,bool docOnly=FALSE) = 0;
@@ -90,18 +92,18 @@ class GroupDef : public DefinitionMutable, public Definition
     virtual Definition *getGroupScope() const = 0;
 
     virtual MemberList *getMemberList(MemberListType lt) const = 0;
-    virtual const QList<MemberList> &getMemberLists() const = 0;
+    virtual const MemberLists &getMemberLists() const = 0;
 
     /* user defined member groups */
-    virtual MemberGroupSDict *getMemberGroupSDict() const = 0;
+    virtual const MemberGroupList &getMemberGroups() const = 0;
 
     virtual FileList *      getFiles() const = 0;
-    virtual ClassLinkedRefMap getClasses() const = 0;
-    virtual NamespaceLinkedRefMap getNamespaces() const = 0;
-    virtual GroupList *     getSubGroups() const = 0;
-    virtual PageSDict *     getPages() const = 0;
+    virtual const ClassLinkedRefMap &getClasses() const = 0;
+    virtual const NamespaceLinkedRefMap &getNamespaces() const = 0;
+    virtual const GroupList &getSubGroups() const = 0;
+    virtual const PageLinkedRefMap &getPages() const = 0;
     virtual const DirList & getDirs() const = 0;
-    virtual PageSDict *     getExamples() const = 0;
+    virtual const PageLinkedRefMap &getExamples() const = 0;
     virtual bool hasDetailedDescription() const = 0;
     virtual void sortSubGroups() = 0;
 
@@ -117,36 +119,12 @@ const GroupDef      *toGroupDef(const Definition *d);
 
 // ------------------
 
-
-/** A sorted dictionary of GroupDef objects. */
-class GroupSDict : public SDict<GroupDef>
+class GroupLinkedMap : public LinkedMap<GroupDef>
 {
-  public:
-    GroupSDict(uint size) : SDict<GroupDef>(size) {}
-    virtual ~GroupSDict() {}
-  private:
-    int compareValues(const GroupDef *item1,const GroupDef *item2) const
-    {
-      return qstrcmp(item1->groupTitle(),item2->groupTitle());
-    }
 };
 
-/** A list of GroupDef objects. */
-class GroupList : public QList<GroupDef>
+class GroupList : public std::vector<const GroupDef *>
 {
-  public:
-    int compareValues(const GroupDef *item1,const GroupDef *item2) const
-    {
-      return qstrcmp(item1->groupTitle(),item2->groupTitle());
-    }
-};
-
-/** An iterator for GroupDef objects in a GroupList. */
-class GroupListIterator : public QListIterator<GroupDef>
-{
-  public:
-    GroupListIterator(const GroupList &l) : QListIterator<GroupDef>(l) {}
-    virtual ~GroupListIterator() {}
 };
 
 void addClassToGroups    (const Entry *root,ClassDef *cd);
index cd615e4..e186c37 100644 (file)
@@ -2350,7 +2350,7 @@ static bool quickLinkVisible(LayoutNavEntry::Kind kind)
     case LayoutNavEntry::Files:              return documentedHtmlFiles>0 && showFiles;
     case LayoutNavEntry::FileList:           return documentedHtmlFiles>0 && showFiles;
     case LayoutNavEntry::FileGlobals:        return documentedFileMembers[FMHL_All]>0;
-    case LayoutNavEntry::Examples:           return Doxygen::exampleSDict->count()>0;
+    case LayoutNavEntry::Examples:           return !Doxygen::exampleLinkedMap->empty();
     case LayoutNavEntry::Interfaces:         return annotatedInterfaces>0;
     case LayoutNavEntry::InterfaceList:      return annotatedInterfaces>0;
     case LayoutNavEntry::InterfaceIndex:     return annotatedInterfaces>0;
index a1b0deb..af511bb 100644 (file)
@@ -109,19 +109,6 @@ struct IndexField
   bool     reversed;
 };
 
-/** Sorted dictionary of IndexField objects. */
-class IndexFieldSDict : public SDict<IndexField>
-{
-  public:
-    IndexFieldSDict() : SDict<IndexField>(17) {}
-   ~IndexFieldSDict() {}
- private:
-    int compareValues(const IndexField *item1, const IndexField *item2) const
-    {
-      return qstricmp(item1->name,item2->name);
-    }
-};
-
 /** A helper class for HtmlHelp that manages a two level index in
  *  alphabetical order.
  */
index e68f7eb..e2e5ea1 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <stdlib.h>
 
+#include <array>
+
 #include <assert.h>
 #include <qtextstream.h>
 #include <qdatetime.h>
@@ -145,29 +147,25 @@ static void endIndexHierarchy(OutputList &ol,int level)
 
 //----------------------------------------------------------------------------
 
-class MemberIndexList : public QList<MemberDef>
-{
-  public:
-    typedef const MemberDef ElementType;
-    MemberIndexList(uint letter) : QList<MemberDef>(), m_letter(letter) {}
-    ~MemberIndexList() {}
-    int compareValues(const MemberDef *md1, const MemberDef *md2) const
-    {
-      int result = qstricmp(md1->name(),md2->name());
-      if (result==0)
-      {
-        result = qstricmp(md1->qualifiedName(),md2->qualifiedName());
-      }
-      return result;
-    }
-    uint letter() const { return m_letter; }
-  private:
-    uint m_letter;
-};
+using MemberIndexList = std::vector<const MemberDef *>;
+using MemberIndexMap = std::map<std::string,MemberIndexList>;
+
+static std::array<MemberIndexMap,CMHL_Total> g_classIndexLetterUsed;
+static std::array<MemberIndexMap,FMHL_Total> g_fileIndexLetterUsed;
+static std::array<MemberIndexMap,NMHL_Total> g_namespaceIndexLetterUsed;
 
-static LetterToIndexMap<MemberIndexList> g_memberIndexLetterUsed[CMHL_Total];
-static LetterToIndexMap<MemberIndexList> g_fileIndexLetterUsed[FMHL_Total];
-static LetterToIndexMap<MemberIndexList> g_namespaceIndexLetterUsed[NMHL_Total];
+void MemberIndexMap_add(MemberIndexMap &map,const std::string &letter,const MemberDef *md)
+{
+  auto it = map.find(letter);
+  if (it!=map.end())
+  {
+    it->second.push_back(md);
+  }
+  else
+  {
+    map.insert(std::make_pair(letter,std::vector<const MemberDef*>({md})));
+  }
+}
 
 const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
 
@@ -357,7 +355,7 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,
                        const QCString &name,const QCString &anchor,
                        bool addToIndex=TRUE,bool preventSeparateIndex=FALSE)
 {
-  bool hasMembers = def->getMemberLists().count()>0 || def->getMemberGroupSDict()!=0;
+  bool hasMembers = !def->getMemberLists().empty() || !def->getMemberGroups().empty();
   Doxygen::indexList->addContentsItem(hasMembers,name,
                                      def->getReference(),def->getOutputFileBase(),anchor,
                                      hasMembers && !preventSeparateIndex,
@@ -400,7 +398,7 @@ void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,
       {
         for (const auto &cd : def->getClasses())
         {
-          if (cd->isLinkable() && (cd->partOfGroups()==0 || def->definitionType()==Definition::TypeGroup))
+          if (cd->isLinkable() && (cd->partOfGroups().empty() || def->definitionType()==Definition::TypeGroup))
           {
             static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
             bool isNestedClass = def->definitionType()==Definition::TypeClass;
@@ -536,7 +534,7 @@ static void writeClassTreeToOutput(OutputList &ol,const BaseClassList &bcl,int l
 
 //----------------------------------------------------------------------------
 
-static bool dirHasVisibleChildren(DirDef *dd)
+static bool dirHasVisibleChildren(const DirDef *dd)
 {
   if (dd->hasDocumentation()) return TRUE;
 
@@ -555,7 +553,7 @@ static bool dirHasVisibleChildren(DirDef *dd)
     }
   }
 
-  for(const auto subdd : dd->subDirs())
+  for(const auto &subdd : dd->subDirs())
   {
     if (dirHasVisibleChildren(subdd))
     {
@@ -566,7 +564,7 @@ static bool dirHasVisibleChildren(DirDef *dd)
 }
 
 //----------------------------------------------------------------------------
-static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv,bool addToIndex)
+static void writeDirTreeNode(OutputList &ol, const DirDef *dd, int level, FTVHelp* ftv,bool addToIndex)
 {
   if (level>20)
   {
@@ -615,7 +613,7 @@ static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv
   if (dd->subDirs().size()>0)
   {
     startIndexHierarchy(ol,level+1);
-    for(const auto subdd : dd->subDirs())
+    for(const auto &subdd : dd->subDirs())
     {
       writeDirTreeNode(ol,subdd,level+1,ftv,addToIndex);
     }
@@ -728,13 +726,11 @@ static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
   startIndexHierarchy(ol,0);
   if (fullPathNames)
   {
-    SDict<DirDef>::Iterator dli(*Doxygen::directories);
-    DirDef *dd;
-    for (dli.toFirst();(dd=dli.current());++dli)
+    for (const auto &dd : *Doxygen::dirLinkedMap)
     {
       if (dd->getOuterScope()==Doxygen::globalScope)
       {
-        writeDirTreeNode(ol,dd,0,ftv,addToIndex);
+        writeDirTreeNode(ol,dd.get(),0,ftv,addToIndex);
       }
     }
   }
@@ -1571,7 +1567,7 @@ static void writeClassTree(const ListType &cl,FTVHelp *ftv,bool addToIndex,bool
           addMembersToIndex(cd,LayoutDocManager::Class,
                             cd->displayName(FALSE),
                             cd->anchor(),
-                            addToIndex && cd->partOfGroups()==0 && !cd->isSimple());
+                            addToIndex && cd->partOfGroups().empty() && !cd->isSimple());
         }
         if (count>0)
         {
@@ -2024,11 +2020,6 @@ inline bool isId1(int c)
   return (c<127 && c>31); // printable ASCII character
 }
 
-static QCString letterToString(uint letter)
-{
-  return QString(QChar(letter)).utf8();
-}
-
 static QCString letterToLabel(const char *startLetter)
 {
   const char *p = startLetter;
@@ -2052,44 +2043,6 @@ static QCString letterToLabel(const char *startLetter)
   return result;
 }
 
-static QCString letterToLabel(uint startLetter)
-{
-  char s[11]; // max 0x12345678 + '\0'
-  if (isId1(startLetter)) // printable ASCII character
-  {
-    s[0]=(char)startLetter;
-    s[1]=0;
-  }
-  else
-  {
-    const char hex[]="0123456789abcdef";
-    int i=0;
-    s[i++]='0';
-    s[i++]='x';
-    if (startLetter>(1<<24)) // 4 byte character
-    {
-      s[i++]=hex[(startLetter>>28)&0xf];
-      s[i++]=hex[(startLetter>>24)&0xf];
-    }
-    if (startLetter>(1<<16)) // 3 byte character
-    {
-      s[i++]=hex[(startLetter>>20)&0xf];
-      s[i++]=hex[(startLetter>>16)&0xf];
-    }
-    if (startLetter>(1<<8)) // 2 byte character
-    {
-      s[i++]=hex[(startLetter>>12)&0xf];
-      s[i++]=hex[(startLetter>>8)&0xf];
-    }
-    // one byte character
-    s[i++]=hex[(startLetter>>4)&0xf];
-    s[i++]=hex[(startLetter>>0)&0xf];
-    s[i++]=0;
-  }
-  return s;
-}
-
-
 //----------------------------------------------------------------------------
 
 /** Class representing a cell in the alphabetical class index. */
@@ -2544,7 +2497,7 @@ static void writeAnnotatedExceptionIndex(OutputList &ol)
 }
 
 //----------------------------------------------------------------------------
-static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
+static void writeClassLinkForMember(OutputList &ol,const MemberDef *md,const char *separator,
                              QCString &prevClassName)
 {
   const ClassDef *cd=md->getClassDef();
@@ -2558,7 +2511,7 @@ static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *sep
   }
 }
 
-static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
+static void writeFileLinkForMember(OutputList &ol,const MemberDef *md,const char *separator,
                              QCString &prevFileName)
 {
   const FileDef *fd=md->getFileDef();
@@ -2572,7 +2525,7 @@ static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *sepa
   }
 }
 
-static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
+static void writeNamespaceLinkForMember(OutputList &ol,const MemberDef *md,const char *separator,
                              QCString &prevNamespaceName)
 {
   const NamespaceDef *nd=md->getNamespaceDef();
@@ -2586,14 +2539,14 @@ static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char
   }
 }
 
-static void writeMemberList(OutputList &ol,bool useSections,int page,
-                            const LetterToIndexMap<MemberIndexList> &memberLists,
+static void writeMemberList(OutputList &ol,bool useSections,const std::string &page,
+                            const MemberIndexMap &memberIndexMap,
                             Definition::DefType type)
 {
   int index = (int)type;
   ASSERT(index<3);
 
-  typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
+  typedef void (*writeLinkForMember_t)(OutputList &ol,const MemberDef *md,const char *separator,
                                    QCString &prevNamespaceName);
 
   // each index tab has its own write function
@@ -2608,20 +2561,26 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
   bool first=TRUE;
   bool firstSection=TRUE;
   bool firstItem=TRUE;
-  MemberIndexList *ml;
-  SIntDict<MemberIndexList>::Iterator it(memberLists);
-  for (it.toFirst();(ml=it.current());++it)
+  const MemberIndexList *mil = 0;
+  std::string letter;
+  for (const auto &kv : memberIndexMap)
   {
-    if (page!=-1)
+    if (!page.empty()) // specific page mode
+    {
+      auto it = memberIndexMap.find(page);
+      if (it != memberIndexMap.end())
+      {
+        mil = &it->second;
+        letter = page;
+      }
+    }
+    else // do all pages
     {
-      ml = memberLists[page];
-      it.toLast();
+      mil = &kv.second;
+      letter = kv.first;
     }
-    if (ml==0 || ml->count()==0) continue;
-    ml->sort();
-    QListIterator<MemberDef> mli(*ml);
-    MemberDef *md;
-    for (mli.toFirst();(md=mli.current());++mli)
+    if (mil==0 || mil->empty()) continue;
+    for (const auto &md : *mil)
     {
       const char *sep;
       bool isFunc=!md->isObjCMethod() &&
@@ -2636,10 +2595,9 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
         {
           if (!firstItem)    ol.endItemListItem();
           if (!firstSection) ol.endItemList();
-          QCString cs = letterToLabel(ml->letter());
-          QCString cl = letterToString(ml->letter());
+          QCString cs = letterToLabel(letter.c_str());
           QCString anchor=(QCString)"index_"+convertToId(cs);
-          QCString title=(QCString)"- "+cl+" -";
+          QCString title=(QCString)"- "+letter.c_str()+" -";
           ol.startSection(anchor,title,SectionType::Subsection);
           ol.docify(title);
           ol.endSection(anchor,SectionType::Subsection);
@@ -2677,6 +2635,10 @@ static void writeMemberList(OutputList &ol,bool useSections,int page,
         writeLinkForMemberMap[index](ol,md,sep,prevDefName);
       }
     }
+    if (!page.empty())
+    {
+      break;
+    }
   }
   if (!firstItem) ol.endItemListItem();
   ol.endItemList();
@@ -2690,11 +2652,11 @@ void initClassMemberIndices()
   for (j=0;j<CMHL_Total;j++)
   {
     documentedClassMembers[j]=0;
-    g_memberIndexLetterUsed[j].clear();
+    g_classIndexLetterUsed[j].clear();
   }
 }
 
-void addClassMemberNameToIndex(MemberDef *md)
+void addClassMemberNameToIndex(const MemberDef *md)
 {
   static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
   const ClassDef *cd=0;
@@ -2706,8 +2668,8 @@ void addClassMemberNameToIndex(MemberDef *md)
   {
     QCString n = md->name();
     int index = getPrefixIndex(n);
-    uint letter = getUtf8CodeToLower(n,index);
-    if (!n.isEmpty())
+    char letter[MAX_UTF8_CHAR_SIZE];
+    if (getUtf8Char(n.data()+index,letter,CaseModifier::ToLower)>0)
     {
       bool isFriendToHide = hideFriendCompounds &&
         (QCString(md->typeString())=="friend class" ||
@@ -2717,48 +2679,48 @@ void addClassMemberNameToIndex(MemberDef *md)
           (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
          )
       {
-        g_memberIndexLetterUsed[CMHL_All].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_All],letter,md);
         documentedClassMembers[CMHL_All]++;
       }
       if (md->isFunction()  || md->isSlot() || md->isSignal())
       {
-        g_memberIndexLetterUsed[CMHL_Functions].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_Functions],letter,md);
         documentedClassMembers[CMHL_Functions]++;
       }
       else if (md->isVariable())
       {
-        g_memberIndexLetterUsed[CMHL_Variables].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_Variables],letter,md);
         documentedClassMembers[CMHL_Variables]++;
       }
       else if (md->isTypedef())
       {
-        g_memberIndexLetterUsed[CMHL_Typedefs].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_Typedefs],letter,md);
         documentedClassMembers[CMHL_Typedefs]++;
       }
       else if (md->isEnumerate())
       {
-        g_memberIndexLetterUsed[CMHL_Enums].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_Enums],letter,md);
         documentedClassMembers[CMHL_Enums]++;
       }
       else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
       {
-        g_memberIndexLetterUsed[CMHL_EnumValues].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_EnumValues],letter,md);
         documentedClassMembers[CMHL_EnumValues]++;
       }
       else if (md->isProperty())
       {
-        g_memberIndexLetterUsed[CMHL_Properties].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_Properties],letter,md);
         documentedClassMembers[CMHL_Properties]++;
       }
       else if (md->isEvent())
       {
-        g_memberIndexLetterUsed[CMHL_Events].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_Events],letter,md);
         documentedClassMembers[CMHL_Events]++;
       }
       else if (md->isRelated() || md->isForeign() ||
                (md->isFriend() && !isFriendToHide))
       {
-        g_memberIndexLetterUsed[CMHL_Related].append(letter,md);
+        MemberIndexMap_add(g_classIndexLetterUsed[CMHL_Related],letter,md);
         documentedClassMembers[CMHL_Related]++;
       }
     }
@@ -2777,55 +2739,55 @@ void initNamespaceMemberIndices()
   }
 }
 
-void addNamespaceMemberNameToIndex(MemberDef *md)
+void addNamespaceMemberNameToIndex(const MemberDef *md)
 {
   const NamespaceDef *nd=md->getNamespaceDef();
   if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
   {
     QCString n = md->name();
     int index = getPrefixIndex(n);
-    uint letter = getUtf8CodeToLower(n,index);
-    if (!n.isEmpty())
+    char letter[MAX_UTF8_CHAR_SIZE];
+    if (getUtf8Char(n.data()+index,letter,CaseModifier::ToLower)>0)
     {
       if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
       {
-        g_namespaceIndexLetterUsed[NMHL_All].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_All],letter,md);
         documentedNamespaceMembers[NMHL_All]++;
       }
 
       if (md->isFunction())
       {
-        g_namespaceIndexLetterUsed[NMHL_Functions].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_Functions],letter,md);
         documentedNamespaceMembers[NMHL_Functions]++;
       }
       else if (md->isVariable())
       {
-        g_namespaceIndexLetterUsed[NMHL_Variables].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_Variables],letter,md);
         documentedNamespaceMembers[NMHL_Variables]++;
       }
       else if (md->isTypedef())
       {
-        g_namespaceIndexLetterUsed[NMHL_Typedefs].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_Typedefs],letter,md);
         documentedNamespaceMembers[NMHL_Typedefs]++;
       }
       else if (md->isSequence())
       {
-        g_namespaceIndexLetterUsed[NMHL_Sequences].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_Sequences],letter,md);
         documentedNamespaceMembers[NMHL_Sequences]++;
       }
       else if (md->isDictionary())
       {
-        g_namespaceIndexLetterUsed[NMHL_Dictionaries].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_Dictionaries],letter,md);
         documentedNamespaceMembers[NMHL_Dictionaries]++;
       }
       else if (md->isEnumerate())
       {
-        g_namespaceIndexLetterUsed[NMHL_Enums].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_Enums],letter,md);
         documentedNamespaceMembers[NMHL_Enums]++;
       }
       else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
       {
-        g_namespaceIndexLetterUsed[NMHL_EnumValues].append(letter,md);
+        MemberIndexMap_add(g_namespaceIndexLetterUsed[NMHL_EnumValues],letter,md);
         documentedNamespaceMembers[NMHL_EnumValues]++;
       }
     }
@@ -2844,60 +2806,60 @@ void initFileMemberIndices()
   }
 }
 
-void addFileMemberNameToIndex(MemberDef *md)
+void addFileMemberNameToIndex(const MemberDef *md)
 {
   const FileDef *fd=md->getFileDef();
   if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
   {
     QCString n = md->name();
     int index = getPrefixIndex(n);
-    uint letter = getUtf8CodeToLower(n,index);
-    if (!n.isEmpty())
+    char letter[MAX_UTF8_CHAR_SIZE];
+    if (getUtf8Char(n.data()+index,letter,CaseModifier::ToLower)>0)
     {
       if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
       {
-        g_fileIndexLetterUsed[FMHL_All].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_All],letter,md);
         documentedFileMembers[FMHL_All]++;
       }
 
       if (md->isFunction())
       {
-        g_fileIndexLetterUsed[FMHL_Functions].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_Functions],letter,md);
         documentedFileMembers[FMHL_Functions]++;
       }
       else if (md->isVariable())
       {
-        g_fileIndexLetterUsed[FMHL_Variables].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_Variables],letter,md);
         documentedFileMembers[FMHL_Variables]++;
       }
       else if (md->isTypedef())
       {
-        g_fileIndexLetterUsed[FMHL_Typedefs].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_Typedefs],letter,md);
         documentedFileMembers[FMHL_Typedefs]++;
       }
       else if (md->isSequence())
       {
-        g_fileIndexLetterUsed[FMHL_Sequences].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_Sequences],letter,md);
         documentedFileMembers[FMHL_Sequences]++;
       }
       else if (md->isDictionary())
       {
-        g_fileIndexLetterUsed[FMHL_Dictionaries].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_Dictionaries],letter,md);
         documentedFileMembers[FMHL_Dictionaries]++;
       }
       else if (md->isEnumerate())
       {
-        g_fileIndexLetterUsed[FMHL_Enums].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_Enums],letter,md);
         documentedFileMembers[FMHL_Enums]++;
       }
       else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
       {
-        g_fileIndexLetterUsed[FMHL_EnumValues].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_EnumValues],letter,md);
         documentedFileMembers[FMHL_EnumValues]++;
       }
       else if (md->isDefine())
       {
-        g_fileIndexLetterUsed[FMHL_Defines].append(letter,md);
+        MemberIndexMap_add(g_fileIndexLetterUsed[FMHL_Defines],letter,md);
         documentedFileMembers[FMHL_Defines]++;
       }
     }
@@ -2906,19 +2868,47 @@ void addFileMemberNameToIndex(MemberDef *md)
 
 //----------------------------------------------------------------------------
 
+static void sortMemberIndexList(MemberIndexMap &map)
+{
+  for (auto &kv : map)
+  {
+    std::sort(kv.second.begin(),kv.second.end(),
+              [](const MemberDef *md1,const MemberDef *md2)
+              {
+                int result = qstricmp(md1->name(),md2->name());
+                return result==0 ? qstricmp(md1->qualifiedName(),md2->qualifiedName())<0 : result<0;
+              });
+  }
+}
+
+void sortMemberIndexLists()
+{
+  for (auto &idx : g_classIndexLetterUsed)
+  {
+    sortMemberIndexList(idx);
+  }
+  for (auto &idx : g_fileIndexLetterUsed)
+  {
+    sortMemberIndexList(idx);
+  }
+  for (auto &idx : g_namespaceIndexLetterUsed)
+  {
+    sortMemberIndexList(idx);
+  }
+}
+
+//----------------------------------------------------------------------------
+
 static void writeQuickMemberIndex(OutputList &ol,
-    const LetterToIndexMap<MemberIndexList> &charUsed,uint page,
+    const MemberIndexMap &map,const std::string &page,
     QCString fullName,bool multiPage)
 {
   bool first=TRUE;
   startQuickIndexList(ol,TRUE);
-  SIntDict<MemberIndexList>::Iterator it(charUsed);
-  MemberIndexList *ml;
-  for (it.toFirst();(ml=it.current());++it)
+  for (const auto &kv : map)
   {
-    uint i = ml->letter();
-    QCString is = letterToLabel(i);
-    QCString ci = letterToString(i);
+    QCString ci = kv.first.c_str();
+    QCString is = letterToLabel(ci);
     QCString anchor;
     QCString extension=Doxygen::htmlFileExtension;
     if (!multiPage)
@@ -2926,8 +2916,8 @@ static void writeQuickMemberIndex(OutputList &ol,
     else if (first)
       anchor=fullName+extension+"#index_";
     else
-      anchor=fullName+"_"+letterToLabel(i)+extension+"#index_";
-    startQuickIndexItem(ol,anchor+convertToId(is),i==page,TRUE,first);
+      anchor=fullName+"_"+is+extension+"#index_";
+    startQuickIndexItem(ol,anchor+convertToId(is),kv.first==page,TRUE,first);
     ol.writeString(ci);
     endQuickIndexItem(ol);
     first=FALSE;
@@ -2945,7 +2935,7 @@ struct CmhlInfo
   QCString title;
 };
 
-static const CmhlInfo *getCmhlInfo(int hl)
+static const CmhlInfo *getCmhlInfo(size_t hl)
 {
   static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
   static bool vhdlOpt    = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
@@ -2996,19 +2986,17 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h
   }
 
   bool first=TRUE;
-  SIntDict<MemberIndexList>::Iterator it(g_memberIndexLetterUsed[hl]);
-  MemberIndexList *ml;
-  for (it.toFirst();(ml=it.current());++it)
+  for (const auto &kv : g_classIndexLetterUsed[hl])
   {
-    uint page = ml->letter();
+    std::string page = kv.first;
     QCString fileName = getCmhlInfo(hl)->fname;
     if (multiPageIndex)
     {
+      QCString cs = page;
       if (!first)
       {
-        fileName+="_"+letterToLabel(page);
+        fileName+="_"+letterToLabel(cs);
       }
-      QCString cs = letterToString(page);
       if (addToIndex)
       {
         Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
@@ -3051,7 +3039,7 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h
         // quick alphabetical index
         if (quickIndex)
         {
-          writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
+          writeQuickMemberIndex(ol,g_classIndexLetterUsed[hl],page,
               getCmhlInfo(hl)->fname,multiPageIndex);
         }
       }
@@ -3076,8 +3064,8 @@ static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight h
     }
 
     writeMemberList(ol,quickIndex,
-        multiPageIndex?page:-1,
-        g_memberIndexLetterUsed[hl],
+        multiPageIndex ? page : std::string(),
+        g_classIndexLetterUsed[hl],
         Definition::TypeClass);
     endFile(ol);
     first=FALSE;
@@ -3124,7 +3112,7 @@ struct FmhlInfo
   QCString title;
 };
 
-static const FmhlInfo *getFmhlInfo(int hl)
+static const FmhlInfo *getFmhlInfo(size_t hl)
 {
   static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
   static bool vhdlOpt    = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
@@ -3175,19 +3163,17 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
   }
 
   bool first=TRUE;
-  SIntDict<MemberIndexList>::Iterator it(g_fileIndexLetterUsed[hl]);
-  MemberIndexList *ml;
-  for (it.toFirst();(ml=it.current());++it)
+  for (const auto &kv : g_fileIndexLetterUsed[hl])
   {
-    uint page = ml->letter();
+    std::string page = kv.first;
     QCString fileName = getFmhlInfo(hl)->fname;
     if (multiPageIndex)
     {
+      QCString cs = page;
       if (!first)
       {
-        fileName+="_"+letterToLabel(page);
+        fileName+="_"+letterToLabel(cs);
       }
-      QCString cs = letterToString(page);
       if (addToIndex)
       {
         Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
@@ -3252,7 +3238,7 @@ static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
     }
 
     writeMemberList(ol,quickIndex,
-        multiPageIndex?page:-1,
+        multiPageIndex ? page : std::string(),
         g_fileIndexLetterUsed[hl],
         Definition::TypeFile);
     endFile(ol);
@@ -3297,7 +3283,7 @@ struct NmhlInfo
   QCString title;
 };
 
-static const NmhlInfo *getNmhlInfo(int hl)
+static const NmhlInfo *getNmhlInfo(size_t hl)
 {
   static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
   static bool vhdlOpt    = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
@@ -3351,19 +3337,17 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol,
   }
 
   bool first=TRUE;
-  SIntDict<MemberIndexList>::Iterator it(g_namespaceIndexLetterUsed[hl]);
-  MemberIndexList *ml;
-  for (it.toFirst();(ml=it.current());++it)
+  for (const auto &kv : g_namespaceIndexLetterUsed[hl])
   {
-    uint page = ml->letter();
+    std::string page = kv.first;
     QCString fileName = getNmhlInfo(hl)->fname;
     if (multiPageIndex)
     {
+      QCString cs = page;
       if (!first)
       {
-        fileName+="_"+letterToLabel(page);
+        fileName+="_"+letterToLabel(cs);
       }
-      QCString cs = letterToString(page);
       if (addToIndex)
       {
         Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
@@ -3428,7 +3412,7 @@ static void writeNamespaceMemberIndexFiltered(OutputList &ol,
     }
 
     writeMemberList(ol,quickIndex,
-        multiPageIndex?page:-1,
+        multiPageIndex ? page : std::string(),
         g_namespaceIndexLetterUsed[hl],
         Definition::TypeNamespace);
     endFile(ol);
@@ -3469,7 +3453,7 @@ static void writeNamespaceMemberIndex(OutputList &ol)
 
 static void writeExampleIndex(OutputList &ol)
 {
-  if (Doxygen::exampleSDict->count()==0) return;
+  if (Doxygen::exampleLinkedMap->empty()) return;
   ol.pushGeneratorState();
   ol.disable(OutputGenerator::Man);
   ol.disable(OutputGenerator::Docbook);
@@ -3496,9 +3480,7 @@ static void writeExampleIndex(OutputList &ol)
   ol.endTextBlock();
 
   ol.startItemList();
-  PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::exampleLinkedMap)
   {
     ol.startItemListItem();
     QCString n=pd->getOutputFileBase();
@@ -3537,15 +3519,13 @@ static void writeExampleIndex(OutputList &ol)
 static void countRelatedPages(int &docPages,int &indexPages)
 {
   docPages=indexPages=0;
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
-    if ( pd->visibleInIndex())
+    if (pd->visibleInIndex())
     {
       indexPages++;
     }
-    if ( pd->documentedPage())
+    if (pd->documentedPage())
     {
       docPages++;
     }
@@ -3565,7 +3545,7 @@ static bool mainPageHasOwnTitle()
   return !projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0;
 }
 
-static void writePages(PageDef *pd,FTVHelp *ftv)
+static void writePages(const PageDef *pd,FTVHelp *ftv)
 {
   //printf("writePages()=%s pd=%p mainpage=%p\n",pd->name().data(),pd,Doxygen::mainPage);
   LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
@@ -3592,7 +3572,7 @@ static void writePages(PageDef *pd,FTVHelp *ftv)
           pd->getReference(),pd->getOutputFileBase(),
           0,hasSubPages,TRUE,pd);
     }
-    if (addToIndex && pd!=Doxygen::mainPage)
+    if (addToIndex && pd!=Doxygen::mainPage.get())
     {
       Doxygen::indexList->addContentsItem(
           hasSubPages || hasSections,pageTitle,
@@ -3602,24 +3582,18 @@ static void writePages(PageDef *pd,FTVHelp *ftv)
   }
   if (hasSubPages && ftv) ftv->incContentsDepth();
   bool doIndent = (hasSections || hasSubPages) &&
-                  (pd!=Doxygen::mainPage || mainPageHasOwnTitle());
+                  (pd!=Doxygen::mainPage.get() || mainPageHasOwnTitle());
   if (doIndent)
   {
     Doxygen::indexList->incContentsDepth();
   }
   if (hasSections)
   {
-    pd->addSectionsToIndex();
+    const_cast<PageDef*>(pd)->addSectionsToIndex();
   }
-  PageSDict *subPages = pd->getSubPages();
-  if (subPages)
+  for (const auto &subPage : pd->getSubPages())
   {
-    PageSDict::Iterator pi(*subPages);
-    PageDef *subPage;
-    for (pi.toFirst();(subPage=pi.current());++pi)
-    {
-      writePages(subPage,ftv);
-    }
+    writePages(subPage,ftv);
   }
   if (hasSubPages && ftv) ftv->decContentsDepth();
   if (doIndent)
@@ -3649,16 +3623,14 @@ static void writePageIndex(OutputList &ol)
 
   {
     FTVHelp* ftv = new FTVHelp(FALSE);
-    PageSDict::Iterator pdi(*Doxygen::pageSDict);
-    PageDef *pd=0;
-    for (pdi.toFirst();(pd=pdi.current());++pdi)
+    for (const auto &pd : *Doxygen::pageLinkedMap)
     {
       if ((pd->getOuterScope()==0 ||
           pd->getOuterScope()->definitionType()!=Definition::TypePage) && // not a sub page
           !pd->isReference() // not an external page
          )
       {
-        writePages(pd,ftv);
+        writePages(pd.get(),ftv);
       }
     }
     QGString outStr;
@@ -3680,9 +3652,7 @@ static void writePageIndex(OutputList &ol)
 static int countGroups()
 {
   int count=0;
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     if (!gd->isReference())
     {
@@ -3698,9 +3668,7 @@ static int countGroups()
 static int countDirs()
 {
   int count=0;
-  SDict<DirDef>::Iterator dli(*Doxygen::directories);
-  DirDef *dd;
-  for (dli.toFirst();(dd=dli.current());++dli)
+  for (const auto &dd : *Doxygen::dirLinkedMap)
   {
     if (dd->isLinkableInProject())
     {
@@ -3764,7 +3732,7 @@ void writeGraphInfo(OutputList &ol)
 /*!
  * write groups as hierarchical trees
  */
-static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex)
+static void writeGroupTreeNode(OutputList &ol, const GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex)
 {
   //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
   //bool vhdlOpt    = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
@@ -3786,14 +3754,12 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp*
   {
     //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
     // write group info
-    bool hasSubGroups = gd->getSubGroups()->count()>0;
-    bool hasSubPages = gd->getPages()->count()>0;
+    bool hasSubGroups = !gd->getSubGroups().empty();
+    bool hasSubPages  = !gd->getPages().empty();
     size_t numSubItems = 0;
     if (1 /*Config_getBool(TOC_EXPAND)*/)
     {
-      QListIterator<MemberList> mli(gd->getMemberLists());
-      MemberList *ml;
-      for (mli.toFirst();(ml=mli.current());++mli)
+      for (const auto &ml : gd->getMemberLists())
       {
         if (ml->listType()&MemberListType_documentationLists)
         {
@@ -3804,7 +3770,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp*
       numSubItems += gd->getClasses().size();
       numSubItems += gd->getFiles()->count();
       numSubItems += gd->getDirs().size();
-      numSubItems += gd->getPages()->count();
+      numSubItems += gd->getPages().size();
     }
 
     bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
@@ -3885,7 +3851,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp*
         {
           //bool nestedClassInSameGroup =
           //    cd->getOuterScope() && cd->getOuterScope()->definitionType()==Definition::TypeClass &&
-          //    cd->getOuterScope()->partOfGroups()!=0 && cd->getOuterScope()->partOfGroups()->contains(gd);
+          //    cd->getOuterScope()->partOfGroups().empty() && cd->getOuterScope()->partOfGroups()->contains(gd);
           //printf("===== GroupClasses: %s visible=%d nestedClassInSameGroup=%d\n",cd->name().data(),cd->isVisible(),nestedClassInSameGroup);
           if (cd->isVisible() /*&& !nestedClassInSameGroup*/)
           {
@@ -3944,9 +3910,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp*
       }
       else if (lde->kind()==LayoutDocEntry::GroupPageDocs && addToIndex)
       {
-        SDict<PageDef>::Iterator it(*gd->getPages());
-        PageDef *pd;
-        for (;(pd=it.current());++it)
+        for (const auto &pd : gd->getPages())
         {
           const SectionInfo *si=0;
           if (!pd->name().isEmpty()) si=SectionManager::instance().find(pd->name());
@@ -3966,7 +3930,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp*
           }
           if (hasSections)
           {
-            pd->addSectionsToIndex();
+            const_cast<PageDef*>(pd)->addSectionsToIndex();
           }
           writePages(pd,0);
           if (hasSections || hasSubPages)
@@ -3977,12 +3941,10 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp*
       }
       else if (lde->kind()==LayoutDocEntry::GroupNestedGroups)
       {
-        if (gd->getSubGroups()->count()>0)
+        if (!gd->getSubGroups().empty())
         {
           startIndexHierarchy(ol,level+1);
-          QListIterator<GroupDef> gli(*gd->getSubGroups());
-          GroupDef *subgd = 0;
-          for (gli.toFirst();(subgd=gli.current());++gli)
+          for (const auto &subgd : gd->getSubGroups())
           {
             writeGroupTreeNode(ol,subgd,level+1,ftv,addToIndex);
           }
@@ -4013,11 +3975,9 @@ static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
     ol.disable(OutputGenerator::Html);
   }
   startIndexHierarchy(ol,0);
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
-    writeGroupTreeNode(ol,gd,0,ftv,addToIndex);
+    writeGroupTreeNode(ol,gd.get(),0,ftv,addToIndex);
   }
   endIndexHierarchy(ol,0);
   if (ftv)
@@ -4026,41 +3986,6 @@ static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
   }
 }
 
-#if 0
-static void writeGroupTree(GroupDef *gd,FTVHelp *ftv,int level,bool addToIndex)
-{
-  static bool externalGroups = Config_getBool(EXTERNAL_GROUPS);
-  /* Some groups should appear twice under different parent-groups.
-   * That is why we should not check if it was visited
-   */
-  if ((!gd->isASubGroup() || level>0) &&
-      gd->isVisible() &&
-      (!gd->isReference() || externalGroups) // hide external groups by default
-     )
-  {
-    if (ftv)
-    {
-      ftv->addContentsItem(hasSubGroups,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0);
-      ftv->incContentsDepth();
-    }
-    if (ftv)
-    {
-      ftv->decContentsDepth();
-    }
-  }
-}
-
-static void writeGroupTree(FTVHelp *ftv,bool addToIndex)
-{
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
-  {
-    writeGroupTree(gd,ftv,0,addToIndex);
-  }
-}
-#endif
-
 //----------------------------------------------------------------------------
 
 static void writeGroupIndex(OutputList &ol)
@@ -4133,62 +4058,6 @@ static void writeGroupIndex(OutputList &ol)
 
 //----------------------------------------------------------------------------
 
-#if 0
-static void writeDirIndex(OutputList &ol)
-{
-  if (documentedDirs==0) return;
-  ol.pushGeneratorState();
-  ol.disable(OutputGenerator::Man);
-  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs);
-  QCString title = lne ? lne->title() : theTranslator->trDirectories();
-  bool addToIndex=FALSE; //lne==0 || lne->visible();
-
-  startFile(ol,"dirs",0,title,HLI_Directories);
-  startTitle(ol,0);
-  ol.parseText(title);
-  endTitle(ol,0,0);
-  ol.startContents();
-  ol.startTextBlock();
-
-  if (addToIndex)
-  {
-    Doxygen::indexList->addContentsItem(TRUE,title,0,"dirs",0,TRUE,TRUE);
-    Doxygen::indexList->incContentsDepth();
-  }
-  ol.parseText(lne ? lne->intro() : theTranslator->trDirDescription());
-  ol.endTextBlock();
-
-  FTVHelp* ftv = 0;
-  bool treeView=Config_getBool(USE_INLINE_TREES);
-  if (treeView)
-  {
-    ftv = new FTVHelp(FALSE);
-  }
-
-  writeDirHierarchy(ol,ftv,addToIndex);
-
-  if (ftv)
-  {
-    QGString outStr;
-    FTextStream t(&outStr);
-    ftv->generateTreeViewInline(t);
-    ol.pushGeneratorState();
-    ol.disableAllBut(OutputGenerator::Html);
-    ol.writeString(outStr);
-    ol.popGeneratorState();
-    delete ftv;
-  }
-  if (addToIndex)
-  {
-    Doxygen::indexList->decContentsDepth();
-  }
-  endFile(ol);
-  ol.popGeneratorState();
-}
-#endif
-
-//----------------------------------------------------------------------------
-
 static void writeUserGroupStubPage(OutputList &ol,LayoutNavEntry *lne)
 {
   if (lne->baseFile().left(9)=="usergroup")
@@ -4275,7 +4144,7 @@ static void writeIndex(OutputList &ol)
     }
     if (Doxygen::mainPage->hasSubPages() || Doxygen::mainPage->hasSections())
     {
-      writePages(Doxygen::mainPage,0);
+      writePages(Doxygen::mainPage.get(),0);
     }
   }
 
@@ -4307,7 +4176,7 @@ static void writeIndex(OutputList &ol)
       ol.startHeaderSection();
       ol.startTitleHead(0);
       ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->getStartBodyLine(),
-                  Doxygen::mainPage,0,Doxygen::mainPage->title(),TRUE,FALSE,
+                  Doxygen::mainPage.get(),0,Doxygen::mainPage->title(),TRUE,FALSE,
                   0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
       headerWritten = TRUE;
     }
@@ -4343,7 +4212,7 @@ static void writeIndex(OutputList &ol)
     }
 
     ol.startTextBlock();
-    ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
+    ol.generateDoc(defFileName,defLine,Doxygen::mainPage.get(),0,
                 Doxygen::mainPage->documentation(),TRUE,FALSE,
                 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
     ol.endTextBlock();
@@ -4382,7 +4251,7 @@ static void writeIndex(OutputList &ol)
   if (!Config_getString(PROJECT_NUMBER).isEmpty())
   {
     ol.startProjectNumber();
-    ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString(PROJECT_NUMBER),FALSE,FALSE,
+    ol.generateDoc(defFileName,defLine,Doxygen::mainPage.get(),0,Config_getString(PROJECT_NUMBER),FALSE,FALSE,
                    0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
     ol.endProjectNumber();
   }
@@ -4411,14 +4280,12 @@ static void writeIndex(OutputList &ol)
   {
     //ol.parseText(projPrefix+theTranslator->trPageDocumentation());
     //ol.endIndexSection(isPageDocumentation);
-    PageSDict::Iterator pdi(*Doxygen::pageSDict);
-    PageDef *pd=pdi.toFirst();
     bool first=Doxygen::mainPage==0;
-    for (pdi.toFirst();(pd=pdi.current());++pdi)
+    for (const auto &pd : *Doxygen::pageLinkedMap)
     {
       if (!pd->getGroupDef() && !pd->isReference() &&
           (!pd->hasParentPage() ||                    // not inside other page
-           (Doxygen::mainPage==pd->getOuterScope()))  // or inside main page
+           (Doxygen::mainPage.get()==pd->getOuterScope()))  // or inside main page
          )
       {
         bool isCitationPage = pd->name()=="citelist";
@@ -4579,7 +4446,7 @@ static void writeIndex(OutputList &ol)
     ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
     ol.endIndexSection(isFileDocumentation);
   }
-  if (Doxygen::exampleSDict->count()>0)
+  if (!Doxygen::exampleLinkedMap->empty())
   {
     ol.startIndexSection(isExampleDocumentation);
     ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
@@ -4595,7 +4462,7 @@ static void writeIndex(OutputList &ol)
     startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
     ol.startContents();
     ol.startTextBlock();
-    ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
+    ol.generateDoc(defFileName,defLine,Doxygen::mainPage.get(),0,
                 Doxygen::mainPage->documentation(),FALSE,FALSE,
                 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)
                );
@@ -4948,7 +4815,7 @@ static bool quickLinkVisible(LayoutNavEntry::Kind kind)
     case LayoutNavEntry::Files:              return documentedHtmlFiles>0 && showFiles;
     case LayoutNavEntry::FileList:           return documentedHtmlFiles>0 && showFiles;
     case LayoutNavEntry::FileGlobals:        return documentedFileMembers[FMHL_All]>0;
-    case LayoutNavEntry::Examples:           return Doxygen::exampleSDict->count()>0;
+    case LayoutNavEntry::Examples:           return !Doxygen::exampleLinkedMap->empty();
     case LayoutNavEntry::None:             // should never happen, means not properly initialized
       assert(kind != LayoutNavEntry::None);
       return FALSE;
@@ -4956,14 +4823,15 @@ static bool quickLinkVisible(LayoutNavEntry::Kind kind)
   return FALSE;
 }
 
-template<class T>
+template<class T,std::size_t total>
 void renderMemberIndicesAsJs(FTextStream &t,
-    int total,const int *numDocumented,const LetterToIndexMap<MemberIndexList> *memberLists,
-    const T *(*getInfo)(int hl))
+    const int *numDocumented,
+    const std::array<MemberIndexMap,total> &memberLists,
+    const T *(*getInfo)(size_t hl))
 {
   // index items per category member lists
   bool firstMember=TRUE;
-  for (int i=0;i<total;i++)
+  for (std::size_t i=0;i<total;i++)
   {
     if (numDocumented[i]>0)
     {
@@ -4988,14 +4856,12 @@ void renderMemberIndicesAsJs(FTextStream &t,
         }
         t << ",children:[" << endl;
         bool firstLetter=TRUE;
-        SIntDict<MemberIndexList>::Iterator it(memberLists[i]);
-        MemberIndexList *ml;
-        for (it.toFirst();(ml=it.current());++it)
+        for (const auto &kv : memberLists[i])
         {
           if (!firstLetter) t << "," << endl;
-          uint letter = ml->letter();
-          QCString is = letterToLabel(letter);
-          QCString ci = letterToString(letter);
+          std::string letter = kv.first;
+          QCString ci = letter;
+          QCString is = letterToLabel(ci);
           QCString anchor;
           QCString extension=Doxygen::htmlFileExtension;
           QCString fullName = getInfo(i)->fname;
@@ -5044,17 +4910,17 @@ static bool renderQuickLinksAsJs(FTextStream &t,LayoutNavEntry *root,bool first)
         bool hasChildren=FALSE;
         if (entry->kind()==LayoutNavEntry::NamespaceMembers)
         {
-          renderMemberIndicesAsJs(t,NMHL_Total,documentedNamespaceMembers,
+          renderMemberIndicesAsJs(t,documentedNamespaceMembers,
                                   g_namespaceIndexLetterUsed,getNmhlInfo);
         }
         else if (entry->kind()==LayoutNavEntry::ClassMembers)
         {
-          renderMemberIndicesAsJs(t,CMHL_Total,documentedClassMembers,
-                                  g_memberIndexLetterUsed,getCmhlInfo);
+          renderMemberIndicesAsJs(t,documentedClassMembers,
+                                  g_classIndexLetterUsed,getCmhlInfo);
         }
         else if (entry->kind()==LayoutNavEntry::FileGlobals)
         {
-          renderMemberIndicesAsJs(t,FMHL_Total,documentedFileMembers,
+          renderMemberIndicesAsJs(t,documentedFileMembers,
                                   g_fileIndexLetterUsed,getFmhlInfo);
         }
         else // recursive into child list
index 6cca60d..5088c46 100644 (file)
@@ -257,9 +257,10 @@ void endFileWithNavPath(const Definition *d,OutputList &ol);
 void initClassMemberIndices();
 void initFileMemberIndices();
 void initNamespaceMemberIndices();
-void addClassMemberNameToIndex(MemberDef *md);
-void addFileMemberNameToIndex(MemberDef *md);
-void addNamespaceMemberNameToIndex(MemberDef *md);
+void addClassMemberNameToIndex(const MemberDef *md);
+void addFileMemberNameToIndex(const MemberDef *md);
+void addNamespaceMemberNameToIndex(const MemberDef *md);
+void sortMemberIndexLists();
 QCString fixSpaces(const QCString &s);
 
 #endif
index fbb6530..e6c9363 100644 (file)
@@ -951,6 +951,26 @@ void LatexDocVisitor::visitPost(DocHtmlListItem *)
 //  m_t << "\\end{alltt}\\normalsize " << endl;
 //}
 
+static bool listIsNested(const DocNode *n)
+{
+  bool isNested=false;
+  if (n)
+  {
+    if (n->kind()==DocNode::Kind_HtmlDescList && ((DocHtmlDescList *)n)->attribs().find("class") == "reflist") return false;
+    n  = n->parent();
+  }
+  while (n && !isNested)
+  {
+    if (n->kind()==DocNode::Kind_HtmlDescList)
+    {
+      QCString val = ((DocHtmlDescList *)n)->attribs().find("class");
+      isNested = (val!="reflist");
+    }
+    n  = n->parent();
+  }
+  return isNested;
+}
+
 void LatexDocVisitor::visitPre(DocHtmlDescList *dl)
 {
   if (m_hide) return;
@@ -961,6 +981,7 @@ void LatexDocVisitor::visitPre(DocHtmlDescList *dl)
   }
   else
   {
+    if (listIsNested(dl)) m_t << "\n\\hfill";
     m_t << "\n\\begin{DoxyDescription}";
   }
 }
index bfde4d1..ece344f 100644 (file)
@@ -998,9 +998,7 @@ void LatexGenerator::startIndexSection(IndexSections is)
       break;
     case isModuleDocumentation:
       {
-        GroupSDict::Iterator gli(*Doxygen::groupSDict);
-        GroupDef *gd;
-        for (gli.toFirst();(gd=gli.current());++gli)
+        for (const auto &gd : *Doxygen::groupLinkedMap)
         {
           if (!gd->isReference())
           {
@@ -1013,9 +1011,7 @@ void LatexGenerator::startIndexSection(IndexSections is)
       break;
     case isDirDocumentation:
       {
-        SDict<DirDef>::Iterator dli(*Doxygen::directories);
-        DirDef *dd;
-        for (dli.toFirst();(dd=dli.current());++dli)
+        for (const auto &dd : *Doxygen::dirLinkedMap)
         {
           if (dd->isLinkableInProject())
           {
@@ -1144,48 +1140,34 @@ void LatexGenerator::endIndexSection(IndexSections is)
       break;
     case isModuleDocumentation:
       {
-        GroupSDict::Iterator gli(*Doxygen::groupSDict);
-        GroupDef *gd;
         bool found=FALSE;
-        for (gli.toFirst();(gd=gli.current()) && !found;++gli)
+        for (const auto &gd : *Doxygen::groupLinkedMap)
         {
           if (!gd->isReference())
           {
-            t << "}\n\\input{" << gd->getOutputFileBase() << "}\n";
-            found=TRUE;
-          }
-        }
-        for (;(gd=gli.current());++gli)
-        {
-          if (!gd->isReference())
-          {
-            //if (compactLatex) t << "\\input"; else t << "\\include";
-            t << "\\include";
-            t << "{" << gd->getOutputFileBase() << "}\n";
+            if (!found)
+            {
+              t << "}\n";
+              found=TRUE;
+            }
+            t << "\\input{" << gd->getOutputFileBase() << "}\n";
           }
         }
       }
       break;
     case isDirDocumentation:
       {
-        SDict<DirDef>::Iterator dli(*Doxygen::directories);
-        DirDef *dd;
         bool found=FALSE;
-        for (dli.toFirst();(dd=dli.current()) && !found;++dli)
+        for (const auto &dd : *Doxygen::dirLinkedMap)
         {
           if (dd->isLinkableInProject())
           {
-            t << "}\n\\input{" << dd->getOutputFileBase() << "}\n";
-            found=TRUE;
-          }
-        }
-        for (;(dd=dli.current());++dli)
-        {
-          if (dd->isLinkableInProject())
-          {
-            //if (compactLatex) t << "\\input"; else t << "\\include";
-            t << "\\input";
-            t << "{" << dd->getOutputFileBase() << "}\n";
+            if (!found)
+            {
+              t << "}\n";
+              found = TRUE;
+            }
+            t << "\\input{" << dd->getOutputFileBase() << "}\n";
           }
         }
       }
@@ -1256,28 +1238,18 @@ void LatexGenerator::endIndexSection(IndexSections is)
     case isExampleDocumentation:
       {
         t << "}\n";
-        PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-        PageDef *pd=pdi.toFirst();
-        if (pd)
+        for (const auto &pd : *Doxygen::exampleLinkedMap)
         {
           t << "\\input{" << pd->getOutputFileBase() << "}\n";
         }
-        for (++pdi;(pd=pdi.current());++pdi)
-        {
-          //if (compactLatex) t << "\\input" ; else t << "\\include";
-          t << "\\input";
-          t << "{" << pd->getOutputFileBase() << "}\n";
-        }
       }
       break;
     case isPageDocumentation:
       {
         t << "}\n";
 #if 0
-        PageSDict::Iterator pdi(*Doxygen::pageSDict);
-        PageDef *pd=pdi.toFirst();
         bool first=TRUE;
-        for (pdi.toFirst();(pd=pdi.current());++pdi)
+        for (const auto *pd : Doxygen::pageLinkedMap)
         {
           if (!pd->getGroupDef() && !pd->isReference())
           {
index 340ac99..93d143d 100644 (file)
@@ -2734,8 +2734,8 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
   if (id.startsWith("autotoc_md")) id = "";
   int indentLevel=title.isEmpty() ? 0 : -1;
   markdown.setIndentLevel(indentLevel);
-  QCString titleFn = QFileInfo(fileName).baseName().utf8();
   QCString fn      = QFileInfo(fileName).fileName().utf8();
+  QCString titleFn = stripExtensionGeneral(fn,getFileNameExtension(fn));
   QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
   bool wasEmpty = id.isEmpty();
   if (wasEmpty) id = markdownFileNameToId(fileName);
index ecc07d7..8f09347 100644 (file)
@@ -195,7 +195,7 @@ class MemberDefImpl : public DefinitionMixin<MemberDefMutable>
     virtual void setEnumBaseType(const QCString &type);
     virtual QCString enumBaseType() const;
     virtual bool hasExamples() const;
-    virtual ExampleSDict *getExamples() const;
+    virtual const ExampleList &getExamples() const;
     virtual bool isPrototype() const;
     virtual const ArgumentList &argumentList() const;
     virtual ArgumentList &argumentList();
@@ -247,7 +247,7 @@ class MemberDefImpl : public DefinitionMixin<MemberDefMutable>
     virtual void setBitfields(const char *s);
     virtual void setMaxInitLines(int lines);
     virtual void setMemberClass(const ClassDef *cd);
-    virtual void setSectionList(const Definition *container,MemberList *sl);
+    virtual void setSectionList(const Definition *container,const MemberList *sl);
     virtual void setGroupDef(const GroupDef *gd,Grouping::GroupPri_t pri,
                      const QCString &fileName,int startLine,bool hasDocs,
                      MemberDef *member=0);
@@ -655,7 +655,7 @@ class MemberDefAliasImpl : public DefinitionAliasMixin<MemberDef>
     { return getMdAlias()->enumBaseType(); }
     virtual bool hasExamples() const
     { return getMdAlias()->hasExamples(); }
-    virtual ExampleSDict *getExamples() const
+    virtual const ExampleList &getExamples() const
     { return getMdAlias()->getExamples(); }
     virtual bool isPrototype() const
     { return getMdAlias()->isPrototype(); }
@@ -1198,7 +1198,7 @@ class MemberDefImpl::IMPL
     MemberDef  *memDec = 0;       // member declaration for this definition
     ClassDef   *relatedAlso = 0;  // points to class marked by relatedAlso
 
-    ExampleSDict *exampleSDict = 0; // a dictionary of all examples for quick access
+    ExampleList examples;     // a dictionary of all examples for quick access
 
     QCString type;            // return actual type
     QCString accessorType;    // return type that tell how to get to this member
@@ -1240,7 +1240,7 @@ class MemberDefImpl::IMPL
                                    // as its type then this is computed by
                                    // getClassDefOfAnonymousType() and
                                    // cached here.
-    SDict<MemberList> *classSectionSDict = 0; // not accessible
+    std::map<const Definition *,const MemberList *> sectionMap;
 
     const MemberDef *groupAlias = 0;    // Member containing the definition
     int grpId = 0;                // group id
@@ -1302,8 +1302,6 @@ class MemberDefImpl::IMPL
 MemberDefImpl::IMPL::IMPL() :
     enumFields(0),
     redefinedBy(0),
-    exampleSDict(0),
-    classSectionSDict(0),
     category(0),
     categoryRelation(0),
     declLine(-1),
@@ -1315,9 +1313,7 @@ MemberDefImpl::IMPL::IMPL() :
 MemberDefImpl::IMPL::~IMPL()
 {
   delete redefinedBy;
-  delete exampleSDict;
   delete enumFields;
-  delete classSectionSDict;
 }
 
 void MemberDefImpl::IMPL::init(Definition *d,
@@ -1338,7 +1334,6 @@ void MemberDefImpl::IMPL::init(Definition *d,
   memDec=0;
   group=0;
   grpId=-1;
-  exampleSDict=0;
   enumFields=0;
   enumScope=0;
   livesInsideEnum=FALSE;
@@ -1391,7 +1386,6 @@ void MemberDefImpl::IMPL::init(Definition *d,
   }
   metaData = meta;
   templateMaster = 0;
-  classSectionSDict = 0;
   docsForDefinition = TRUE;
   isTypedefValCached = FALSE;
   cachedTypedefValue = 0;
@@ -1462,9 +1456,7 @@ MemberDef *MemberDefImpl::deepCopy() const
   *result->m_impl = *m_impl;
   // clear pointers owned by object
   result->m_impl->redefinedBy= 0;
-  result->m_impl->exampleSDict=0;
   result->m_impl->enumFields=0;
-  result->m_impl->classSectionSDict=0;
   // replace pointers owned by the object by deep copies
   if (m_impl->redefinedBy)
   {
@@ -1475,15 +1467,6 @@ MemberDef *MemberDefImpl::deepCopy() const
       result->insertReimplementedBy(md);
     }
   }
-  if (m_impl->exampleSDict)
-  {
-    ExampleSDict::Iterator it(*m_impl->exampleSDict);
-    Example *e;
-    for (it.toFirst();(e=it.current());++it)
-    {
-      result->addExample(e->anchor,e->name,e->file);
-    }
-  }
   if (m_impl->enumFields)
   {
     MemberListIterator mli(*m_impl->enumFields);
@@ -1497,16 +1480,6 @@ MemberDef *MemberDefImpl::deepCopy() const
   result->m_impl->tArgList = m_impl->tArgList;
   result->m_impl->typeConstraints = m_impl->typeConstraints;
   result->setDefinitionTemplateParameterLists(m_impl->defTmpArgLists);
-  if (m_impl->classSectionSDict)
-  {
-    result->m_impl->classSectionSDict = new SDict<MemberList>(7);
-    SDict<MemberList>::IteratorDict it(*m_impl->classSectionSDict);
-    MemberList *ml;
-    for (it.toFirst();(ml=it.current());++it)
-    {
-      result->m_impl->classSectionSDict->append(it.currentKey(),ml);
-    }
-  }
   result->m_impl->declArgList = m_impl->declArgList;
   return result;
 }
@@ -1598,30 +1571,15 @@ void MemberDefImpl::insertEnumField(MemberDef *md)
   m_impl->enumFields->append(md);
 }
 
-bool MemberDefImpl::addExample(const char *anchor,const char *nameStr,
-                           const char *file)
+bool MemberDefImpl::addExample(const char *anchor,const char *nameStr, const char *file)
 {
   //printf("%s::addExample(%s,%s,%s)\n",name().data(),anchor,nameStr,file);
-  if (m_impl->exampleSDict==0) m_impl->exampleSDict = new ExampleSDict;
-  if (m_impl->exampleSDict->find(nameStr)==0)
-  {
-    //printf("Add reference to example %s to member %s\n",nameStr,name.data());
-    Example *e=new Example;
-    e->anchor=anchor;
-    e->name=nameStr;
-    e->file=file;
-    m_impl->exampleSDict->inSort(nameStr,e);
-    return TRUE;
-  }
-  return FALSE;
+  return m_impl->examples.inSort(Example(anchor,nameStr,file));
 }
 
 bool MemberDefImpl::hasExamples() const
 {
-  if (m_impl->exampleSDict==0)
-    return FALSE;
-  else
-    return m_impl->exampleSDict->count()>0;
+  return !m_impl->examples.empty();
 }
 
 QCString MemberDefImpl::getOutputFileBase() const
@@ -2000,12 +1958,17 @@ bool MemberDefImpl::isBriefSectionVisible() const
   //    "", //getFileDef()->name().data(),
   //    argsString());
 
-  MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
-  //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
-  //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
-  bool hasDocs = hasDocumentation() ||
+  auto it = Doxygen::memberGroupInfoMap.find(m_impl->grpId);
+  bool hasDocs = hasDocumentation();
+  if (it!=Doxygen::memberGroupInfoMap.end())
+  {
+    auto &info = it->second;
+    //printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
+    //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
+    hasDocs = hasDocs ||
                   // part of a documented member group
-                 (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
+                 (m_impl->grpId!=-1 && !(info->doc.isEmpty() && info->header.isEmpty()));
+  }
 
   // only include static members with file/namespace scope if
   // explicitly enabled in the config file
@@ -2996,7 +2959,7 @@ void MemberDefImpl::_writeExamples(OutputList &ol) const
   {
     ol.startExamples();
     ol.startDescForItem();
-    writeExample(ol,m_impl->exampleSDict);
+    writeExamples(ol,m_impl->examples);
     ol.endDescForItem();
     ol.endExamples();
   }
@@ -4378,23 +4341,14 @@ void MemberDefImpl::addListReference(Definition *)
 
 const MemberList *MemberDefImpl::getSectionList(const Definition *container) const
 {
-  const Definition *d = container;
-  char key[20];
-  sprintf(key,"%p",(void*)d);
-  return (d!=0 && m_impl->classSectionSDict) ? m_impl->classSectionSDict->find(key) : 0;
+  auto it = m_impl->sectionMap.find(container);
+  return it!=m_impl->sectionMap.end() ? it->second : 0;
 }
 
-void MemberDefImpl::setSectionList(const Definition *container,MemberList *sl)
+void MemberDefImpl::setSectionList(const Definition *container,const MemberList *sl)
 {
   //printf("MemberDefImpl::setSectionList(%s,%p) name=%s\n",d->name().data(),sl,name().data());
-  const Definition *d= container;
-  char key[20];
-  sprintf(key,"%p",(void*)d);
-  if (m_impl->classSectionSDict==0)
-  {
-    m_impl->classSectionSDict = new SDict<MemberList>(7);
-  }
-  m_impl->classSectionSDict->append(key,sl);
+  m_impl->sectionMap.insert(std::make_pair(container,sl));
 }
 
 Specifier MemberDefImpl::virtualness(int count) const
@@ -5348,9 +5302,9 @@ const MemberList *MemberDefImpl::enumFieldList() const
   return m_impl->enumFields;
 }
 
-ExampleSDict *MemberDefImpl::getExamples() const
+const ExampleList &MemberDefImpl::getExamples() const
 {
-  return m_impl->exampleSDict;
+  return m_impl->examples;
 }
 
 bool MemberDefImpl::isPrototype() const
index 11d403c..ff0e300 100644 (file)
@@ -34,7 +34,7 @@ class GroupDef;
 class FileDef;
 class MemberList;
 class MemberGroup;
-class ExampleSDict;
+class ExampleList;
 class OutputList;
 class GroupDef;
 class QTextStream;
@@ -214,7 +214,7 @@ class MemberDef : public Definition
     virtual QCString enumBaseType() const = 0;
 
     virtual bool hasExamples() const = 0;
-    virtual ExampleSDict *getExamples() const = 0;
+    virtual const ExampleList &getExamples() const = 0;
     virtual bool isPrototype() const = 0;
 
     // argument related members
@@ -308,7 +308,7 @@ class MemberDefMutable : public DefinitionMutable, public MemberDef
     virtual void setBitfields(const char *s) = 0;
     virtual void setMaxInitLines(int lines) = 0;
     virtual void setMemberClass(const ClassDef *cd) = 0;
-    virtual void setSectionList(const Definition *container,MemberList *sl) = 0;
+    virtual void setSectionList(const Definition *container,const MemberList *sl) = 0;
     virtual void setGroupDef(const GroupDef *gd,Grouping::GroupPri_t pri,
                      const QCString &fileName,int startLine,bool hasDocs,
                      MemberDef *member=0) = 0;
index e1dae25..5b0c621 100644 (file)
@@ -19,6 +19,8 @@
 #define MEMBERGROUP_H
 
 #include <vector>
+#include <map>
+#include <memory>
 
 #include <qlist.h>
 #include "sortdict.h"
@@ -105,31 +107,8 @@ class MemberGroup
     RefItemVector m_xrefListItems;
 };
 
-/** A list of MemberGroup objects. */
-class MemberGroupList : public QList<MemberGroup>
-{
-};
-
-/** An iterator for MemberGroup objects in a MemberGroupList. */
-class MemberGroupListIterator : public QListIterator<MemberGroup>
-{
-  public:
-    MemberGroupListIterator(const MemberGroupList &l) :
-      QListIterator<MemberGroup>(l) {}
-};
-
-/** A sorted dictionary of MemberGroup objects. */
-class MemberGroupSDict : public SIntDict<MemberGroup>
-{
-  public:
-    MemberGroupSDict(int size=17) : SIntDict<MemberGroup>(size) {}
-   ~MemberGroupSDict() {}
- private:
-    int compareValues(const MemberGroup *item1,const MemberGroup *item2) const
-    {
-      return item1->groupId() - item2->groupId();
-    }
-};
+using MemberGroupRefList = std::vector<MemberGroup *>;
+using MemberGroupList = std::vector< std::unique_ptr<MemberGroup> >;
 
 /** Data collected for a member group */
 struct MemberGroupInfo
@@ -143,4 +122,6 @@ struct MemberGroupInfo
   RefItemVector m_sli;
 };
 
+using MemberGroupInfoMap = std::unordered_map< int,std::unique_ptr<MemberGroupInfo> >;
+
 #endif
index bbc6e5d..c71390c 100644 (file)
@@ -35,7 +35,6 @@
 MemberList::MemberList() : m_listType(MemberListType_pubMethods)
 {
   //printf("%p: MemberList::MemberList()\n",this);
-  memberGroupList=0;
   m_numDecMembers=-1; // special value indicating that value needs to be computed
   m_numDecEnumValues=0;
   m_numDocMembers=-1; // special value indicating that value needs to be computed
@@ -48,7 +47,6 @@ MemberList::MemberList() : m_listType(MemberListType_pubMethods)
 MemberList::MemberList(MemberListType lt) : m_listType(lt)
 {
   //printf("%p: MemberList::MemberList(%d)\n",this,lt);
-  memberGroupList=0;
   m_numDecMembers=-1; // special value indicating that value needs to be computed
   m_numDecEnumValues=0;
   m_numDocMembers=-1; // special value indicating that value needs to be computed
@@ -60,7 +58,6 @@ MemberList::MemberList(MemberListType lt) : m_listType(lt)
 
 MemberList::~MemberList()
 {
-  delete memberGroupList;
 }
 
 int genericCompareMembers(const MemberDef *c1,const MemberDef *c2)
@@ -126,14 +123,9 @@ int MemberList::countInheritableMembers(const ClassDef *inheritedFrom) const
       }
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      count+=mg->countInheritableMembers(inheritedFrom);
-    }
+    count+=mg->countInheritableMembers(inheritedFrom);
   }
   //printf("%s::countInheritableMembers(%s)=%d\n",
   //    listTypeAsString().data(),
@@ -208,28 +200,23 @@ void MemberList::countDecMembers()
       }
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->countDecMembers();
-      /*
-      m_varCnt+=mg->varCount();
-      m_funcCnt+=mg->funcCount();
-      m_enumCnt+=mg->enumCount();
-      m_enumValCnt+=mg->enumValueCount();
-      m_typeCnt+=mg->typedefCount();
-      m_seqCnt+=mg->sequenceCount();
-      m_dictCnt+=mg->dictionaryCount();
-      m_protoCnt+=mg->protoCount();
-      m_defCnt+=mg->defineCount();
-      m_friendCnt+=mg->friendCount();
-      */
-      m_numDecMembers+=mg->numDecMembers();
-      m_numDecEnumValues+=mg->numDecEnumValues();
-    }
+    mg->countDecMembers();
+    /*
+    m_varCnt+=mg->varCount();
+    m_funcCnt+=mg->funcCount();
+    m_enumCnt+=mg->enumCount();
+    m_enumValCnt+=mg->enumValueCount();
+    m_typeCnt+=mg->typedefCount();
+    m_seqCnt+=mg->sequenceCount();
+    m_dictCnt+=mg->dictionaryCount();
+    m_protoCnt+=mg->protoCount();
+    m_defCnt+=mg->defineCount();
+    m_friendCnt+=mg->friendCount();
+    */
+    m_numDecMembers+=mg->numDecMembers();
+    m_numDecEnumValues+=mg->numDecEnumValues();
   }
   //printf("----- end countDecMembers ----\n");
 
@@ -254,16 +241,11 @@ void MemberList::countDocMembers()
       m_numDocMembers++;
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->countDocMembers();
-      m_numDocMembers+=mg->numDocMembers();
-      m_numDocEnumValues+=mg->numDocEnumValues();
-    }
+    mg->countDocMembers();
+    m_numDocMembers+=mg->numDocMembers();
+    m_numDocEnumValues+=mg->numDocEnumValues();
   }
   //printf("MemberList::countDocMembers()=%d memberGroupList=%p\n",m_numDocMembers,memberGroupList);
 }
@@ -348,14 +330,9 @@ void MemberList::setAnonymousEnumType()
       }
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->setAnonymousEnumType();
-    }
+    mg->setAnonymousEnumType();
   }
 }
 
@@ -718,39 +695,33 @@ void MemberList::writeDeclarations(OutputList &ol,
     }
 
     //printf("memberGroupList=%p\n",memberGroupList);
-    if (memberGroupList)
+    for (const auto &mg : m_memberGroupRefList)
     {
-      MemberGroupListIterator mgli(*memberGroupList);
-      MemberGroup *mg;
-      while ((mg=mgli.current()))
+      bool hasHeader=!mg->header().isEmpty() && mg->header()!="[NOHEADER]";
+      if (inheritId.isEmpty())
       {
-        bool hasHeader=!mg->header().isEmpty() && mg->header()!="[NOHEADER]";
-        if (inheritId.isEmpty())
+        //printf("mg->header=%s hasHeader=%d\n",mg->header().data(),hasHeader);
+        ol.startMemberGroupHeader(hasHeader);
+        if (hasHeader)
         {
-          //printf("mg->header=%s hasHeader=%d\n",mg->header().data(),hasHeader);
-          ol.startMemberGroupHeader(hasHeader);
-          if (hasHeader)
-          {
-            ol.parseText(mg->header());
-          }
-          ol.endMemberGroupHeader();
-          if (!mg->documentation().isEmpty())
-          {
-            //printf("Member group has docs!\n");
-            ol.startMemberGroupDocs();
-            ol.generateDoc(mg->docFile(),mg->docLine(),ctx,0,mg->documentation()+"\n",FALSE,FALSE,
-                           0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
-            ol.endMemberGroupDocs();
-          }
-          ol.startMemberGroup();
+          ol.parseText(mg->header());
         }
-        //printf("--- mg->writePlainDeclarations ---\n");
-        mg->writePlainDeclarations(ol,cd,nd,fd,gd,inheritedFrom,inheritId);
-        if (inheritId.isEmpty())
+        ol.endMemberGroupHeader();
+        if (!mg->documentation().isEmpty())
         {
-          ol.endMemberGroup(hasHeader);
+          //printf("Member group has docs!\n");
+          ol.startMemberGroupDocs();
+          ol.generateDoc(mg->docFile(),mg->docLine(),ctx,0,mg->documentation()+"\n",FALSE,FALSE,
+              0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
+          ol.endMemberGroupDocs();
         }
-        ++mgli;
+        ol.startMemberGroup();
+      }
+      //printf("--- mg->writePlainDeclarations ---\n");
+      mg->writePlainDeclarations(ol,cd,nd,fd,gd,inheritedFrom,inheritId);
+      if (inheritId.isEmpty())
+      {
+        ol.endMemberGroup(hasHeader);
       }
     }
   }
@@ -834,15 +805,10 @@ void MemberList::writeDocumentation(OutputList &ol,
       }
     }
   }
-  if (memberGroupList)
+  //printf("MemberList::writeDocumentation()  --  member groups %d\n",memberGroupList->count());
+  for (const auto &mg : m_memberGroupRefList)
   {
-    //printf("MemberList::writeDocumentation()  --  member groups %d\n",memberGroupList->count());
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->writeDocumentation(ol,scopeName,container,showEnumValues,showInline);
-    }
+    mg->writeDocumentation(ol,scopeName,container,showEnumValues,showInline);
   }
   ol.endMemberDocList();
 }
@@ -953,26 +919,15 @@ void MemberList::writeDocumentationPage(OutputList &ol,
       }
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    //printf("MemberList::writeDocumentation()  --  member groups\n");
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->writeDocumentationPage(ol,scopeName,container);
-    }
+    mg->writeDocumentationPage(ol,scopeName,container);
   }
 }
 
 void MemberList::addMemberGroup(MemberGroup *mg)
 {
-  if (memberGroupList==0)
-  {
-    memberGroupList=new MemberGroupList;
-  }
-  //printf("addMemberGroup: this=%p mg=%p\n",this,mg);
-  memberGroupList->append(mg);
+  m_memberGroupRefList.push_back(mg);
 }
 
 void MemberList::addListReferences(Definition *def)
@@ -1003,14 +958,9 @@ void MemberList::addListReferences(Definition *def)
       }
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->addListReferences(def);
-    }
+    mg->addListReferences(def);
   }
 }
 
@@ -1026,14 +976,9 @@ void MemberList::findSectionsInDocumentation(const Definition *d)
       md->findSectionsInDocumentation();
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->findSectionsInDocumentation(d);
-    }
+    mg->findSectionsInDocumentation(d);
   }
 }
 
@@ -1132,14 +1077,9 @@ void MemberList::writeTagFile(FTextStream &tagFile)
       }
     }
   }
-  if (memberGroupList)
+  for (const auto &mg : m_memberGroupRefList)
   {
-    MemberGroupListIterator mgli(*memberGroupList);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->writeTagFile(tagFile);
-    }
+    mg->writeTagFile(tagFile);
   }
 }
 
@@ -1159,13 +1099,3 @@ void MemberList::setAnchors()
   }
 }
 
-
-
-//--------------------------------------------------------------------------
-
-int MemberSDict::compareValues(const MemberDef *c1, const MemberDef *c2) const
-{
-  return genericCompareMembers(c1,c2);
-}
-
-
index e62655b..08e2873 100644 (file)
 #ifndef MEMBERLIST_H
 #define MEMBERLIST_H
 
+#include <vector>
+#include <algorithm>
+
 #include <qlist.h>
 #include "memberdef.h"
-#include "sortdict.h"
+#include "linkedmap.h"
 #include "types.h"
+#include "membergroup.h"
 
 class GroupDef;
-class MemberGroup;
-class MemberGroupList;
 
 /** A list of MemberDef objects. */
 class MemberList : private QList<MemberDef>
@@ -88,11 +90,13 @@ class MemberList : private QList<MemberDef>
     void addListReferences(Definition *def);
     void findSectionsInDocumentation(const Definition *d);
     void setNeedsSorting(bool b);
-    MemberGroupList *getMemberGroupList() const { return memberGroupList; }
+    const MemberGroupRefList &getMemberGroupList() const { return m_memberGroupRefList; }
     void setAnonymousEnumType();
     void setAnchors();
 
   private:
+    MemberList(const MemberList &) = delete;
+    MemberList &operator=(const MemberList &) = delete;
     int compareValues(const MemberDef *item1,const MemberDef *item2) const;
     int countEnumValues(const MemberDef *md) const;
     /*
@@ -110,7 +114,7 @@ class MemberList : private QList<MemberDef>
     int m_numDecEnumValues;
     int m_numDocMembers; // number of members in the detailed part of the memberlist
     int m_numDocEnumValues;
-    MemberGroupList *memberGroupList;
+    MemberGroupRefList m_memberGroupRefList;
     bool m_inGroup; // is this list part of a group definition
     bool m_inFile;  // is this list part of a file definition
     MemberListType m_listType;
@@ -126,22 +130,27 @@ class MemberListIterator : public QListIterator<MemberDef>
     virtual ~MemberListIterator() {}
 };
 
-/** An unsorted dictionary of MemberDef objects. */
-class MemberDict : public QDict<MemberDef>
+class MemberLinkedRefMap : public LinkedRefMap<const MemberDef>
 {
-  public:
-    MemberDict(uint size) : QDict<MemberDef>(size) {}
-    virtual ~MemberDict() {}
 };
 
-/** A sorted dictionary of MemberDef objects. */
-class MemberSDict : public SDict<MemberDef>
+class MemberLists : public std::vector< std::unique_ptr<MemberList> >
 {
   public:
-    MemberSDict(uint size=17) : SDict<MemberDef>(size) {}
-    virtual ~MemberSDict() {}
+    MemberLists() = default;
+    const std::unique_ptr<MemberList> &get(MemberListType lt)
+    {
+      // find the list with the given type
+      auto it = std::find_if(begin(),end(),[&lt](const auto &ml) { return ml->listType()==lt; });
+      if (it!=end()) return *it;
+      // or create a new list if it is not found
+      emplace_back(std::make_unique<MemberList>(lt));
+      return back();
+    }
+
   private:
-    int compareValues(const MemberDef *item1,const MemberDef *item2) const;
+    MemberLists(const MemberLists &) = delete;
+    MemberLists &operator=(const MemberLists &) = delete;
 };
 
 int genericCompareMembers(const MemberDef *c1,const MemberDef *c2);
index 11597bc..d0a88f0 100644 (file)
@@ -95,9 +95,9 @@ class NamespaceDefImpl : public DefinitionMixin<NamespaceDefMutable>
     virtual void setFileName(const QCString &fn);
     virtual bool subGrouping() const { return m_subGrouping; }
     virtual MemberList *getMemberList(MemberListType lt) const;
-    virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; }
-    virtual MemberDef    *getMemberByName(const QCString &) const;
-    virtual MemberGroupSDict *getMemberGroupSDict() const { return memberGroupSDict; }
+    virtual const MemberLists &getMemberLists() const { return m_memberLists; }
+    virtual const MemberDef *getMemberByName(const QCString &) const;
+    virtual const MemberGroupList &getMemberGroups() const { return m_memberGroups; }
     virtual ClassLinkedRefMap getClasses() const { return classes; }
     virtual ClassLinkedRefMap getInterfaces() const { return interfaces; }
     virtual ClassLinkedRefMap getStructs() const { return structs; }
@@ -110,7 +110,6 @@ class NamespaceDefImpl : public DefinitionMixin<NamespaceDefMutable>
     virtual void setMetaData(const QCString &m);
 
   private:
-    MemberList *createMemberList(MemberListType lt);
     void addMemberToList(MemberListType lt,MemberDef *md);
     void writeMemberDeclarations(OutputList &ol,MemberListType lt,const QCString &title);
     void writeMemberDocumentation(OutputList &ol,MemberListType lt,const QCString &title);
@@ -138,9 +137,9 @@ class NamespaceDefImpl : public DefinitionMixin<NamespaceDefMutable>
     LinkedRefMap<const ClassDef> m_usingDeclList;
     SDict<Definition>    *m_innerCompounds = 0;
 
-    MemberSDict          *m_allMembersDict = 0;
-    QList<MemberList>     m_memberLists;
-    MemberGroupSDict     *memberGroupSDict = 0;
+    MemberLinkedRefMap    m_allMembers;
+    MemberLists           m_memberLists;
+    MemberGroupList       m_memberGroups;
     ClassLinkedRefMap     classes;
     ClassLinkedRefMap     interfaces;
     ClassLinkedRefMap     structs;
@@ -208,12 +207,12 @@ class NamespaceDefAliasImpl : public DefinitionAliasMixin<NamespaceDef>
     { return getNSAlias()->subGrouping(); }
     virtual MemberList *getMemberList(MemberListType lt) const
     { return getNSAlias()->getMemberList(lt); }
-    virtual const QList<MemberList> &getMemberLists() const
+    virtual const MemberLists &getMemberLists() const
     { return getNSAlias()->getMemberLists(); }
-    virtual MemberDef    *getMemberByName(const QCString &name) const
+    virtual const MemberDef *getMemberByName(const QCString &name) const
     { return getNSAlias()->getMemberByName(name); }
-    virtual MemberGroupSDict *getMemberGroupSDict() const
-    { return getNSAlias()->getMemberGroupSDict(); }
+    virtual const MemberGroupList &getMemberGroups() const
+    { return getNSAlias()->getMemberGroups(); }
     virtual ClassLinkedRefMap getClasses() const
     { return getNSAlias()->getClasses(); }
     virtual ClassLinkedRefMap getInterfaces() const
@@ -264,10 +263,7 @@ NamespaceDefImpl::NamespaceDefImpl(const char *df,int dl,int dc,
     setFileName(name);
   }
   m_innerCompounds = new SDict<Definition>(17);
-  m_allMembersDict = 0;
   setReference(lref);
-  memberGroupSDict = new MemberGroupSDict;
-  memberGroupSDict->setAutoDelete(TRUE);
   m_inline=FALSE;
   m_subGrouping=Config_getBool(SUBGROUPING);
   if (type && !strcmp("module", type))
@@ -291,8 +287,6 @@ NamespaceDefImpl::NamespaceDefImpl(const char *df,int dl,int dc,
 NamespaceDefImpl::~NamespaceDefImpl()
 {
   delete m_innerCompounds;
-  delete memberGroupSDict;
-  delete m_allMembersDict;
 }
 
 void NamespaceDefImpl::setFileName(const QCString &fn)
@@ -309,9 +303,7 @@ void NamespaceDefImpl::setFileName(const QCString &fn)
 
 void NamespaceDefImpl::distributeMemberGroupDocumentation()
 {
-  MemberGroupSDict::Iterator mgli(*memberGroupSDict);
-  MemberGroup *mg;
-  for (;(mg=mgli.current());++mgli)
+  for (const auto &mg : m_memberGroups)
   {
     mg->distributeMemberGroupDocumentation();
   }
@@ -321,15 +313,11 @@ void NamespaceDefImpl::findSectionsInDocumentation()
 {
   docFindSections(briefDescription(),this,docFile());
   docFindSections(documentation(),this,docFile());
-  MemberGroupSDict::Iterator mgli(*memberGroupSDict);
-  MemberGroup *mg;
-  for (;(mg=mgli.current());++mgli)
+  for (const auto &mg : m_memberGroups)
   {
     mg->findSectionsInDocumentation(this);
   }
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_declarationLists)
     {
@@ -394,28 +382,21 @@ void NamespaceDefImpl::insertNamespace(const NamespaceDef *nd)
 
 void NamespaceDefImpl::addMembersToMemberGroup()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_declarationLists)
     {
-      ::addMembersToMemberGroup(ml,&memberGroupSDict,this);
+      ::addMembersToMemberGroup(ml.get(),&m_memberGroups,this);
     }
   }
 
   // add members inside sections to their groups
-  if (memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    if (mg->allMembersInSameSection() && m_subGrouping)
     {
-      if (mg->allMembersInSameSection() && m_subGrouping)
-      {
-        //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
-        mg->addToDeclarationSection();
-      }
+      //printf("----> addToDeclarationSection(%s)\n",mg->header().data());
+      mg->addToDeclarationSection();
     }
   }
 }
@@ -463,16 +444,12 @@ void NamespaceDefImpl::insertMember(MemberDef *md)
     MemberList *allMemberList = getMemberList(MemberListType_allMembersList);
     if (allMemberList==0)
     {
-      allMemberList = new MemberList(MemberListType_allMembersList);
-      m_memberLists.append(allMemberList);
+      m_memberLists.emplace_back(std::make_unique<MemberList>(MemberListType_allMembersList));
+      allMemberList = m_memberLists.back().get();
     }
     allMemberList->append(md);
-    if (m_allMembersDict==0)
-    {
-      m_allMembersDict = new MemberSDict;
-    }
     //printf("%s::m_allMembersDict->append(%s)\n",name().data(),md->localName().data());
-    m_allMembersDict->append(md->localName(),md);
+    m_allMembers.add(md->localName(),md);
     //::addNamespaceMemberNameToIndex(md);
     //static bool sortBriefDocs=Config_getBool(SORT_BRIEF_DOCS);
     switch(md->memberType())
@@ -620,14 +597,9 @@ void NamespaceDefImpl::writeTagFile(FTextStream &tagFile)
         break;
       case LayoutDocEntry::MemberGroups:
         {
-          if (memberGroupSDict)
+          for (const auto &mg : m_memberGroups)
           {
-            MemberGroupSDict::Iterator mgli(*memberGroupSDict);
-            MemberGroup *mg;
-            for (;(mg=mgli.current());++mgli)
-            {
-              mg->writeTagFile(tagFile);
-            }
+            mg->writeTagFile(tagFile);
           }
         }
         break;
@@ -789,18 +761,12 @@ void NamespaceDefImpl::writeNamespaceDeclarations(OutputList &ol,const QCString
 void NamespaceDefImpl::writeMemberGroups(OutputList &ol)
 {
   /* write user defined member groups */
-  if (memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    memberGroupSDict->sort();
-    MemberGroupSDict::Iterator mgli(*memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
+    if ((!mg->allMembersInSameSection() || !m_subGrouping)
+        && mg->header()!="[NOHEADER]")
     {
-      if ((!mg->allMembersInSameSection() || !m_subGrouping)
-          && mg->header()!="[NOHEADER]")
-      {
-        mg->writeDeclarations(ol,0,this,0,0);
-      }
+      mg->writeDeclarations(ol,0,this,0,0);
     }
   }
 }
@@ -1082,9 +1048,7 @@ void NamespaceDefImpl::writeMemberPages(OutputList &ol)
   ol.pushGeneratorState();
   ol.disableAllBut(OutputGenerator::Html);
 
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_documentationLists)
     {
@@ -1139,22 +1103,15 @@ void NamespaceDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *cur
 
 void NamespaceDefImpl::countMembers()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     ml->countDecMembers();
     ml->countDocMembers();
   }
-  if (memberGroupSDict)
+  for (const auto &mg : m_memberGroups)
   {
-    MemberGroupSDict::Iterator mgli(*memberGroupSDict);
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      mg->countDecMembers();
-      mg->countDocMembers();
-    }
+    mg->countDecMembers();
+    mg->countDocMembers();
   }
 }
 
@@ -1213,15 +1170,11 @@ void NamespaceDefImpl::addListReferences()
         this
         );
   }
-  MemberGroupSDict::Iterator mgli(*memberGroupSDict);
-  MemberGroup *mg;
-  for (;(mg=mgli.current());++mgli)
+  for (const auto &mg : m_memberGroups)
   {
     mg->addListReferences(this);
   }
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()&MemberListType_documentationLists)
     {
@@ -1372,29 +1325,11 @@ void NamespaceLinkedRefMap::writeDeclaration(OutputList &ol,const char *title,
 
 //-------------------------------------------------------------------------------
 
-MemberList *NamespaceDefImpl::createMemberList(MemberListType lt)
-{
-  m_memberLists.setAutoDelete(TRUE);
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
-  {
-    if (ml->listType()==lt)
-    {
-      return ml;
-    }
-  }
-  // not found, create a new member list
-  ml = new MemberList(lt);
-  m_memberLists.append(ml);
-  return ml;
-}
-
 void NamespaceDefImpl::addMemberToList(MemberListType lt,MemberDef *md)
 {
   static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
   static bool sortMemberDocs = Config_getBool(SORT_MEMBER_DOCS);
-  MemberList *ml = createMemberList(lt);
+  const auto &ml = m_memberLists.get(lt);
   ml->setNeedsSorting(
       ((ml->listType()&MemberListType_declarationLists) && sortBriefDocs) ||
       ((ml->listType()&MemberListType_documentationLists) && sortMemberDocs));
@@ -1405,21 +1340,18 @@ void NamespaceDefImpl::addMemberToList(MemberListType lt,MemberDef *md)
     MemberDefMutable *mdm = toMemberDefMutable(md);
     if (mdm)
     {
-      mdm->setSectionList(this,ml);
+      mdm->setSectionList(this,ml.get());
     }
   }
 }
 
 void NamespaceDefImpl::sortMemberLists()
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->needsSorting()) { ml->sort(); ml->setNeedsSorting(FALSE); }
   }
 
-
   if (Config_getBool(SORT_BRIEF_DOCS))
   {
     auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
@@ -1447,13 +1379,11 @@ void NamespaceDefImpl::sortMemberLists()
 
 MemberList *NamespaceDefImpl::getMemberList(MemberListType lt) const
 {
-  QListIterator<MemberList> mli(m_memberLists);
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (auto &ml : m_memberLists)
   {
     if (ml->listType()==lt)
     {
-      return ml;
+      return ml.get();
     }
   }
   return 0;
@@ -1495,15 +1425,9 @@ bool NamespaceDefImpl::isLinkable() const
   return isLinkableInProject() || isReference();
 }
 
-MemberDef * NamespaceDefImpl::getMemberByName(const QCString &n) const
+const MemberDef * NamespaceDefImpl::getMemberByName(const QCString &n) const
 {
-  MemberDef *md = 0;
-  if (m_allMembersDict && !n.isEmpty())
-  {
-    md = m_allMembersDict->find(n);
-    //printf("%s::m_allMembersDict->find(%s)=%p\n",name().data(),n.data(),md);
-  }
-  return md;
+  return m_allMembers.find(n);
 }
 
 QCString NamespaceDefImpl::title() const
index e9bf86f..e644a32 100644 (file)
 #include "definition.h"
 #include "filedef.h"
 #include "linkedmap.h"
+#include "membergroup.h"
 
 class MemberList;
 class ClassDef;
 class OutputList;
 class ClassLinkedRefMap;
 class MemberDef;
-class MemberGroupSDict;
 class NamespaceDef;
 class FTextStream;
 class NamespaceDef;
@@ -75,11 +75,11 @@ class NamespaceDef : public Definition
     virtual const Definition *findInnerCompound(const char *name) const = 0;
     virtual bool subGrouping() const = 0;
     virtual MemberList *getMemberList(MemberListType lt) const = 0;
-    virtual const QList<MemberList> &getMemberLists() const = 0;
-    virtual MemberDef *getMemberByName(const QCString &) const = 0;
+    virtual const MemberLists &getMemberLists() const = 0;
+    virtual const MemberDef *getMemberByName(const QCString &) const = 0;
 
     /*! Returns the user defined member groups */
-    virtual MemberGroupSDict *getMemberGroupSDict() const = 0;
+    virtual const MemberGroupList &getMemberGroups() const = 0;
 
     /*! Returns the classes contained in this namespace */
     virtual ClassLinkedRefMap getClasses() const = 0;
index b0d375e..d3cf823 100644 (file)
@@ -45,8 +45,8 @@ class PageDefImpl : public DefinitionMixin<PageDef>
     virtual QCString anchor() const { return QCString(); }
     virtual void findSectionsInDocumentation();
     virtual QCString title() const { return m_title; }
-    virtual GroupDef *  getGroupDef() const;
-    virtual PageSDict * getSubPages() const { return m_subPageDict; }
+    virtual const GroupDef * getGroupDef() const;
+    virtual const PageLinkedRefMap &getSubPages() const { return m_subPages; }
     virtual void addInnerCompound(const Definition *d);
     virtual bool visibleInIndex() const;
     virtual bool documentedPage() const;
@@ -61,12 +61,12 @@ class PageDefImpl : public DefinitionMixin<PageDef>
     virtual void writeDocumentation(OutputList &ol);
     virtual void writeTagFile(FTextStream &);
     virtual void setNestingLevel(int l);
-    virtual void writePageDocumentation(OutputList &ol);
+    virtual void writePageDocumentation(OutputList &ol) const;
 
   private:
     QCString m_fileName;
     QCString m_title;
-    PageSDict *m_subPageDict;                 // list of pages in the group
+    PageLinkedRefMap m_subPages;                 // list of pages in the group
     Definition *m_pageScope;
     int m_nestingLevel;
     LocalToc m_localToc;
@@ -85,7 +85,6 @@ PageDefImpl::PageDefImpl(const char *f,int l,const char *n,
  : DefinitionMixin(f,l,1,n), m_title(t)
 {
   setDocumentation(d,f,l);
-  m_subPageDict = new PageSDict(7);
   m_pageScope = 0;
   m_nestingLevel = 0;
   m_fileName = ::convertNameToFile(n,FALSE,TRUE);
@@ -94,7 +93,6 @@ PageDefImpl::PageDefImpl(const char *f,int l,const char *n,
 
 PageDefImpl::~PageDefImpl()
 {
-  delete m_subPageDict;
 }
 
 void PageDefImpl::findSectionsInDocumentation()
@@ -103,10 +101,9 @@ void PageDefImpl::findSectionsInDocumentation()
   docFindSections(documentation(),this,docFile());
 }
 
-GroupDef *PageDefImpl::getGroupDef() const
+const GroupDef *PageDefImpl::getGroupDef() const
 {
-  GroupList *groups = partOfGroups();
-  return groups!=0 ? groups->getFirst() : 0;
+  return !partOfGroups().empty() ? partOfGroups().front() : 0;
 }
 
 QCString PageDefImpl::getOutputFileBase() const
@@ -129,9 +126,9 @@ void PageDefImpl::addInnerCompound(const Definition *def)
     PageDef *pd = const_cast<PageDef*>(toPageDef(def));
     if (pd)
     {
-      m_subPageDict->append(pd->name(),pd);
+      m_subPages.add(pd->name(),pd);
       pd->setOuterScope(this);
-      if (this==Doxygen::mainPage)
+      if (this==Doxygen::mainPage.get())
       {
         pd->setNestingLevel(m_nestingLevel);
       }
@@ -294,7 +291,7 @@ void PageDefImpl::writeDocumentation(OutputList &ol)
   Doxygen::indexList->addIndexItem(this,0,0,filterTitle(title()));
 }
 
-void PageDefImpl::writePageDocumentation(OutputList &ol)
+void PageDefImpl::writePageDocumentation(OutputList &ol) const
 {
   ol.startTextBlock();
   QCString docStr = documentation()+inbodyDocumentation();
@@ -330,9 +327,7 @@ void PageDefImpl::writePageDocumentation(OutputList &ol)
     ol.enable(OutputGenerator::Docbook);
     ol.enable(OutputGenerator::RTF);
 
-    PageSDict::Iterator pdi(*m_subPageDict);
-    PageDef *subPage=pdi.toFirst();
-    for (pdi.toFirst();(subPage=pdi.current());++pdi)
+    for (const auto &subPage : m_subPages)
     {
       SectionType sectionType = SectionType::Paragraph;
       switch (m_nestingLevel)
@@ -377,7 +372,7 @@ bool PageDefImpl::documentedPage() const
 
 bool PageDefImpl::hasSubPages() const
 {
-  return m_subPageDict->count()>0;
+  return !m_subPages.empty();
 }
 
 void PageDefImpl::setNestingLevel(int l)
index 03cc5a8..c0a7bf0 100644 (file)
@@ -19,7 +19,7 @@
 #include "definition.h"
 #include "sortdict.h"
 
-class PageSDict;
+class PageLinkedRefMap;
 class OutputList;
 class FTextStream;
 
@@ -42,8 +42,8 @@ class PageDef : public DefinitionMutable, public Definition
     virtual QCString anchor() const = 0;
     virtual void findSectionsInDocumentation() = 0;
     virtual QCString title() const = 0;
-    virtual GroupDef *  getGroupDef() const = 0;
-    virtual PageSDict * getSubPages() const = 0;
+    virtual const GroupDef *getGroupDef() const = 0;
+    virtual const PageLinkedRefMap &getSubPages() const = 0;
     virtual void addInnerCompound(const Definition *) = 0;
     virtual bool visibleInIndex() const = 0;
     virtual bool documentedPage() const = 0;
@@ -59,7 +59,7 @@ class PageDef : public DefinitionMutable, public Definition
     virtual void writeDocumentation(OutputList &) = 0;
     virtual void writeTagFile(FTextStream &) = 0;
     virtual void setNestingLevel(int) = 0;
-    virtual void writePageDocumentation(OutputList &) = 0;
+    virtual void writePageDocumentation(OutputList &) const = 0;
 
 };
 
@@ -72,16 +72,12 @@ const PageDef      *toPageDef(const Definition *d);
 
 // ------------------
 
-class PageSDict : public SDict<PageDef>
+class PageLinkedMap : public LinkedMap<PageDef>
+{
+};
+
+class PageLinkedRefMap : public LinkedRefMap<const PageDef>
 {
-  public:
-    PageSDict(uint size) : SDict<PageDef>(size) {}
-    virtual ~PageSDict() {}
-  private:
-    int compareValues(const PageDef *i1,const PageDef *i2) const
-    {
-      return qstricmp(i1->name(),i2->name());
-    }
 };
 
 #endif
index d84d5e4..854b3df 100644 (file)
@@ -1529,7 +1529,7 @@ public:
   inline PerlModGenerator(bool pretty) : m_output(pretty) { }
 
   void generatePerlModForMember(const MemberDef *md, const Definition *);
-  void generatePerlUserDefinedSection(const Definition *d, const MemberGroupSDict *gsd);
+  void generatePerlUserDefinedSection(const Definition *d, const MemberGroupList &mgl);
   void generatePerlModSection(const Definition *d, MemberList *ml,
                              const char *name, const char *header=0);
   void addListOfAllMembers(const ClassDef *cd);
@@ -1776,37 +1776,33 @@ void PerlModGenerator::addListOfAllMembers(const ClassDef *cd)
   m_output.closeList();
 }
 
-/* DGA: fix #7490 Perlmod generation issue with multiple grouped functions (member groups) */
-void PerlModGenerator::generatePerlUserDefinedSection(const Definition *d, const MemberGroupSDict *gsd)
-{
-       if (gsd)
-       {
-               MemberGroupSDict::Iterator mgli(*gsd);
-               MemberGroup *mg;
-               m_output.openList("user_defined");
-               for (; (mg = mgli.current()); ++mgli)
-               {
-                       m_output.openHash();
-                       if (mg->header())
-                               m_output.addFieldQuotedString("header", mg->header());
-
-                       if (mg->members())
-                       {
-                               m_output.openList("members");
-                               MemberListIterator mli(*mg->members());
-                               const MemberDef *md;
-                               for (mli.toFirst(); (md = mli.current()); ++mli)
-                               {
-                                       generatePerlModForMember(md, d);
-                               }
-                               m_output.closeList();
-                       }
-                       m_output.closeHash();
-               }
-               m_output.closeList();
-       }
-}
-/* DGA: end of fix #7490 */
+void PerlModGenerator::generatePerlUserDefinedSection(const Definition *d, const MemberGroupList &mgl)
+{
+  if (!mgl.empty())
+  {
+    m_output.openList("user_defined");
+    for (const auto &mg : mgl)
+    {
+      m_output.openHash();
+      if (mg->header())
+        m_output.addFieldQuotedString("header", mg->header());
+
+      if (mg->members())
+      {
+        m_output.openList("members");
+        MemberListIterator mli(*mg->members());
+        const MemberDef *md;
+        for (mli.toFirst(); (md = mli.current()); ++mli)
+        {
+          generatePerlModForMember(md, d);
+        }
+        m_output.closeList();
+      }
+      m_output.closeHash();
+    }
+    m_output.closeList();
+  }
+}
 
 void PerlModGenerator::generatePerlModForClass(const ClassDef *cd)
 {
@@ -1892,7 +1888,7 @@ void PerlModGenerator::generatePerlModForClass(const ClassDef *cd)
 
   addTemplateList(cd,m_output);
   addListOfAllMembers(cd);
-  generatePerlUserDefinedSection(cd, cd->getMemberGroupSDict());
+  generatePerlUserDefinedSection(cd, cd->getMemberGroups());
 
   generatePerlModSection(cd,cd->getMemberList(MemberListType_pubTypes),"public_typedefs");
   generatePerlModSection(cd,cd->getMemberList(MemberListType_pubMethods),"public_methods");
@@ -1986,7 +1982,7 @@ void PerlModGenerator::generatePerlModForNamespace(const NamespaceDef *nd)
     m_output.closeList();
   }
 
-  generatePerlUserDefinedSection(nd, nd->getMemberGroupSDict());
+  generatePerlUserDefinedSection(nd, nd->getMemberGroups());
 
   generatePerlModSection(nd,nd->getMemberList(MemberListType_decDefineMembers),"defines");
   generatePerlModSection(nd,nd->getMemberList(MemberListType_decProtoMembers),"prototypes");
@@ -2057,8 +2053,7 @@ void PerlModGenerator::generatePerlModForFile(const FileDef *fd)
   }
   m_output.closeList();
 
-  /* DGA: fix #7494 Perlmod does not generate grouped members from files */
-  generatePerlUserDefinedSection(fd, fd->getMemberGroupSDict());
+  generatePerlUserDefinedSection(fd, fd->getMemberGroups());
 
   generatePerlModSection(fd,fd->getMemberList(MemberListType_decDefineMembers),"defines");
   generatePerlModSection(fd,fd->getMemberList(MemberListType_decProtoMembers),"prototypes");
@@ -2126,33 +2121,27 @@ void PerlModGenerator::generatePerlModForGroup(const GroupDef *gd)
     m_output.closeList();
   }
 
-  PageSDict *pl = gd->getPages();
-  if (pl)
+  if (!gd->getPages().empty())
   {
     m_output.openList("pages");
-    PageSDict::Iterator pli(*pl);
-    PageDef *pd;
-    for (pli.toFirst();(pd=pli.current());++pli)
+    for (const auto &pd : gd->getPages())
       m_output.openHash()
        .addFieldQuotedString("title", pd->title())
        .closeHash();
     m_output.closeList();
   }
 
-  GroupList *gl = gd->getSubGroups();
-  if (gl)
+  if (!gd->getSubGroups().empty())
   {
     m_output.openList("groups");
-    GroupListIterator gli(*gl);
-    const GroupDef *sgd;
-    for (gli.toFirst();(sgd=gli.current());++gli)
+    for (const auto &sgd : gd->getSubGroups())
       m_output.openHash()
        .addFieldQuotedString("title", sgd->groupTitle())
        .closeHash();
     m_output.closeList();
   }
 
-  generatePerlUserDefinedSection(gd, gd->getMemberGroupSDict());
+  generatePerlUserDefinedSection(gd, gd->getMemberGroups());
 
   generatePerlModSection(gd,gd->getMemberList(MemberListType_decDefineMembers),"defines");
   generatePerlModSection(gd,gd->getMemberList(MemberListType_decProtoMembers),"prototypes");
@@ -2218,24 +2207,20 @@ bool PerlModGenerator::generatePerlModOutput()
   m_output.closeList();
 
   m_output.openList("groups");
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  const GroupDef *gd;
-  for (;(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
-    generatePerlModForGroup(gd);
+    generatePerlModForGroup(gd.get());
   }
   m_output.closeList();
 
   m_output.openList("pages");
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
-    generatePerlModForPage(pd);
+    generatePerlModForPage(pd.get());
   }
   if (Doxygen::mainPage)
   {
-    generatePerlModForPage(Doxygen::mainPage);
+    generatePerlModForPage(Doxygen::mainPage.get());
   }
   m_output.closeList();
 
index b7f3b66..65788cc 100644 (file)
@@ -81,8 +81,8 @@ struct pycodeYY_state
   int           inputLines = 0;      //!< number of line in the code fragment
   int           yyLineNr = 0;        //!< current line number
   FileDef *     sourceFileDef = 0;
-  Definition *  currentDefinition = 0;
-  MemberDef *   currentMemberDef = 0;
+  const Definition * currentDefinition = 0;
+  const MemberDef *  currentMemberDef = 0;
   bool          includeCodeFragment = FALSE;
   QCString      realScope;
   int           bodyCurlyCount = 0;
@@ -1010,7 +1010,7 @@ static void startCodeLine(yyscan_t yyscanner)
     //lineNumber.sprintf("%05d",yyextra->yyLineNr);
     //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
 
-    Definition *d   = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
+    const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
     //printf("startCodeLine %d d=%p\n",yyextra->yyLineNr,d);
     //yyextra->code->startLineNumber();
 
@@ -1291,7 +1291,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
 
   if ((lcd=yyextra->theVarContext.findVariable(className))==0) // not a local variable
   {
-    Definition *d = yyextra->currentDefinition;
+    const Definition *d = yyextra->currentDefinition;
     QCString scope = substitute(className,".","::");
 
     cd = yyextra->symbolResolver.resolveClass(d,substitute(className,".","::"));
@@ -1378,7 +1378,7 @@ static void generateClassOrGlobalLink(yyscan_t yyscanner,
         const NamespaceDef *mnd = getResolvedNamespace(scope);
         if (mnd)
         {
-          MemberDef *mmd=mnd->getMemberByName(locName);
+          const MemberDef *mmd=mnd->getMemberByName(locName);
           if (mmd)
           {
             //printf("name=%s scope=%s\n",locName.data(),scope.data());
@@ -1472,8 +1472,8 @@ static bool findMemberLink(yyscan_t yyscanner,
       sym->getOuterScope()->definitionType()==Definition::TypeClass &&
       yyextra->currentDefinition->definitionType()==Definition::TypeClass)
   {
-    ClassDef *cd = toClassDef(sym->getOuterScope());
-    ClassDef *thisCd = toClassDef(yyextra->currentDefinition);
+    const ClassDef *cd = toClassDef(sym->getOuterScope());
+    const ClassDef *thisCd = toClassDef(yyextra->currentDefinition);
     if (sym->definitionType()==Definition::TypeMember)
     {
       if (yyextra->currentMemberDef && yyextra->collectXRefs)
index a8aa898..94b6893 100644 (file)
@@ -471,9 +471,7 @@ void RTFGenerator::startIndexSection(IndexSections is)
     case isModuleDocumentation:
       {
         //Module Documentation
-        GroupSDict::Iterator gli(*Doxygen::groupSDict);
-        GroupDef *gd;
-        for (gli.toFirst();(gd=gli.current());++gli)
+        for (const auto &gd : *Doxygen::groupLinkedMap)
         {
           if (!gd->isReference())
           {
@@ -486,9 +484,7 @@ void RTFGenerator::startIndexSection(IndexSections is)
     case isDirDocumentation:
       {
         //Directory Documentation
-        SDict<DirDef>::Iterator dli(*Doxygen::directories);
-        DirDef *dd;
-        for (dli.toFirst();(dd=dli.current());++dli)
+        for (const auto &dd : *Doxygen::dirLinkedMap)
         {
           if (dd->isLinkableInProject())
           {
@@ -741,14 +737,18 @@ void RTFGenerator::endIndexSection(IndexSections is)
       break;
     case isModuleDocumentation:
       {
-        GroupSDict::Iterator gli(*Doxygen::groupSDict);
-        GroupDef *gd;
+        bool first=true;
         t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl;
-        for (gli.toFirst();(gd=gli.current());++gli)
+        for (const auto &gd : *Doxygen::groupLinkedMap)
         {
           if (!gd->isReference())
           {
             t << "\\par " << rtf_Style_Reset << endl;
+            if (!first)
+            {
+              beginRTFSection();
+            }
+            first=false;
             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
             t << gd->getOutputFileBase();
             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
@@ -758,14 +758,18 @@ void RTFGenerator::endIndexSection(IndexSections is)
       break;
     case isDirDocumentation:
       {
-        SDict<DirDef>::Iterator dli(*Doxygen::directories);
-        DirDef *dd;
+        bool first=true;
         t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl;
-        for (dli.toFirst();(dd=dli.current());++dli)
+        for (const auto &dd : *Doxygen::dirLinkedMap)
         {
           if (dd->isLinkableInProject())
           {
             t << "\\par " << rtf_Style_Reset << endl;
+            if (!first)
+            {
+              beginRTFSection();
+            }
+            first=false;
             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
             t << dd->getOutputFileBase();
             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
@@ -858,20 +862,16 @@ void RTFGenerator::endIndexSection(IndexSections is)
     case isExampleDocumentation:
       {
         //t << "}\n";
+        bool isFirst=true;
         t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
-        PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-        PageDef *pd=pdi.toFirst();
-        if (pd)
-        {
-          t << "\\par " << rtf_Style_Reset << endl;
-          t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
-          t << pd->getOutputFileBase();
-          t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
-        }
-        for (++pdi;(pd=pdi.current());++pdi)
+        for (const auto &pd : *Doxygen::exampleLinkedMap)
         {
           t << "\\par " << rtf_Style_Reset << endl;
-          beginRTFSection();
+          if (!isFirst)
+          {
+            beginRTFSection();
+          }
+          isFirst=false;
           t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
           t << pd->getOutputFileBase();
           t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
@@ -883,10 +883,8 @@ void RTFGenerator::endIndexSection(IndexSections is)
 //#error "fix me in the same way as the latex index..."
         //t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
         //t << "}"<< endl;
-        //PageSDict::Iterator pdi(*Doxygen::pageSDict);
-        //PageDef *pd=pdi.toFirst();
         //bool first=TRUE;
-        //for (pdi.toFirst();(pd=pdi.current());++pdi)
+        //for (const auto *pd : Doxygen::pageLinkedMap)
         //{
         //  if (!pd->getGroupDef() && !pd->isReference())
         //  {
index 42601b9..89f1681 100644 (file)
@@ -1,8 +1,6 @@
 /******************************************************************************
  *
- *
- *
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
+ * Copyright (C) 1997-2020 by Dimitri van Heesch.
  *
  * Permission to use, copy, modify, and distribute this software and its
  * documentation under the terms of the GNU General Public License is hereby
@@ -15,6 +13,7 @@
  *
  */
 
+
 #include <ctype.h>
 #include <assert.h>
 
@@ -31,7 +30,6 @@
 #include "message.h"
 #include "version.h"
 #include "groupdef.h"
-#include "classlist.h"
 #include "filedef.h"
 #include "memberdef.h"
 #include "filename.h"
 #include "namespacedef.h"
 #include "classdef.h"
 
+//---------------------------------------------------------------------------------------------
+// the following part is for the server based search engine
+//---------------------------------------------------------------------------------------------
+
 // file format: (all multi-byte values are stored in big endian format)
 //   4 byte header
 //   256*256*4 byte index (4 bytes)
@@ -532,11 +534,96 @@ void SearchIndexExternal::write(const char *fileName)
   }
 }
 
-//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------------------------
 // the following part is for the javascript based search engine
+//---------------------------------------------------------------------------------------------
+
+QCString searchName(const Definition *d)
+{
+  return d->definitionType()==Definition::TypeGroup ?  QCString(toGroupDef(d)->groupTitle()) :
+         d->definitionType()==Definition::TypePage  ?  toPageDef(d)->title() :
+                                                       d->localName();
+}
+
+QCString searchId(const Definition *d)
+{
+  QCString s = searchName(d);
+  int c;
+  uint i;
+  QCString result;
+  for (i=0;i<s.length();i++)
+  {
+    c=s.at(i);
+    if (c>0x7f || c<0) // part of multibyte character
+    {
+      result+=(char)c;
+    }
+    else if (isalnum(c)) // simply alpha numerical character
+    {
+      result+=(char)tolower(c);
+    }
+    else // other 'unprintable' characters
+    {
+      char val[4];
+      sprintf(val,"_%02x",(uchar)c);
+      result+=val;
+    }
+  }
+  return result;
+}
 
 
-static SearchIndexInfo g_searchIndexInfo[NUM_SEARCH_INDICES];
+#define SEARCH_INDEX_ALL           0
+#define SEARCH_INDEX_CLASSES       1
+#define SEARCH_INDEX_INTERFACES    2
+#define SEARCH_INDEX_STRUCTS       3
+#define SEARCH_INDEX_EXCEPTIONS    4
+#define SEARCH_INDEX_NAMESPACES    5
+#define SEARCH_INDEX_FILES         6
+#define SEARCH_INDEX_FUNCTIONS     7
+#define SEARCH_INDEX_VARIABLES     8
+#define SEARCH_INDEX_TYPEDEFS      9
+#define SEARCH_INDEX_SEQUENCES    10
+#define SEARCH_INDEX_DICTIONARIES 11
+#define SEARCH_INDEX_ENUMS        12
+#define SEARCH_INDEX_ENUMVALUES   13
+#define SEARCH_INDEX_PROPERTIES   14
+#define SEARCH_INDEX_EVENTS       15
+#define SEARCH_INDEX_RELATED      16
+#define SEARCH_INDEX_DEFINES      17
+#define SEARCH_INDEX_GROUPS       18
+#define SEARCH_INDEX_PAGES        19
+
+static std::array<SearchIndexInfo,NUM_SEARCH_INDICES> g_searchIndexInfo =
+{ {
+  //  index                         name            getText                                                  symbolList
+  { /* SEARCH_INDEX_ALL */          "all"         , []() { return theTranslator->trAll();                 }, {} },
+  { /* SEARCH_INDEX_CLASSES */      "classes"     , []() { return theTranslator->trClasses();             }, {} },
+  { /* SEARCH_INDEX_INTERFACES */   "interfaces"  , []() { return theTranslator->trSliceInterfaces();     }, {} },
+  { /* SEARCH_INDEX_STRUCTS */      "structs"     , []() { return theTranslator->trStructs();             }, {} },
+  { /* SEARCH_INDEX_EXCEPTIONS */   "exceptions"  , []() { return theTranslator->trExceptions();          }, {} },
+  { /* SEARCH_INDEX_NAMESPACES */   "namespaces"  , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
+                                                                  theTranslator->trModules() :
+                                                                  theTranslator->trNamespace(TRUE,FALSE); }, {} },
+  { /* SEARCH_INDEX_FILES */        "files"       , []() { return theTranslator->trFile(TRUE,FALSE);      }, {} },
+  { /* SEARCH_INDEX_FUNCTIONS */    "functions"   , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
+                                                                  theTranslator->trOperations() :
+                                                                  theTranslator->trFunctions();           }, {} },
+  { /* SEARCH_INDEX_VARIABLES */    "variables"   , []() { return Config_getBool(OPTIMIZE_OUTPUT_SLICE) ?
+                                                                  theTranslator->trConstants() :
+                                                                  theTranslator->trVariables();           }, {} },
+  { /* SEARCH_INDEX_TYPEDEFS */     "typedefs"    , []() { return theTranslator->trTypedefs();            }, {} },
+  { /* SEARCH_INDEX_SEQUENCES */    "sequences"   , []() { return theTranslator->trSequences();           }, {} },
+  { /* SEARCH_INDEX_DICTIONARIES */ "dictionaries", []() { return theTranslator->trDictionaries();        }, {} },
+  { /* SEARCH_INDEX_ENUMS */        "enums"       , []() { return theTranslator->trEnumerations();        }, {} },
+  { /* SEARCH_INDEX_ENUMVALUES */   "enumvalues"  , []() { return theTranslator->trEnumerationValues();   }, {} },
+  { /* SEARCH_INDEX_PROPERTIES */   "properties"  , []() { return theTranslator->trProperties();          }, {} },
+  { /* SEARCH_INDEX_EVENTS */       "events"      , []() { return theTranslator->trEvents();              }, {} },
+  { /* SEARCH_INDEX_RELATED */      "related"     , []() { return theTranslator->trFriends();             }, {} },
+  { /* SEARCH_INDEX_DEFINES */      "defines"     , []() { return theTranslator->trDefines();             }, {} },
+  { /* SEARCH_INDEX_GROUPS */       "groups"      , []() { return theTranslator->trGroup(TRUE,FALSE);     }, {} },
+  { /* SEARCH_INDEX_PAGES */        "pages"       , []() { return theTranslator->trPage(TRUE,FALSE);      }, {} }
+} };
 
 static void addMemberToSearchIndex(const MemberDef *md)
 {
@@ -556,55 +643,56 @@ static void addMemberToSearchIndex(const MemberDef *md)
     QCString n = md->name();
     if (!n.isEmpty())
     {
-      uint letter = getUtf8CodeToLower(n,0);
+      char letter[MAX_UTF8_CHAR_SIZE];
+      getUtf8Char(n,letter,CaseModifier::ToLower);
       bool isFriendToHide = hideFriendCompounds &&
         (QCString(md->typeString())=="friend class" ||
          QCString(md->typeString())=="friend struct" ||
          QCString(md->typeString())=="friend union");
       if (!(md->isFriend() && isFriendToHide))
       {
-        g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,md);
       }
       if (md->isFunction() || md->isSlot() || md->isSignal())
       {
-        g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].add(letter,md);
       }
       else if (md->isVariable())
       {
-        g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_VARIABLES].add(letter,md);
       }
       else if (md->isSequence())
       {
-        g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].add(letter,md);
       }
       else if (md->isDictionary())
       {
-        g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].add(letter,md);
       }
       else if (md->isTypedef())
       {
-        g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].add(letter,md);
       }
       else if (md->isEnumerate())
       {
-        g_searchIndexInfo[SEARCH_INDEX_ENUMS].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_ENUMS].add(letter,md);
       }
       else if (md->isEnumValue())
       {
-        g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].add(letter,md);
       }
       else if (md->isProperty())
       {
-        g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].add(letter,md);
       }
       else if (md->isEvent())
       {
-        g_searchIndexInfo[SEARCH_INDEX_EVENTS].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_EVENTS].add(letter,md);
       }
       else if (md->isRelated() || md->isForeign() ||
                (md->isFriend() && !isFriendToHide))
       {
-        g_searchIndexInfo[SEARCH_INDEX_RELATED].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_RELATED].add(letter,md);
       }
     }
   }
@@ -617,155 +705,80 @@ static void addMemberToSearchIndex(const MemberDef *md)
     QCString n = md->name();
     if (!n.isEmpty())
     {
-      uint letter = getUtf8CodeToLower(n,0);
-      g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,md);
+      char letter[MAX_UTF8_CHAR_SIZE];
+      getUtf8Char(n,letter,CaseModifier::ToLower);
+      g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,md);
 
       if (md->isFunction())
       {
-        g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].add(letter,md);
       }
       else if (md->isVariable())
       {
-        g_searchIndexInfo[SEARCH_INDEX_VARIABLES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_VARIABLES].add(letter,md);
       }
       else if (md->isSequence())
       {
-        g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].add(letter,md);
       }
       else if (md->isDictionary())
       {
-        g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].add(letter,md);
       }
       else if (md->isTypedef())
       {
-        g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].add(letter,md);
       }
       else if (md->isEnumerate())
       {
-        g_searchIndexInfo[SEARCH_INDEX_ENUMS].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_ENUMS].add(letter,md);
       }
       else if (md->isEnumValue())
       {
-        g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].add(letter,md);
       }
       else if (md->isDefine())
       {
-        g_searchIndexInfo[SEARCH_INDEX_DEFINES].symbolList.append(letter,md);
+        g_searchIndexInfo[SEARCH_INDEX_DEFINES].add(letter,md);
       }
     }
   }
 }
 
-// see also function convertToId() in search.js, which should match in
-// behaviour
-static QCString searchId(const QCString &s)
-{
-  int c;
-  uint i;
-  QCString result;
-  for (i=0;i<s.length();i++)
-  {
-    c=s.at(i);
-    if (c>0x7f || c<0) // part of multibyte character
-    {
-      result+=(char)c;
-    }
-    else if (isalnum(c)) // simply alpha numerical character
-    {
-      result+=(char)tolower(c);
-    }
-    else // other 'unprintable' characters
-    {
-      char val[4];
-      sprintf(val,"_%02x",(uchar)c);
-      result+=val;
-    }
-  }
-  return result;
-}
+//---------------------------------------------------------------------------------------------
 
 void createJavaScriptSearchIndex()
 {
-  bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
-
-  // set index names
-  g_searchIndexInfo[SEARCH_INDEX_ALL].name          = "all";
-  g_searchIndexInfo[SEARCH_INDEX_CLASSES].name      = "classes";
-  g_searchIndexInfo[SEARCH_INDEX_INTERFACES].name   = "interfaces";
-  g_searchIndexInfo[SEARCH_INDEX_STRUCTS].name      = "structs";
-  g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].name   = "exceptions";
-  g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].name   = "namespaces";
-  g_searchIndexInfo[SEARCH_INDEX_FILES].name        = "files";
-  g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].name    = "functions";
-  g_searchIndexInfo[SEARCH_INDEX_VARIABLES].name    = "variables";
-  g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].name     = "typedefs";
-  g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].name    = "sequences";
-  g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].name = "dictionaries";
-  g_searchIndexInfo[SEARCH_INDEX_ENUMS].name        = "enums";
-  g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].name   = "enumvalues";
-  g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].name   = "properties";
-  g_searchIndexInfo[SEARCH_INDEX_EVENTS].name       = "events";
-  g_searchIndexInfo[SEARCH_INDEX_RELATED].name      = "related";
-  g_searchIndexInfo[SEARCH_INDEX_DEFINES].name      = "defines";
-  g_searchIndexInfo[SEARCH_INDEX_GROUPS].name       = "groups";
-  g_searchIndexInfo[SEARCH_INDEX_PAGES].name        = "pages";
-
-  // set index texts
-  g_searchIndexInfo[SEARCH_INDEX_ALL].text          = theTranslator->trAll();
-  g_searchIndexInfo[SEARCH_INDEX_CLASSES].text      = theTranslator->trClasses();
-  g_searchIndexInfo[SEARCH_INDEX_INTERFACES].text   = theTranslator->trSliceInterfaces();
-  g_searchIndexInfo[SEARCH_INDEX_STRUCTS].text      = theTranslator->trStructs();
-  g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].text   = theTranslator->trExceptions();
-  g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].text   = sliceOpt ? theTranslator->trModules() :
-                                                        theTranslator->trNamespace(TRUE,FALSE);
-  g_searchIndexInfo[SEARCH_INDEX_FILES].text        = theTranslator->trFile(TRUE,FALSE);
-  g_searchIndexInfo[SEARCH_INDEX_FUNCTIONS].text    = sliceOpt ? theTranslator->trOperations() :
-                                                        theTranslator->trFunctions();
-  g_searchIndexInfo[SEARCH_INDEX_VARIABLES].text    = sliceOpt ? theTranslator->trConstants() :
-                                                        theTranslator->trVariables();
-  g_searchIndexInfo[SEARCH_INDEX_TYPEDEFS].text     = theTranslator->trTypedefs();
-  g_searchIndexInfo[SEARCH_INDEX_SEQUENCES].text    = theTranslator->trSequences();
-  g_searchIndexInfo[SEARCH_INDEX_DICTIONARIES].text = theTranslator->trDictionaries();
-  g_searchIndexInfo[SEARCH_INDEX_ENUMS].text        = theTranslator->trEnumerations();
-  g_searchIndexInfo[SEARCH_INDEX_ENUMVALUES].text   = theTranslator->trEnumerationValues();
-  g_searchIndexInfo[SEARCH_INDEX_PROPERTIES].text   = theTranslator->trProperties();
-  g_searchIndexInfo[SEARCH_INDEX_EVENTS].text       = theTranslator->trEvents();
-  g_searchIndexInfo[SEARCH_INDEX_RELATED].text      = theTranslator->trFriends();
-  g_searchIndexInfo[SEARCH_INDEX_DEFINES].text      = theTranslator->trDefines();
-  g_searchIndexInfo[SEARCH_INDEX_GROUPS].text       = theTranslator->trGroup(TRUE,FALSE);
-  g_searchIndexInfo[SEARCH_INDEX_PAGES].text        = theTranslator->trPage(TRUE,FALSE);
-
-  // add symbols to letter -> symbol list map
-
   // index classes
   for (const auto &cd : *Doxygen::classLinkedMap)
   {
-    uint letter = getUtf8CodeToLower(cd->localName(),0);
-    if (cd->isLinkable() && isId(letter))
+    char letter[MAX_UTF8_CHAR_SIZE];
+    getUtf8Char(cd->localName(),letter,CaseModifier::ToLower);
+    if (cd->isLinkable())
     {
-      g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,cd.get());
-      if (sliceOpt)
+      g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,cd.get());
+      if (Config_getBool(OPTIMIZE_OUTPUT_SLICE))
       {
         if (cd->compoundType()==ClassDef::Interface)
         {
-          g_searchIndexInfo[SEARCH_INDEX_INTERFACES].symbolList.append(letter,cd.get());
+          g_searchIndexInfo[SEARCH_INDEX_INTERFACES].add(letter,cd.get());
         }
         else if (cd->compoundType()==ClassDef::Struct)
         {
-          g_searchIndexInfo[SEARCH_INDEX_STRUCTS].symbolList.append(letter,cd.get());
+          g_searchIndexInfo[SEARCH_INDEX_STRUCTS].add(letter,cd.get());
         }
         else if (cd->compoundType()==ClassDef::Exception)
         {
-          g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].symbolList.append(letter,cd.get());
+          g_searchIndexInfo[SEARCH_INDEX_EXCEPTIONS].add(letter,cd.get());
         }
         else // cd->compoundType()==ClassDef::Class
         {
-          g_searchIndexInfo[SEARCH_INDEX_CLASSES].symbolList.append(letter,cd.get());
+          g_searchIndexInfo[SEARCH_INDEX_CLASSES].add(letter,cd.get());
         }
       }
       else // non slice optimisation: group all types under classes
       {
-        g_searchIndexInfo[SEARCH_INDEX_CLASSES].symbolList.append(letter,cd.get());
+        g_searchIndexInfo[SEARCH_INDEX_CLASSES].add(letter,cd.get());
       }
     }
   }
@@ -773,11 +786,12 @@ void createJavaScriptSearchIndex()
   // index namespaces
   for (const auto &nd : *Doxygen::namespaceLinkedMap)
   {
-    uint letter = getUtf8CodeToLower(nd->name(),0);
-    if (nd->isLinkable() && isId(letter))
+    char letter[MAX_UTF8_CHAR_SIZE];
+    getUtf8Char(nd->name(),letter,CaseModifier::ToLower);
+    if (nd->isLinkable())
     {
-      g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,nd.get());
-      g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].symbolList.append(letter,nd.get());
+      g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,nd.get());
+      g_searchIndexInfo[SEARCH_INDEX_NAMESPACES].add(letter,nd.get());
     }
   }
 
@@ -786,11 +800,12 @@ void createJavaScriptSearchIndex()
   {
     for (const auto &fd : *fn)
     {
-      uint letter = getUtf8CodeToLower(fd->name(),0);
-      if (fd->isLinkable() && isId(letter))
+      char letter[MAX_UTF8_CHAR_SIZE];
+      getUtf8Char(fd->name(),letter,CaseModifier::ToLower);
+      if (fd->isLinkable())
       {
-        g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,fd.get());
-        g_searchIndexInfo[SEARCH_INDEX_FILES].symbolList.append(letter,fd.get());
+        g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,fd.get());
+        g_searchIndexInfo[SEARCH_INDEX_FILES].add(letter,fd.get());
       }
     }
   }
@@ -822,43 +837,33 @@ void createJavaScriptSearchIndex()
   }
 
   // index groups
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  GroupDef *gd;
-  for (gli.toFirst();(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     if (gd->isLinkable())
     {
       QCString title = gd->groupTitle();
       if (!title.isEmpty()) // TODO: able searching for all word in the title
       {
-        uchar charCode = title.at(0);
-        uint letter = charCode<128 ? tolower(charCode) : charCode;
-        if (isId(letter))
-        {
-          g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,gd);
-          g_searchIndexInfo[SEARCH_INDEX_GROUPS].symbolList.append(letter,gd);
-        }
+        char letter[MAX_UTF8_CHAR_SIZE];
+        getUtf8Char(title,letter,CaseModifier::ToLower);
+        g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,gd.get());
+        g_searchIndexInfo[SEARCH_INDEX_GROUPS].add(letter,gd.get());
       }
     }
   }
 
   // index pages
-  PageSDict::Iterator pdi(*Doxygen::pageSDict);
-  PageDef *pd=0;
-  for (pdi.toFirst();(pd=pdi.current());++pdi)
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
     if (pd->isLinkable())
     {
       QCString title = pd->title();
       if (!title.isEmpty())
       {
-        uchar charCode = title.at(0);
-        uint letter = charCode<128 ? tolower(charCode) : charCode;
-        if (isId(letter))
-        {
-          g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,pd);
-          g_searchIndexInfo[SEARCH_INDEX_PAGES].symbolList.append(letter,pd);
-        }
+        char letter[MAX_UTF8_CHAR_SIZE];
+        getUtf8Char(title,letter,CaseModifier::ToLower);
+        g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,pd.get());
+        g_searchIndexInfo[SEARCH_INDEX_PAGES].add(letter,pd.get());
       }
     }
   }
@@ -867,45 +872,43 @@ void createJavaScriptSearchIndex()
     QCString title = Doxygen::mainPage->title();
     if (!title.isEmpty())
     {
-      uchar charCode = title.at(0);
-      uint letter = charCode<128 ? tolower(charCode) : charCode;
-      if (isId(letter))
-      {
-        g_searchIndexInfo[SEARCH_INDEX_ALL].symbolList.append(letter,Doxygen::mainPage);
-        g_searchIndexInfo[SEARCH_INDEX_PAGES].symbolList.append(letter,Doxygen::mainPage);
-      }
+      char letter[MAX_UTF8_CHAR_SIZE];
+      getUtf8Char(title,letter,CaseModifier::ToLower);
+      g_searchIndexInfo[SEARCH_INDEX_ALL].add(letter,Doxygen::mainPage.get());
+      g_searchIndexInfo[SEARCH_INDEX_PAGES].add(letter,Doxygen::mainPage.get());
     }
   }
 
   // sort all lists
-  int i;
-  for (i=0;i<NUM_SEARCH_INDICES;i++)
+  for (auto &sii : g_searchIndexInfo) // for each index
   {
-    SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList);
-    SearchIndexList *sl;
-    for (it.toFirst();(sl=it.current());++it)
+    for (auto &kv : sii.symbolMap) // for each symbol in the index
     {
-      sl->sort();
+      // sort the symbols (first on "search" name, and then on full name)
+      std::sort(kv.second.begin(),
+                kv.second.end(),
+                [](const Definition *d1,const Definition *d2)
+                {
+                  int eq = qstricmp(searchName(d1),searchName(d2));         // search name first
+                  return eq==0 ? qstricmp(d1->name(),d2->name())<0 : eq<0;  // then full name
+                });
     }
   }
 }
 
 void writeJavaScriptSearchIndex()
 {
-  int i;
   int cnt = 0;
   // write index files
   QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
 
-  for (i=0;i<NUM_SEARCH_INDICES;i++) // for each index
+  for (auto &sii : g_searchIndexInfo)
   {
-    SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList);
-    SearchIndexList *sl;
     int p=0;
-    for (it.toFirst();(sl=it.current());++it,++p) // for each letter
+    for (const auto &kv : sii.symbolMap)
     {
       QCString baseName;
-      baseName.sprintf("%s_%x",g_searchIndexInfo[i].name.data(),p);
+      baseName.sprintf("%s_%x",sii.name.data(),p);
 
       QCString fileName = searchDirName + "/"+baseName+Doxygen::htmlFileExtension;
       QCString dataFileName = searchDirName + "/"+baseName+".js";
@@ -975,44 +978,61 @@ void writeJavaScriptSearchIndex()
         ti << "[" << endl;
         bool firstEntry=TRUE;
 
-        SDict<SearchDefinitionList>::Iterator li(*sl);
-        SearchDefinitionList *dl;
-        int itemCount=0;
-        for (li.toFirst();(dl=li.current());++li)
+        int childCount=0;
+        QCString lastName;
+        const Definition *prevScope = 0;
+        for (auto it = kv.second.begin(); it!=kv.second.end();)
         {
-          const Definition *d = dl->getFirst();
+          const Definition *d = *it;
+          QCString sname = searchName(d);
+          QCString id    = searchId(d);
 
-          if (!firstEntry)
+          if (sname!=lastName) // this item has a different search word
           {
-            ti << "," << endl;
+            if (!firstEntry)
+            {
+              ti << "]]]";
+              ti << "," << endl;
+            }
+            firstEntry=FALSE;
+
+            ti << "  ['" << id << "_" << cnt++ << "',['" << convertToXML(sname) << "',[";
+            childCount=0;
+            prevScope=0;
           }
-          firstEntry=FALSE;
 
-          ti << "  ['" << dl->id() << "_" << cnt++ << "',['" << convertToXML(dl->name()) << "',[";
+          ++it;
+          const Definition *scope     = d->getOuterScope();
+          const Definition *next      = it!=kv.second.end() ? *it : 0;
+          const Definition *nextScope = 0;
+          const MemberDef  *md        = toMemberDef(d);
+          if (next) nextScope = next->getOuterScope();
+          QCString anchor = d->anchor();
 
-          if (dl->count()==1) // item with a unique name
+          if (childCount>0)
           {
-            const MemberDef  *md = toMemberDef(d);
-            QCString anchor = d->anchor();
-
-            ti << "'" << externalRef("../",d->getReference(),TRUE)
-              << addHtmlExtensionIfMissing(d->getOutputFileBase());
-            if (!anchor.isEmpty())
-            {
-              ti << "#" << anchor;
-            }
-            ti << "',";
+            ti << "],[";
+          }
+          ti << "'" << externalRef("../",d->getReference(),TRUE)
+            << addHtmlExtensionIfMissing(d->getOutputFileBase());
+          if (!anchor.isEmpty())
+          {
+            ti << "#" << anchor;
+          }
+          ti << "',";
 
-            static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
-            if (!extLinksInWindow || d->getReference().isEmpty())
-            {
-              ti << "1,";
-            }
-            else
-            {
-              ti << "0,";
-            }
+          static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
+          if (!extLinksInWindow || d->getReference().isEmpty())
+          {
+            ti << "1,";
+          }
+          else
+          {
+            ti << "0,";
+          }
 
+          if (lastName!=sname && (next==0 || searchName(next)!=sname)) // unique name
+          {
             if (d->getOuterScope()!=Doxygen::globalScope)
             {
               ti << "'" << convertToXML(d->getOuterScope()->name()) << "'";
@@ -1030,127 +1050,84 @@ void writeJavaScriptSearchIndex()
             {
               ti << "''";
             }
-            ti << "]]";
           }
-          else // multiple items with the same name
+          else // multiple entries with the same name
           {
-            QListIterator<Definition> di(*dl);
-            bool overloadedFunction = FALSE;
-            const Definition *prevScope = 0;
-            int childCount=0;
-            for (di.toFirst();(d=di.current());)
+            bool found=FALSE;
+            bool overloadedFunction = ((prevScope!=0 && scope==prevScope) ||
+                (scope && scope==nextScope)) && md && (md->isFunction() || md->isSlot());
+            QCString prefix;
+            if (md) prefix=convertToXML(md->localName());
+            if (overloadedFunction) // overloaded member function
             {
-              ++di;
-              const Definition *scope     = d->getOuterScope();
-              const Definition *next      = di.current();
-              const Definition *nextScope = 0;
-              const MemberDef  *md        = toMemberDef(d);
-              if (next) nextScope = next->getOuterScope();
-              QCString anchor = d->anchor();
-
-              if (childCount>0)
-              {
-                ti << "],[";
-              }
-              ti << "'" << externalRef("../",d->getReference(),TRUE)
-                << addHtmlExtensionIfMissing(d->getOutputFileBase());
-              if (!anchor.isEmpty())
-              {
-                ti << "#" << anchor;
-              }
-              ti << "',";
-
-              static bool extLinksInWindow = Config_getBool(EXT_LINKS_IN_WINDOW);
-              if (!extLinksInWindow || d->getReference().isEmpty())
-              {
-                ti << "1,";
-              }
-              else
-              {
-                ti << "0,";
-              }
-              bool found=FALSE;
-              overloadedFunction = ((prevScope!=0 && scope==prevScope) ||
-                  (scope && scope==nextScope)
-                  ) && md &&
-                (md->isFunction() || md->isSlot());
-              QCString prefix;
-              if (md) prefix=convertToXML(md->localName());
-              if (overloadedFunction) // overloaded member function
-              {
-                prefix+=convertToXML(md->argsString());
-                // show argument list to disambiguate overloaded functions
-              }
-              else if (md) // unique member function
-              {
-                prefix+="()"; // only to show it is a function
-              }
-              QCString name;
-              if (d->definitionType()==Definition::TypeClass)
-              {
-                name = convertToXML((toClassDef(d))->displayName());
-                found = TRUE;
-              }
-              else if (d->definitionType()==Definition::TypeNamespace)
-              {
-                name = convertToXML((toNamespaceDef(d))->displayName());
-                found = TRUE;
-              }
-              else if (scope==0 || scope==Doxygen::globalScope) // in global scope
+              prefix+=convertToXML(md->argsString());
+              // show argument list to disambiguate overloaded functions
+            }
+            else if (md) // unique member function
+            {
+              prefix+="()"; // only to show it is a function
+            }
+            QCString name;
+            if (d->definitionType()==Definition::TypeClass)
+            {
+              name = convertToXML((toClassDef(d))->displayName());
+              found = TRUE;
+            }
+            else if (d->definitionType()==Definition::TypeNamespace)
+            {
+              name = convertToXML((toNamespaceDef(d))->displayName());
+              found = TRUE;
+            }
+            else if (scope==0 || scope==Doxygen::globalScope) // in global scope
+            {
+              if (md)
               {
-                if (md)
+                const FileDef *fd = md->getBodyDef();
+                if (fd==0) fd = md->resolveAlias()->getFileDef();
+                if (fd)
                 {
-                  const FileDef *fd = md->getBodyDef();
-                  if (fd==0) fd = md->resolveAlias()->getFileDef();
-                  if (fd)
-                  {
-                    if (!prefix.isEmpty()) prefix+=":&#160;";
-                    name = prefix + convertToXML(fd->localName());
-                    found = TRUE;
-                  }
+                  if (!prefix.isEmpty()) prefix+=":&#160;";
+                  name = prefix + convertToXML(fd->localName());
+                  found = TRUE;
                 }
               }
-              else if (md && (md->resolveAlias()->getClassDef() || md->resolveAlias()->getNamespaceDef()))
-                // member in class or namespace scope
-              {
-                SrcLangExt lang = md->getLanguage();
-                name = convertToXML(d->getOuterScope()->qualifiedName())
-                  + getLanguageSpecificSeparator(lang) + prefix;
-                found = TRUE;
-              }
-              else if (scope) // some thing else? -> show scope
-              {
-                name = prefix + convertToXML(scope->name());
-                found = TRUE;
-              }
-              if (!found) // fallback
-              {
-                name = prefix + "("+theTranslator->trGlobalNamespace()+")";
-              }
-
-              ti << "'" << name << "'";
-
-              prevScope = scope;
-              childCount++;
             }
+            else if (md && (md->resolveAlias()->getClassDef() || md->resolveAlias()->getNamespaceDef()))
+              // member in class or namespace scope
+            {
+              SrcLangExt lang = md->getLanguage();
+              name = convertToXML(d->getOuterScope()->qualifiedName())
+                + getLanguageSpecificSeparator(lang) + prefix;
+              found = TRUE;
+            }
+            else if (scope) // some thing else? -> show scope
+            {
+              name = prefix + convertToXML(scope->name());
+              found = TRUE;
+            }
+            if (!found) // fallback
+            {
+              name = prefix + "("+theTranslator->trGlobalNamespace()+")";
+            }
+
+            ti << "'" << name << "'";
 
-            ti << "]]";
+            prevScope = scope;
+            childCount++;
           }
-          ti << "]";
-          itemCount++;
+          lastName = sname;
         }
         if (!firstEntry)
         {
-          ti << endl;
+          ti << "]]]" << endl;
         }
-
         ti << "];" << endl;
-
       }
       else
       {
         err("Failed to open file '%s' for writing...\n",fileName.data());
       }
+      p++;
     }
   }
 
@@ -1161,64 +1138,57 @@ void writeJavaScriptSearchIndex()
       FTextStream t(&f);
       t << "var indexSectionsWithContent =" << endl;
       t << "{" << endl;
-      bool first=TRUE;
       int j=0;
-      for (i=0;i<NUM_SEARCH_INDICES;i++)
+      for (const auto &sii : g_searchIndexInfo)
       {
-        if (g_searchIndexInfo[i].symbolList.count()>0)
+        if (!sii.symbolMap.empty())
         {
-          if (!first) t << "," << endl;
+          if (j>0) t << "," << endl;
           t << "  " << j << ": \"";
 
-          SIntDict<SearchIndexList>::Iterator it(g_searchIndexInfo[i].symbolList);
-          SearchIndexList *sl;
-          for (it.toFirst();(sl=it.current());++it) // for each letter
+          for (const auto &kv : sii.symbolMap)
           {
-            if ( sl->letter() == '"' ) t << QString( QChar( '\\' ) ).utf8();
-            t << QString( QChar( sl->letter() ) ).utf8();
+            if ( kv.first == "\"" ) t << "\\";
+            t << kv.first.c_str();
           }
           t << "\"";
-          first=FALSE;
           j++;
         }
       }
-      if (!first) t << "\n";
+      if (j>0) t << "\n";
       t << "};" << endl << endl;
       t << "var indexSectionNames =" << endl;
       t << "{" << endl;
-      first=TRUE;
       j=0;
-      for (i=0;i<NUM_SEARCH_INDICES;i++)
+      for (const auto &sii : g_searchIndexInfo)
       {
-        if (g_searchIndexInfo[i].symbolList.count()>0)
+        if (!sii.symbolMap.empty())
         {
-          if (!first) t << "," << endl;
-          t << "  " << j << ": \"" << g_searchIndexInfo[i].name << "\"";
-          first=FALSE;
+          if (j>0) t << "," << endl;
+          t << "  " << j << ": \"" << sii.name << "\"";
           j++;
         }
       }
-      if (!first) t << "\n";
+      if (j>0) t << "\n";
       t << "};" << endl << endl;
       t << "var indexSectionLabels =" << endl;
       t << "{" << endl;
-      first=TRUE;
       j=0;
-      for (i=0;i<NUM_SEARCH_INDICES;i++)
+      for (const auto &sii : g_searchIndexInfo)
       {
-        if (g_searchIndexInfo[i].symbolList.count()>0)
+        if (!sii.symbolMap.empty())
         {
-          if (!first) t << "," << endl;
-          t << "  " << j << ": \"" << convertToXML(g_searchIndexInfo[i].text) << "\"";
-          first=FALSE;
+          if (j>0) t << "," << endl;
+          t << "  " << j << ": \"" << convertToXML(sii.getText()) << "\"";
           j++;
         }
       }
-      if (!first) t << "\n";
+      if (j>0) t << "\n";
       t << "};" << endl << endl;
     }
     ResourceMgr::instance().copyResource("search.js",searchDirName);
   }
+
   {
     QFile f(searchDirName+"/nomatches"+Doxygen::htmlFileExtension);
     if (f.open(IO_WriteOnly))
@@ -1244,53 +1214,23 @@ void writeJavaScriptSearchIndex()
   Doxygen::indexList->addStyleSheetFile("search/search.js");
 }
 
-const SearchIndexInfo *getSearchIndices()
+void SearchIndexInfo::add(const std::string &letter,const Definition *def)
 {
-  return g_searchIndexInfo;
-}
-
-//---------------------------------------------------------------------------------------------
-
-SearchIndexList::SearchIndexList(uint letter)
-  : SDict< SearchDefinitionList >(17,FALSE), m_letter(letter)
-{
-  setAutoDelete(TRUE);
-}
-
-SearchIndexList::~SearchIndexList()
-{
-}
-
-void SearchIndexList::append(const Definition *d)
-{
-  QCString dispName = d->localName();
-  SearchDefinitionList *l = find(dispName);
-  if (l==0)
+  //printf("%p: %s->%s (full=%s)\n",this,letter.data(),searchName(def).data(),def->name().data());
+  auto it = symbolMap.find(letter);
+  if (it!=symbolMap.end())
   {
-    if (d->definitionType()==Definition::TypeGroup)
-    {
-      dispName = (toGroupDef(d))->groupTitle();
-    }
-    else if (d->definitionType()==Definition::TypePage)
-    {
-      dispName = (toPageDef(d))->title();
-    }
-    l=new SearchDefinitionList(searchId(dispName),dispName);
-    SDict< SearchDefinitionList >::append(dispName,l);
+    it->second.push_back(def);
+  }
+  else
+  {
+    symbolMap.insert(std::make_pair(letter,std::vector<const Definition*>({def})));
   }
-  l->append(d);
-}
-
-uint SearchIndexList::letter() const
-{
-  return m_letter;
 }
 
-int SearchIndexList::compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const
+const std::array<SearchIndexInfo,NUM_SEARCH_INDICES> &getSearchIndices()
 {
-  QCString n1 = md1->getFirst()->localName();
-  QCString n2 = md2->getFirst()->localName();
-  return qstricmp(n1.data(),n2.data());
+  return g_searchIndexInfo;
 }
 
 //---------------------------------------------------------------------------------------------
index 71c1ce1..9039f00 100644 (file)
@@ -1,8 +1,6 @@
 /******************************************************************************
  *
- *
- *
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
+ * Copyright (C) 1997-2020 by Dimitri van Heesch.
  *
  * Permission to use, copy, modify, and distribute this software and its
  * documentation under the terms of the GNU General Public License is hereby
  *
  */
 
-#ifndef _SEARCHINDEX_H
-#define _SEARCHINDEX_H
+#ifndef SEARCHINDEX_H
+#define SEARCHINDEX_H
 
 #include <memory>
 #include <vector>
 #include <map>
 #include <unordered_map>
 #include <string>
+#include <array>
+#include <functional>
 
-#include <qintdict.h>
-#include <qlist.h>
-#include <qintdict.h>
-#include "sortdict.h"
-#include "definition.h"
-#include "util.h"
+#include <qcstring.h>
 
-class FTextStream;
 class Definition;
-class MemberDef;
 
 /*! Initialize the search indexer */
 void initSearchIndexer();
@@ -116,61 +109,24 @@ class SearchIndexExternal : public SearchIndexIntf
 
 //------- client side search index ----------------------
 
-#define SEARCH_INDEX_ALL           0
-#define SEARCH_INDEX_CLASSES       1
-#define SEARCH_INDEX_INTERFACES    2
-#define SEARCH_INDEX_STRUCTS       3
-#define SEARCH_INDEX_EXCEPTIONS    4
-#define SEARCH_INDEX_NAMESPACES    5
-#define SEARCH_INDEX_FILES         6
-#define SEARCH_INDEX_FUNCTIONS     7
-#define SEARCH_INDEX_VARIABLES     8
-#define SEARCH_INDEX_TYPEDEFS      9
-#define SEARCH_INDEX_SEQUENCES    10
-#define SEARCH_INDEX_DICTIONARIES 11
-#define SEARCH_INDEX_ENUMS        12
-#define SEARCH_INDEX_ENUMVALUES   13
-#define SEARCH_INDEX_PROPERTIES   14
-#define SEARCH_INDEX_EVENTS       15
-#define SEARCH_INDEX_RELATED      16
-#define SEARCH_INDEX_DEFINES      17
-#define SEARCH_INDEX_GROUPS       18
-#define SEARCH_INDEX_PAGES        19
-#define NUM_SEARCH_INDICES        20
-
-class SearchDefinitionList : public QList<Definition>
-{
-  public:
-    SearchDefinitionList(const QCString &id,const QCString &name) : m_id(id), m_name(name) {}
-    QCString id() const   { return m_id;   }
-    QCString name() const { return m_name; }
-  private:
-    QCString m_id;
-    QCString m_name;
-};
+#define NUM_SEARCH_INDICES 20
 
-class SearchIndexList : public SDict< SearchDefinitionList >
-{
-  public:
-    typedef const Definition ElementType;
-    SearchIndexList(uint letter);
-   ~SearchIndexList();
-    void append(const Definition *d);
-    uint letter() const;
-  private:
-    int compareValues(const SearchDefinitionList *md1, const SearchDefinitionList *md2) const;
-    uint m_letter;
-};
+QCString searchId(const Definition *d);
+QCString searchName(const Definition *d);
+
+using SearchIndexList = std::vector<const Definition *>;
+using SearchIndexMap  = std::map<std::string,SearchIndexList>;
 
 struct SearchIndexInfo
 {
-  LetterToIndexMap<SearchIndexList> symbolList;
+  void add(const std::string &letter,const Definition *def);
   QCString name;
-  QCString text;
+  std::function<QCString()> getText;
+  SearchIndexMap symbolMap;
 };
 
 void createJavaScriptSearchIndex();
 void writeJavaScriptSearchIndex();
-const SearchIndexInfo *getSearchIndices();
+const std::array<SearchIndexInfo,NUM_SEARCH_INDICES> &getSearchIndices();
 
 #endif
index 15282ec..907cb78 100644 (file)
@@ -1,13 +1,13 @@
 /******************************************************************************
  *
- * 
+ *
  *
  *
  * Copyright (C) 1997-2015 by Dimitri van Heesch.
  *
  * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby 
- * granted. No representations are made about the suitability of this software 
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
  * for any purpose. It is provided "as is" without express or implied warranty.
  * See the GNU General Public License for more details.
  *
@@ -26,7 +26,7 @@
 #define AUTORESIZE 1
 
 #if AUTORESIZE
-const uint SDict_primes[] = 
+const uint SDict_primes[] =
 {
   17,
   29,
@@ -71,10 +71,9 @@ const uint SDict_primes[] =
 #endif
 
 template<class T> class SDict;
-template<class T> class SIntDict;
 
-/** internal wrapper class that redirects compareValues() to the 
- *  dictionary 
+/** internal wrapper class that redirects compareValues() to the
+ *  dictionary
  */
 template<class T>
 class SList : public QList<T>
@@ -87,20 +86,20 @@ class SList : public QList<T>
       return m_owner->compareValues(item1,item2);
     }
   private:
-    SDict<T> *m_owner;  
+    SDict<T> *m_owner;
 };
 
-/** Ordered dictionary of elements of type T. 
+/** Ordered dictionary of elements of type T.
  *  Internally uses a QList<T> and a QDict<T>.
  */
 template<class T>
-class SDict 
+class SDict
 {
   private:
     SList<T> *m_list;
     QDict<T> *m_dict;
     uint m_sizeIndex;
-    
+
   public:
     /*! Create an ordered dictionary.
      *  \param size The size of the dictionary. Should be a prime number for
@@ -120,7 +119,7 @@ class SDict
     }
 
     /*! Destroys the dictionary */
-    virtual ~SDict() 
+    virtual ~SDict()
     {
       delete m_list;
       delete m_dict;
@@ -182,7 +181,7 @@ class SDict
     }
 
     /*! Sorts the members of the dictionary. First appending a number
-     *  of members and then sorting them is faster (O(NlogN) than using 
+     *  of members and then sorting them is faster (O(NlogN) than using
      *  inSort() for each member (O(N^2)).
      */
     void sort()
@@ -224,10 +223,10 @@ class SDict
       m_list->setAutoDelete(val);
     }
 
-    /*! Looks up a compound given its key. 
+    /*! Looks up a compound given its key.
      *  \param key The key to identify this element.
      *  \return The requested compound or zero if it cannot be found.
-     *  \sa append() 
+     *  \sa append()
      */
     T *find(const char *key)
     {
@@ -274,7 +273,7 @@ class SDict
       m_list->clear();
       m_dict->clear();
     }
-    
+
     /*! Returns the number of items stored in the dictionary
      */
     uint count() const
@@ -302,16 +301,16 @@ class SDict
           delete m_li;
         }
 
-        /*! Set the iterator to the first element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
+        /*! Set the iterator to the first element in the list.
+         *  \return The first compound, or zero if the list was empty.
          */
         T *toFirst() const
         {
           return m_li->toFirst();
         }
 
-        /*! Set the iterator to the last element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
+        /*! Set the iterator to the last element in the list.
+         *  \return The first compound, or zero if the list was empty.
          */
         T *toLast() const
         {
@@ -323,7 +322,7 @@ class SDict
         {
           return m_li->current();
         }
-        
+
         /*! Moves the iterator to the next element.
          *  \return the new "current" element, or zero if the iterator was
          *          already pointing at the last element.
@@ -366,16 +365,16 @@ class SDict
           delete m_di;
         }
 
-        /*! Set the iterator to the first element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
+        /*! Set the iterator to the first element in the list.
+         *  \return The first compound, or zero if the list was empty.
          */
         T *toFirst() const
         {
           return m_di->toFirst();
         }
 
-        /*! Set the iterator to the last element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
+        /*! Set the iterator to the last element in the list.
+         *  \return The first compound, or zero if the list was empty.
          */
         T *toLast() const
         {
@@ -387,322 +386,13 @@ class SDict
         {
           return m_di->current();
         }
-        
+
         /*! Returns the current key */
         QCString currentKey() const
         {
           return m_di->currentKey();
         }
-        
-        /*! Moves the iterator to the next element.
-         *  \return the new "current" element, or zero if the iterator was
-         *          already pointing at the last element.
-         */
-        T *operator++()
-        {
-          return m_di->operator++();
-        }
-
-        /*! Moves the iterator to the previous element.
-         *  \return the new "current" element, or zero if the iterator was
-         *          already pointing at the first element.
-         */
-        T *operator--()
-        {
-          return m_di->operator--();
-        }
-
-      private:
-        QDictIterator<T> *m_di;
-    };
-};
-
-/** internal wrapper class that redirects compareValues() to the 
- *  dictionary 
- */
-template<class T>
-class SIntList : public QList<T>
-{
-  public:
-    SIntList(SIntDict<T> *owner) : m_owner(owner) {}
-    virtual ~SIntList() {}
-  private:
-    int compareValues(const T *item1,const T *item2) const
-    {
-      return m_owner->compareValues(item1,item2);
-    }
-    SIntDict<T> *m_owner;  
-};
-
-/** Ordered dictionary of elements of type T. 
- *  Internally uses a QList<T> and a QIntDict<T>.
- */
-template<class T>
-class SIntDict 
-{
-  private:
-    SIntList<T> *m_list;
-    QIntDict<T> *m_dict;
-    int m_sizeIndex;
-    
-  public:
-    /*! Create an ordered dictionary.
-     *  \param size The size of the dictionary. Should be a prime number for
-     *              best distribution of elements.
-     */
-    SIntDict(int size=17) : m_sizeIndex(0)
-    {
-      m_list = new SIntList<T>(this);
-#if AUTORESIZE
-      while ((uint)size>SDict_primes[m_sizeIndex]) m_sizeIndex++;
-      m_dict = new QIntDict<T>(SDict_primes[m_sizeIndex]);
-#else
-      m_dict = new QIntDict<T>(size);
-#endif
-    }
-
-    /*! Destroys the dictionary */
-    virtual ~SIntDict() 
-    {
-      delete m_list;
-      delete m_dict;
-    }
-
-    /*! Appends a compound to the dictionary. The element is owned by the
-     *  dictionary.
-     *  \param key The unique key to use to quickly find the item later on.
-     *  \param d The compound to add.
-     *  \sa find()
-     */
-    void append(int key,const T *d)
-    {
-      m_list->append(d);
-      m_dict->insert(key,d);
-#if AUTORESIZE
-      if (m_dict->size()>SDict_primes[m_sizeIndex])
-      {
-        m_dict->resize(SDict_primes[++m_sizeIndex]);
-      }
-#endif
-    }
-
-    /*! Prepend a compound to the dictionary. The element is owned by the
-     *  dictionary.
-     *  \param key The unique key to use to quickly find the item later on.
-     *  \param d The compound to add.
-     *  \sa find()
-     */
-    void prepend(int key,const T *d)
-    {
-      m_list->prepend(d);
-      m_dict->insert(key,d);
-#if AUTORESIZE
-      if (m_dict->size()>SDict_primes[m_sizeIndex])
-      {
-        m_dict->resize(SDict_primes[++m_sizeIndex]);
-      }
-#endif
-    }
-
-    /*! Remove an item from the dictionary */
-    bool remove(int key)
-    {
-      T *item = m_dict->take(key);
-      return item ? m_list->remove(item) : FALSE;
-    }
-
-    /*! Sorts the members of the dictionary. First appending a number
-     *  of members and then sorting them is faster (O(NlogN) than using 
-     *  inSort() for each member (O(N^2)).
-     */
-    void sort()
-    {
-      m_list->sort();
-    }
-
-    /*! Inserts a compound into the dictionary in a sorted way.
-     *  \param key The unique key to use to quickly find the item later on.
-     *  \param d The compound to add.
-     *  \sa find()
-     */
-    void inSort(int key,const T *d)
-    {
-      m_list->inSort(d);
-      m_dict->insert(key,d);
-#if AUTORESIZE
-      if (m_dict->size()>SDict_primes[m_sizeIndex])
-      {
-        m_dict->resize(SDict_primes[++m_sizeIndex]);
-      }
-#endif
-    }
-
-    /*! Indicates whether or not the dictionary owns its elements */
-    void setAutoDelete(bool val)
-    {
-      m_list->setAutoDelete(val);
-    }
-
-    /*! Looks up a compound given its key. 
-     *  \param key The key to identify this element.
-     *  \return The requested compound or zero if it cannot be found.
-     *  \sa append() 
-     */
-    T *find(int key)
-    {
-      return m_dict->find(key);
-    }
-
-    /*! Equivalent to find(). */
-    T *operator[](int key) const
-    {
-      return m_dict->find(key);
-    }
-
-    /*! Returns the item at position \a i in the sorted dictionary */
-    T *at(uint i)
-    {
-      return m_list->at(i);
-    }
-
-    /*! Function that is used to compare two items when sorting.
-     *  Overload this to properly sort items.
-     *  \sa inSort()
-     */
-    virtual int compareValues(const T *item1,const T *item2) const
-    {
-      return item1!=item2;
-    }
-
-    /*! Clears the dictionary. Will delete items if setAutoDelete() was
-     *  set to \c TRUE.
-     *  \sa setAutoDelete
-     */
-    void clear()
-    {
-      m_list->clear();
-      m_dict->clear();
-    }
-
-    /*! Returns the number of items stored in the dictionary
-     */
-    int count() const
-    {
-      return m_list->count();
-    }
-
-    class Iterator;         // first forward declare
-    friend class Iterator;  // then make it a friend
-    /*! Simple iterator for SDict. It iterates in the order in which the
-     *  elements are stored.
-     */
-    class Iterator
-    {
-      public:
-        /*! Create an iterator given the dictionary. */
-        Iterator(const SIntDict<T> &dict)
-        {
-          m_li = new QListIterator<T>(*dict.m_list);
-        }
-        
-        /*! Destroys the dictionary */
-        virtual ~Iterator()
-        {
-          delete m_li;
-        }
-        
-        /*! Set the iterator to the first element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
-         */
-        T *toFirst() const
-        {
-          return m_li->toFirst();
-        }
-        
-        /*! Set the iterator to the last element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
-         */
-        T *toLast() const
-        {
-          return m_li->toLast();
-        }
-        
-        /*! Returns the current compound */
-        T *current() const
-        {
-          return m_li->current();
-        }
-
-        /*! Moves the iterator to the next element.
-         *  \return the new "current" element, or zero if the iterator was
-         *          already pointing at the last element.
-         */
-        T *operator++()
-        {
-          return m_li->operator++();
-        }
-        
-        /*! Moves the iterator to the previous element.
-         *  \return the new "current" element, or zero if the iterator was
-         *          already pointing at the first element.
-         */
-        T *operator--()
-        {
-          return m_li->operator--();
-        }
-
-      private:
-        QListIterator<T> *m_li;
-    };
-
-    class IteratorDict;         // first forward declare
-    friend class IteratorDict;  // then make it a friend
-    /*! Simple iterator for SDict. It iterates over the dictionary elements
-     *  in an unsorted way, but does provide information about the element's key.
-     */
-    class IteratorDict
-    {
-      public:
-        /*! Create an iterator given the dictionary. */
-        IteratorDict(const SIntDict<T> &dict)
-        {
-          m_di = new QIntDictIterator<T>(*dict.m_dict);
-        }
 
-        /*! Destroys the dictionary */
-        virtual ~IteratorDict()
-        {
-          delete m_di;
-        }
-
-        /*! Set the iterator to the first element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
-         */
-        T *toFirst() const
-        {
-          return m_di->toFirst();
-        }
-
-        /*! Set the iterator to the last element in the list. 
-         *  \return The first compound, or zero if the list was empty. 
-         */
-        T *toLast() const
-        {
-          return m_di->toLast();
-        }
-
-        /*! Returns the current compound */
-        T *current() const
-        {
-          return m_di->current();
-        }
-        
-        /*! Returns the current key */
-        int currentKey() const
-        {
-          return m_di->currentKey();
-        }
-        
         /*! Moves the iterator to the next element.
          *  \return the new "current" element, or zero if the iterator was
          *          already pointing at the last element.
@@ -724,7 +414,7 @@ class SIntDict
       private:
         QDictIterator<T> *m_di;
     };
-
 };
 
+
 #endif
index 97c7337..67adebf 100644 (file)
@@ -1279,13 +1279,9 @@ static void writeInnerClasses(const ClassLinkedRefMap &cl, struct Refid outer_re
   }
 }
 
-static void writeInnerPages(const PageSDict *pl, struct Refid outer_refid)
+static void writeInnerPages(const PageLinkedRefMap &pl, struct Refid outer_refid)
 {
-  if (!pl) return;
-
-  PageSDict::Iterator pli(*pl);
-  const PageDef *pd;
-  for (pli.toFirst();(pd=pli.current());++pli)
+  for (const auto &pd : pl)
   {
     struct Refid inner_refid = insertRefid(
       pd->getGroupDef() ? pd->getOutputFileBase()+"_"+pd->name() : pd->getOutputFileBase()
@@ -1294,24 +1290,18 @@ static void writeInnerPages(const PageSDict *pl, struct Refid outer_refid)
     bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
     bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
     step(contains_insert);
-
   }
 }
 
-static void writeInnerGroups(const GroupList *gl, struct Refid outer_refid)
+static void writeInnerGroups(const GroupList &gl, struct Refid outer_refid)
 {
-  if (gl)
+  for (const auto &sgd : gl)
   {
-    GroupListIterator gli(*gl);
-    const GroupDef *sgd;
-    for (gli.toFirst();(sgd=gli.current());++gli)
-    {
-      struct Refid inner_refid = insertRefid(sgd->getOutputFileBase());
+    struct Refid inner_refid = insertRefid(sgd->getOutputFileBase());
 
-      bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
-      bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
-      step(contains_insert);
-    }
+    bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
+    bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
+    step(contains_insert);
   }
 }
 
@@ -2015,25 +2005,18 @@ static void generateSqlite3ForClass(const ClassDef *cd)
   writeTemplateList(cd);
 
   // + member groups
-  if (cd->getMemberGroupSDict())
+  for (const auto &mg : cd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateSqlite3Section(cd,mg->members(),refid,"user-defined",mg->header(),
-          mg->documentation());
-    }
+    generateSqlite3Section(cd,mg->members(),refid,"user-defined",mg->header(),
+        mg->documentation());
   }
 
   // this is just a list of *local* members
-  QListIterator<MemberList> mli(cd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : cd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_detailedLists)==0)
     {
-      generateSqlite3Section(cd,ml,refid,"user-defined");
+      generateSqlite3Section(cd,ml.get(),refid,"user-defined");
     }
   }
 
@@ -2079,25 +2062,18 @@ static void generateSqlite3ForNamespace(const NamespaceDef *nd)
   writeInnerNamespaces(nd->getNamespaces(),refid);
 
   // + member groups
-  if (nd->getMemberGroupSDict())
+  for (const auto &mg : nd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateSqlite3Section(nd,mg->members(),refid,"user-defined",mg->header(),
-          mg->documentation());
-    }
+    generateSqlite3Section(nd,mg->members(),refid,"user-defined",mg->header(),
+        mg->documentation());
   }
 
   // + normal members
-  QListIterator<MemberList> mli(nd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : nd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_declarationLists)!=0)
     {
-      generateSqlite3Section(nd,ml,refid,"user-defined");
+      generateSqlite3Section(nd,ml.get(),refid,"user-defined");
     }
   }
 }
@@ -2241,25 +2217,18 @@ static void generateSqlite3ForFile(const FileDef *fd)
   writeInnerNamespaces(fd->getNamespaces(),refid);
 
   // + member groups
-  if (fd->getMemberGroupSDict())
+  for (const auto &mg : fd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateSqlite3Section(fd,mg->members(),refid,"user-defined",mg->header(),
+    generateSqlite3Section(fd,mg->members(),refid,"user-defined",mg->header(),
           mg->documentation());
-    }
   }
 
   // + normal members
-  QListIterator<MemberList> mli(fd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : fd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_declarationLists)!=0)
     {
-      generateSqlite3Section(fd,ml,refid,"user-defined");
+      generateSqlite3Section(fd,ml.get(),refid,"user-defined");
     }
   }
 }
@@ -2315,25 +2284,18 @@ static void generateSqlite3ForGroup(const GroupDef *gd)
   writeInnerGroups(gd->getSubGroups(),refid);
 
   // + member groups
-  if (gd->getMemberGroupSDict())
+  for (const auto &mg : gd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateSqlite3Section(gd,mg->members(),refid,"user-defined",mg->header(),
-          mg->documentation());
-    }
+    generateSqlite3Section(gd,mg->members(),refid,"user-defined",mg->header(),
+        mg->documentation());
   }
 
   // + members
-  QListIterator<MemberList> mli(gd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : gd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_declarationLists)!=0)
     {
-      generateSqlite3Section(gd,ml,refid,"user-defined");
+      generateSqlite3Section(gd,ml.get(),refid,"user-defined");
     }
   }
 }
@@ -2413,7 +2375,7 @@ static void generateSqlite3ForPage(const PageDef *pd,bool isExample)
   bindTextParameter(compounddef_insert,":name",pd->name());
 
   QCString title;
-  if (pd==Doxygen::mainPage) // main page is special
+  if (pd==Doxygen::mainPage.get()) // main page is special
   {
     if (mainPageHasTitle())
     {
@@ -2564,52 +2526,38 @@ void generateSqlite3()
   }
 
   // + groups
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  const GroupDef *gd;
-  for (;(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     msg("Generating Sqlite3 output for group %s\n",gd->name().data());
-    generateSqlite3ForGroup(gd);
+    generateSqlite3ForGroup(gd.get());
   }
 
   // + page
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
-    PageSDict::Iterator pdi(*Doxygen::pageSDict);
-    const PageDef *pd=0;
-    for (pdi.toFirst();(pd=pdi.current());++pdi)
-    {
-      msg("Generating Sqlite3 output for page %s\n",pd->name().data());
-      generateSqlite3ForPage(pd,FALSE);
-    }
+    msg("Generating Sqlite3 output for page %s\n",pd->name().data());
+    generateSqlite3ForPage(pd.get(),FALSE);
   }
 
   // + dirs
+  for (const auto &dd : *Doxygen::dirLinkedMap)
   {
-    const DirDef *dir;
-    DirSDict::Iterator sdi(*Doxygen::directories);
-    for (sdi.toFirst();(dir=sdi.current());++sdi)
-    {
-      msg("Generating Sqlite3 output for dir %s\n",dir->name().data());
-      generateSqlite3ForDir(dir);
-    }
+    msg("Generating Sqlite3 output for dir %s\n",dd->name().data());
+    generateSqlite3ForDir(dd.get());
   }
 
   // + examples
+  for (const auto &pd : *Doxygen::exampleLinkedMap)
   {
-    PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-    const PageDef *pd=0;
-    for (pdi.toFirst();(pd=pdi.current());++pdi)
-    {
-      msg("Generating Sqlite3 output for example %s\n",pd->name().data());
-      generateSqlite3ForPage(pd,TRUE);
-    }
+    msg("Generating Sqlite3 output for example %s\n",pd->name().data());
+    generateSqlite3ForPage(pd.get(),TRUE);
   }
 
   // + main page
   if (Doxygen::mainPage)
   {
     msg("Generating Sqlite3 output for the main page\n");
-    generateSqlite3ForPage(Doxygen::mainPage,FALSE);
+    generateSqlite3ForPage(Doxygen::mainPage.get(),FALSE);
   }
 
   // TODO: copied from initializeSchema; not certain if we should say/do more
index 58188fe..d5e8275 100644 (file)
@@ -2669,7 +2669,10 @@ void TemplateContextImpl::addIndexEntry(const QCString &indexName,const std::vec
   if (list->count()>0)
   {
     TemplateStruct *lastEntry = dynamic_cast<TemplateStruct*>(list->at(list->count()-1).toStruct());
-    lastEntry->set("last",false);
+    if (lastEntry)
+    {
+      lastEntry->set("last",false);
+    }
   }
   entry->set("is_leaf_node",true);
   entry->set("first",list->count()==0);
index e4916cd..7fcd5ed 100644 (file)
 
 //------------------------------------------------------------------------
 
-// selects one of the name to sub-dir mapping algorithms that is used
-// to select a sub directory when CREATE_SUBDIRS is set to YES.
-
-#define ALGO_COUNT 1
-#define ALGO_CRC16 2
-#define ALGO_MD5   3
-
-//#define MAP_ALGO ALGO_COUNT
-//#define MAP_ALGO ALGO_CRC16
-#define MAP_ALGO ALGO_MD5
-
 #define REL_PATH_TO_ROOT "../../"
 
 static const char *hex = "0123456789ABCDEF";
@@ -1081,9 +1070,9 @@ void linkifyText(const TextGeneratorIntf &out, const Definition *scope,
 }
 
 
-void writeExample(OutputList &ol,ExampleSDict *ed)
+void writeExamples(OutputList &ol,const ExampleList &list)
 {
-  QCString exampleLine=theTranslator->trWriteList(ed->count());
+  QCString exampleLine=theTranslator->trWriteList((int)list.size());
 
   //bool latexEnabled = ol.isEnabled(OutputGenerator::Latex);
   //bool manEnabled   = ol.isEnabled(OutputGenerator::Man);
@@ -1096,9 +1085,9 @@ void writeExample(OutputList &ol,ExampleSDict *ed)
     bool ok;
     ol.parseText(exampleLine.mid(index,newIndex-index));
     uint entryIndex = exampleLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
-    Example *e=ed->at(entryIndex);
-    if (ok && e)
+    if (ok && entryIndex<list.size())
     {
+      const auto &e = list[entryIndex];
       ol.pushGeneratorState();
       //if (latexEnabled) ol.disable(OutputGenerator::Latex);
       ol.disable(OutputGenerator::Latex);
@@ -1106,7 +1095,7 @@ void writeExample(OutputList &ol,ExampleSDict *ed)
       ol.disable(OutputGenerator::Docbook);
       // link for Html / man
       //printf("writeObjectLink(file=%s)\n",e->file.data());
-      ol.writeObjectLink(0,e->file,e->anchor,e->name);
+      ol.writeObjectLink(0,e.file,e.anchor,e.name);
       ol.popGeneratorState();
 
       ol.pushGeneratorState();
@@ -1115,7 +1104,7 @@ void writeExample(OutputList &ol,ExampleSDict *ed)
       ol.disable(OutputGenerator::Html);
       // link for Latex / pdf with anchor because the sources
       // are not hyperlinked (not possible with a verbatim environment).
-      ol.writeObjectLink(0,e->file,0,e->name);
+      ol.writeObjectLink(0,e.file,0,e.name);
       //if (manEnabled) ol.enable(OutputGenerator::Man);
       //if (htmlEnabled) ol.enable(OutputGenerator::Html);
       ol.popGeneratorState();
@@ -3037,7 +3026,7 @@ bool resolveRef(/* in */  const char *scName,
     //    md->name().data(),md,md->anchor().data(),md->isLinkable(),(*resContext)->name().data());
     return TRUE;
   }
-  else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupSDict->find(nameStr)))
+  else if (inSeeBlock && !nameStr.isEmpty() && (gd=Doxygen::groupLinkedMap->find(nameStr)))
   { // group link
     *resContext=gd;
     return TRUE;
@@ -3188,7 +3177,7 @@ bool resolveLink(/* in */ const char *scName,
   {
     return FALSE;
   }
-  else if ((pd=Doxygen::pageSDict->find(linkRef))) // link to a page
+  else if ((pd=Doxygen::pageLinkedMap->find(linkRef))) // link to a page
   {
     gd = pd->getGroupDef();
     if (gd)
@@ -3209,12 +3198,12 @@ bool resolveLink(/* in */ const char *scName,
     resAnchor = si->label();
     return TRUE;
   }
-  else if ((pd=Doxygen::exampleSDict->find(linkRef))) // link to an example
+  else if ((pd=Doxygen::exampleLinkedMap->find(linkRef))) // link to an example
   {
     *resContext=pd;
     return TRUE;
   }
-  else if ((gd=Doxygen::groupSDict->find(linkRef))) // link to a group
+  else if ((gd=Doxygen::groupLinkedMap->find(linkRef))) // link to a group
   {
     *resContext=gd;
     return TRUE;
@@ -3254,7 +3243,7 @@ bool resolveLink(/* in */ const char *scName,
     *resContext=nd;
     return TRUE;
   }
-  else if ((dir=Doxygen::directories->find(QFileInfo(linkRef).absFilePath().utf8()+"/"))
+  else if ((dir=Doxygen::dirLinkedMap->find(QFileInfo(linkRef).absFilePath().utf8()+"/"))
       && dir->isLinkable()) // TODO: make this location independent like filedefs
   {
     *resContext=dir;
@@ -3564,10 +3553,10 @@ bool hasVisibleRoot(const BaseClassList &bcl)
   for (const auto &bcd : bcl)
   {
     const ClassDef *cd=bcd.classDef;
-    if (cd->isVisibleInHierarchy()) return TRUE;
-    hasVisibleRoot(cd->baseClasses());
+    if (cd->isVisibleInHierarchy()) return true;
+    if (hasVisibleRoot(cd->baseClasses())) return true;
   }
-  return FALSE;
+  return false;
 }
 
 //----------------------------------------------------------------------
@@ -3834,40 +3823,12 @@ QCString convertNameToFile(const char *name,bool allowDots,bool allowUnderscore)
   {
     int l1Dir=0,l2Dir=0;
 
-#if MAP_ALGO==ALGO_COUNT
-    // old algorithm, has the problem that after regeneration the
-    // output can be located in a different dir.
-    if (Doxygen::htmlDirMap==0)
-    {
-      Doxygen::htmlDirMap=new QDict<int>(100003);
-      Doxygen::htmlDirMap->setAutoDelete(TRUE);
-    }
-    static int curDirNum=0;
-    int *dirNum = Doxygen::htmlDirMap->find(result);
-    if (dirNum==0) // new name
-    {
-      Doxygen::htmlDirMap->insert(result,new int(curDirNum));
-      l1Dir = (curDirNum)&0xf;    // bits 0-3
-      l2Dir = (curDirNum>>4)&0xff; // bits 4-11
-      curDirNum++;
-    }
-    else // existing name
-    {
-      l1Dir = (*dirNum)&0xf;       // bits 0-3
-      l2Dir = ((*dirNum)>>4)&0xff; // bits 4-11
-    }
-#elif MAP_ALGO==ALGO_CRC16
-    // second algorithm based on CRC-16 checksum
-    int dirNum = qChecksum(result,result.length());
-    l1Dir = dirNum&0xf;
-    l2Dir = (dirNum>>4)&0xff;
-#elif MAP_ALGO==ALGO_MD5
-    // third algorithm based on MD5 hash
+    // compute md5 hash to determine sub directory to use
     uchar md5_sig[16];
     MD5Buffer((const unsigned char *)result.data(),result.length(),md5_sig);
     l1Dir = md5_sig[14]&0xf;
     l2Dir = md5_sig[15];
-#endif
+
     result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
   }
   //printf("*** convertNameToFile(%s)->%s\n",name,result.data());
@@ -4412,7 +4373,7 @@ QCString getOverloadDocs()
 }
 
 void addMembersToMemberGroup(MemberList *ml,
-    MemberGroupSDict **ppMemberGroupSDict,
+    MemberGroupList *pMemberGroups,
     const Definition *context)
 {
   ASSERT(context!=0);
@@ -4435,31 +4396,34 @@ void addMembersToMemberGroup(MemberList *ml,
           int groupId=fmd->getMemberGroupId();
           if (groupId!=-1)
           {
-            MemberGroupInfo *info = Doxygen::memGrpInfoDict[groupId];
-            //QCString *pGrpHeader = Doxygen::memberHeaderDict[groupId];
-            //QCString *pDocs      = Doxygen::memberDocDict[groupId];
-            if (info)
+            auto it = Doxygen::memberGroupInfoMap.find(groupId);
+            if (it!=Doxygen::memberGroupInfoMap.end())
             {
-              if (*ppMemberGroupSDict==0)
+              auto &info = it->second;
+              auto mg_it = std::find_if(pMemberGroups->begin(),
+                                        pMemberGroups->end(),
+                                        [&groupId](const auto &g)
+                                        { return g->groupId()==groupId; }
+                                       );
+              MemberGroup *mg_ptr = 0;
+              if (mg_it==pMemberGroups->end())
               {
-                *ppMemberGroupSDict = new MemberGroupSDict;
-                (*ppMemberGroupSDict)->setAutoDelete(TRUE);
+                auto mg = std::make_unique<MemberGroup>(
+                          context,
+                          groupId,
+                          info->header,
+                          info->doc,
+                          info->docFile,
+                          info->docLine);
+                mg_ptr = mg.get();
+                pMemberGroups->push_back(std::move(mg));
               }
-              MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
-              if (mg==0)
+              else
               {
-                mg = new MemberGroup(
-                    context,
-                    groupId,
-                    info->header,
-                    info->doc,
-                    info->docFile,
-                    info->docLine
-                    );
-                (*ppMemberGroupSDict)->append(groupId,mg);
+                mg_ptr = (*mg_it).get();
               }
-              mg->insertMember(fmd); // insert in member group
-              fmd->setMemberGroup(mg);
+              mg_ptr->insertMember(fmd); // insert in member group
+              fmd->setMemberGroup(mg_ptr);
             }
           }
         }
@@ -4468,33 +4432,36 @@ void addMembersToMemberGroup(MemberList *ml,
     int groupId=md->getMemberGroupId();
     if (groupId!=-1)
     {
-      MemberGroupInfo *info = Doxygen::memGrpInfoDict[groupId];
-      //QCString *pGrpHeader = Doxygen::memberHeaderDict[groupId];
-      //QCString *pDocs      = Doxygen::memberDocDict[groupId];
-      if (info)
-      {
-        if (*ppMemberGroupSDict==0)
+      auto it = Doxygen::memberGroupInfoMap.find(groupId);
+      if (it!=Doxygen::memberGroupInfoMap.end())
+      {
+        auto &info = it->second;
+        auto mg_it = std::find_if(pMemberGroups->begin(),
+                                  pMemberGroups->end(),
+                                  [&groupId](const auto &g)
+                                  { return g->groupId()==groupId; }
+                                 );
+        MemberGroup *mg_ptr = 0;
+        if (mg_it==pMemberGroups->end())
         {
-          *ppMemberGroupSDict = new MemberGroupSDict;
-          (*ppMemberGroupSDict)->setAutoDelete(TRUE);
+          auto mg = std::make_unique<MemberGroup>(
+                    context,
+                    groupId,
+                    info->header,
+                    info->doc,
+                    info->docFile,
+                    info->docLine);
+          mg_ptr = mg.get();
+          pMemberGroups->push_back(std::move(mg));
         }
-        MemberGroup *mg = (*ppMemberGroupSDict)->find(groupId);
-        if (mg==0)
+        else
         {
-          mg = new MemberGroup(
-              context,
-              groupId,
-              info->header,
-              info->doc,
-              info->docFile,
-              info->docLine
-              );
-          (*ppMemberGroupSDict)->append(groupId,mg);
+          mg_ptr = (*mg_it).get();
         }
         md = ml->take(index); // remove from member list
-        mg->insertMember(md->resolveAlias()); // insert in member group
-        mg->setRefItems(info->m_sli);
-        md->setMemberGroup(mg);
+        mg_ptr->insertMember(md->resolveAlias()); // insert in member group
+        mg_ptr->setRefItems(info->m_sli);
+        md->setMemberGroup(mg_ptr);
         continue;
       }
     }
@@ -4920,7 +4887,7 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle,
   PageDef *pd=0;
   //printf("addRelatedPage(name=%s gd=%p)\n",name,gd);
   QCString title=ptitle.stripWhiteSpace();
-  if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo)
+  if ((pd=Doxygen::pageLinkedMap->find(name)) && !tagInfo)
   {
     if (!xref && !title.isEmpty() && pd->title()!=title)
     {
@@ -4941,7 +4908,10 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle,
     else if (baseName.right(Doxygen::htmlFileExtension.length())==Doxygen::htmlFileExtension)
       baseName=baseName.left(baseName.length()-Doxygen::htmlFileExtension.length());
 
-    pd=createPageDef(fileName,docLine,baseName,doc,title);
+    //printf("Appending page '%s'\n",baseName.data());
+    pd = Doxygen::pageLinkedMap->add(baseName,
+        std::unique_ptr<PageDef>(
+           createPageDef(fileName,docLine,baseName,doc,title)));
     pd->setBodySegment(startLine,startLine,-1);
 
     pd->setRefItems(sli);
@@ -4953,8 +4923,6 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle,
       pd->setFileName(tagInfo->fileName);
     }
 
-    //printf("Appending page '%s'\n",baseName.data());
-    Doxygen::pageSDict->append(baseName,pd);
 
     if (gd) gd->addPage(pd);
 
@@ -5027,8 +4995,7 @@ void addRefItem(const RefItemVector &sli,
 
 bool recursivelyAddGroupListToTitle(OutputList &ol,const Definition *d,bool root)
 {
-  GroupList *groups = d->partOfGroups();
-  if (groups) // write list of group to which this definition belongs
+  if (!d->partOfGroups().empty()) // write list of group to which this definition belongs
   {
     if (root)
     {
@@ -5036,10 +5003,8 @@ bool recursivelyAddGroupListToTitle(OutputList &ol,const Definition *d,bool root
       ol.disableAllBut(OutputGenerator::Html);
       ol.writeString("<div class=\"ingroups\">");
     }
-    GroupListIterator gli(*groups);
-    GroupDef *gd;
     bool first=true;
-    for (gli.toFirst();(gd=gli.current());++gli)
+    for (const auto &gd : d->partOfGroups())
     {
       if (!first) { ol.writeString(" &#124; "); } else first=false;
       if (recursivelyAddGroupListToTitle(ol, gd, FALSE))
index 38e8b2e..b19e1c5 100644 (file)
@@ -50,8 +50,6 @@ class MemberDef;
 class ExampleSDict;
 class GroupDef;
 class NamespaceSDict;
-class ClassList;
-class MemberGroupSDict;
 struct TagInfo;
 class PageDef;
 class SectionInfo;
@@ -94,32 +92,6 @@ class TextGeneratorOLImpl : public TextGeneratorIntf
 
 //--------------------------------------------------------------------
 
-/** @brief maps a unicode character code to a list of T::ElementType's
- */
-template<class T>
-class LetterToIndexMap : public SIntDict<T>
-{
-  public:
-    LetterToIndexMap() { SIntDict<T>::setAutoDelete(TRUE); }
-    void append(uint letter,typename T::ElementType *elem)
-    {
-      T *l = SIntDict<T>::find((int)letter);
-      if (l==0)
-      {
-        l = new T(letter);
-        SIntDict<T>::inSort((int)letter,l);
-      }
-      l->append(elem);
-    }
-  private:
-    int compareValues(const T *l1, const T *l2) const
-    {
-      return (int)l1->letter()-(int)l2->letter();
-    }
-};
-
-//--------------------------------------------------------------------
-
 QCString langToString(SrcLangExt lang);
 QCString getLanguageSpecificSeparator(SrcLangExt lang,bool classScope=FALSE);
 
@@ -233,7 +205,7 @@ QCString tempArgListToString(const ArgumentList &al,SrcLangExt lang,bool include
 
 QCString generateMarker(int id);
 
-void writeExample(OutputList &ol,ExampleSDict *el);
+void writeExamples(OutputList &ol,const ExampleList &el);
 
 QCString stripAnonymousNamespaceScope(const QCString &s);
 
@@ -291,7 +263,7 @@ QCString convertToPSString(const char *s);
 QCString getOverloadDocs();
 
 void addMembersToMemberGroup(/* in,out */ MemberList *ml,
-                             /* in,out */ MemberGroupSDict **ppMemberGroupSDict,
+                             /* in,out */ MemberGroupList *pMemberGroups,
                              /* in */     const Definition *context);
 
 int extractClassNameFromType(const QCString &type,int &pos,
index efb367b..0f52356 100644 (file)
@@ -1014,7 +1014,7 @@ static void startCodeLine(yyscan_t yyscanner)
     //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
     //  if ((yyextra->yyLineNr % 500) == 0)
     //         fprintf(stderr,"\n starting Line %d:",yyextra->yyLineNr);
-    Definition *d   = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
+    const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
     //printf("startCodeLine %d d=%s\n", yyextra->yyLineNr,d ? d->name().data() : "<null>");
     if (!yyextra->includeCodeFragment && d)
     {
@@ -1268,7 +1268,7 @@ static void generateFuncLink(yyscan_t yyscanner,CodeOutputInterface &ol,MemberDe
   //printf("generateFuncLink(FuncName=%s)\n",mdef->name().data());
   QCString memberName=mdef->name();
 
-  if (mdef && mdef->isLinkable()) // is it a linkable class
+  if (mdef->isLinkable()) // is it a linkable class
   {
     writeMultiLineCodeLink(yyscanner,ol,mdef,mdef->name());
     addToSearchIndex(yyscanner,memberName);
index dd208aa..7afc832 100644 (file)
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
+#include <map>
 #include <qcstring.h>
 #include <qfileinfo.h>
 #include <qcstringlist.h>
-#include <qmap.h>
 
 /* --------------------------------------------------------------- */
 
@@ -642,9 +642,9 @@ ClassDef* VhdlDocGen::getPackageName(const QCString & name)
   return getClass(name);
 }
 
-static QMap<QCString,MemberDef*> varMap;
-static QList<ClassDef> qli;
-static QMap<ClassDef*,QList<ClassDef> > packages;
+static std::map<std::string,MemberDef*>            g_varMap;
+static std::vector<ClassDef*>                      g_classList;
+static std::map<ClassDef*,std::vector<ClassDef*> > g_packages;
 
 MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& memName)
 {
@@ -712,7 +712,7 @@ MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& mem
     }
     if (acd) //d && d->definitionType()==Definition::TypeClass)
     {
-      if(!packages.contains(acd))
+      if(g_packages.find(acd)==g_packages.end())
       {
         VhdlDocGen::findAllPackages(acd);
       }
@@ -721,20 +721,19 @@ MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& mem
   else
   {
     ecd=cd;
-    if (!packages.contains(ecd)) VhdlDocGen::findAllPackages(ecd);
+    if (g_packages.find(ecd)==g_packages.end()) VhdlDocGen::findAllPackages(ecd);
   }
 
   if (ecd)
   {
-    QMap<ClassDef*,QList<ClassDef> >::Iterator cList=packages.find(ecd);
-    if (cList!=packages.end())
+    auto cList_it = g_packages.find(ecd);
+    if (cList_it!=g_packages.end())
     {
-      QList<ClassDef> mlist=cList.data();
-      for (uint j=0;j<mlist.count();j++)
+      for (const auto &cdp : cList_it->second)
       {
-        mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_variableMembers);
+        mdef=VhdlDocGen::findMemberDef(cdp,memName,MemberListType_variableMembers);
         if (mdef) return mdef;
-        mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_pubMethods);
+        mdef=VhdlDocGen::findMemberDef(cdp,memName,MemberListType_pubMethods);
         if (mdef) return mdef;
       }
     }
@@ -754,21 +753,21 @@ MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberList
   QCString keyType=cd->symbolName()+"@"+key;
   //printf("\n %s | %s | %s",cd->symbolName().data(),key.data(,),keyType.data());
 
-  QMap<QCString, MemberDef*>::Iterator it =varMap.find(keyType);
-  if (it.key())
+  auto it = g_varMap.find(keyType.str());
+  if (it!=g_varMap.end())
   {
-    md=it.data();
+    md=it->second;
     if (md)
     {
       return md;
     }
   }
-  if (qli.contains(cd))
+  if (std::find(g_classList.begin(),g_classList.end(),cd)!=g_classList.end())
   {
     return 0;
   }
   ml=cd->getMemberList(type);
-  qli.append(cd);
+  g_classList.push_back(cd);
   if (!ml)
   {
     return 0;
@@ -780,16 +779,15 @@ MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberList
   for (fmni.toFirst();(md=fmni.current());++fmni)
   {
     QCString tkey=cd->symbolName()+"@"+md->name();
-    if (varMap.contains(tkey))
+    if (g_varMap.find(tkey.str())==g_varMap.end())
     {
-      continue;
+      g_varMap.insert({tkey.str(),md});
     }
-    varMap.insert(tkey.data(),md);
   }
-  it=varMap.find(keyType.data());
-  if (it.key())
+  it=g_varMap.find(keyType.str());
+  if (it!=g_varMap.end())
   {
-    md=it.data();
+    md=it->second;
     if (md)
     {
       return md;
@@ -804,8 +802,8 @@ MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberList
 
 void VhdlDocGen::findAllPackages( ClassDef *cdef)
 {
-  QList<ClassDef> cList;
-  if (packages.contains(cdef)) return;
+  if (g_packages.find(cdef)!=g_packages.end()) return;
+  std::vector<ClassDef*> cList;
   MemberList *mem=cdef->getMemberList(MemberListType_variableMembers);
   MemberDef *md;
 
@@ -819,9 +817,9 @@ void VhdlDocGen::findAllPackages( ClassDef *cdef)
       ClassDef* cd=VhdlDocGen::getPackageName(md->name());
       if (cd)
       {
-        cList.append(cd);
+        cList.push_back(cd);
         VhdlDocGen::findAllPackages(cd);
-        packages.insert(cdef,cList);
+        g_packages.insert({cdef,cList});
       }
     }
   }//for
@@ -2125,8 +2123,7 @@ void VhdlDocGen::writePlainVHDLDeclarations(
     const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,int specifier)
 {
 
-  SDict<QCString> pack(1009);
-  pack.setAutoDelete(TRUE);
+  StringSet pack;
 
   bool first=TRUE;
   MemberDef *imd;
@@ -2144,17 +2141,16 @@ void VhdlDocGen::writePlainVHDLDeclarations(
       } //if
       else if (md->isBriefSectionVisible() && (mems==specifier))
       {
-        if (!pack.find(md->name().data()))
+        if (pack.find(md->name().str())==pack.end())
         {
           if (first) ol.startMemberList(),first=FALSE;
           VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
-          pack.append(md->name().data(),new QCString(md->name().data()));
+          pack.insert(md->name().str());
         }
       } //if
     } //if
   } //for
   if (!first) ol.endMemberList();
-  pack.clear();
 }//plainDeclaration
 
 static bool membersHaveSpecificType(const MemberList *ml,uint64 type)
@@ -2169,17 +2165,11 @@ static bool membersHaveSpecificType(const MemberList *ml,uint64 type)
       return TRUE;
     }
   }
-  if (ml->getMemberGroupList())
+  for (const auto &mg : ml->getMemberGroupList())
   {
-    MemberGroupListIterator mgli(*ml->getMemberGroupList());
-    MemberGroup *mg;
-    while ((mg=mgli.current()))
+    if (mg->members())
     {
-      if (mg->members())
-      {
-        if (membersHaveSpecificType(mg->members(),type)) return TRUE;
-      }
-      ++mgli;
+      if (membersHaveSpecificType(mg->members(),type)) return TRUE;
     }
   }
   return FALSE;
@@ -2208,36 +2198,30 @@ void VhdlDocGen::writeVHDLDeclarations(const MemberList* ml,OutputList &ol,
 
   VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,type);
 
-  if (ml->getMemberGroupList())
+  for (const auto &mg : ml->getMemberGroupList())
   {
-    MemberGroupListIterator mgli(*ml->getMemberGroupList());
-    MemberGroup *mg;
-    while ((mg=mgli.current()))
+    if (membersHaveSpecificType(mg->members(),type))
     {
-      if (membersHaveSpecificType(mg->members(),type))
+      //printf("mg->header=%s\n",mg->header().data());
+      bool hasHeader=mg->header()!="[NOHEADER]";
+      ol.startMemberGroupHeader(hasHeader);
+      if (hasHeader)
       {
-        //printf("mg->header=%s\n",mg->header().data());
-        bool hasHeader=mg->header()!="[NOHEADER]";
-        ol.startMemberGroupHeader(hasHeader);
-        if (hasHeader)
-        {
-          ol.parseText(mg->header());
-        }
-        ol.endMemberGroupHeader();
-        if (!mg->documentation().isEmpty())
-        {
-          //printf("Member group has docs!\n");
-          ol.startMemberGroupDocs();
-          ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE,
-                         0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
-          ol.endMemberGroupDocs();
-        }
-        ol.startMemberGroup();
-        //printf("--- mg->writePlainDeclarations ---\n");
-        VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
-        ol.endMemberGroup(hasHeader);
+        ol.parseText(mg->header());
+      }
+      ol.endMemberGroupHeader();
+      if (!mg->documentation().isEmpty())
+      {
+        //printf("Member group has docs!\n");
+        ol.startMemberGroupDocs();
+        ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE,
+            0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
+        ol.endMemberGroupDocs();
       }
-      ++mgli;
+      ol.startMemberGroup();
+      //printf("--- mg->writePlainDeclarations ---\n");
+      VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
+      ol.endMemberGroup(hasHeader);
     }
   }
 }// writeVHDLDeclarations
@@ -2871,9 +2855,9 @@ void VhdlDocGen::createFlowChart(const MemberDef *mdef)
 
 void VhdlDocGen::resetCodeVhdlParserState()
 {
-  varMap.clear();
-  qli.clear();
-  packages.clear();
+  g_varMap.clear();
+  g_classList.clear();
+  g_packages.clear();
 }
 
 bool VhdlDocGen::isConstraint(const MemberDef *mdef)
@@ -2984,7 +2968,7 @@ static struct
 QList<FlowChart>  FlowChart::flowList;
 
 #ifdef DEBUGFLOW
-static QMap<QCString,int> keyMap;
+static std::map<std::string,int> g_keyMap;
 #endif
 
 void alignText(QCString & q)
@@ -3606,7 +3590,7 @@ void FlowChart::writeShape(FTextStream &t,const FlowChart* fl)
 
 #ifdef DEBUGFLOW
   QCString qq(getNodeName(fl->id).data());
-  keyMap.insert(qq,fl->id);
+  g_keyMap.insert({qq.str(),fl->id});
 #endif
 
   bool dec=(fl->type & DECLN);
@@ -3695,11 +3679,11 @@ void FlowChart::writeEdge(FTextStream &t,const FlowChart* fl_from,const FlowChar
 #ifdef DEBUGFLOW
   QCString s1(getNodeName(fl_from->id).data());
   QCString s2(getNodeName(fl_to->id).data());
-  QMap<QCString, int>::Iterator it = keyMap.find(s1);
-  QMap<QCString, int>::Iterator it1 = keyMap.find(s2);
+  auto it = g_keyMap.find(s1.str());
+  auto it1 = g_keyMap.find(s2.str());
   // checks if the link is connected to a valid node
-  assert(it.key());
-  assert(it1.key());
+  assert(it!=g_keyMap.end());
+  assert(it1!=g_keyMap.end());
 #endif
 
   writeEdge(t,fl_from->id,fl_to->id,i,b,c);
index c7322cb..41f5504 100644 (file)
@@ -239,7 +239,7 @@ static void startCodeLine(yyscan_t yyscanner)
   struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
   if (yyextra->sourceFileDef)
   {
-    Definition *d   = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
+    const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
 
     if (!yyextra->includeCodeFragment && d && d->isLinkableInProject())
     {
index 73aac7c..29990c9 100644 (file)
@@ -41,7 +41,7 @@ static void visitCaption(XmlDocVisitor *parent, QList<DocNode> children)
 static void visitPreStart(FTextStream &t, const char *cmd, bool doCaption,
                           XmlDocVisitor *parent, QList<DocNode> children,
                           const QCString &name, bool writeType, DocImage::Type type, const QCString &width,
-                          const QCString &height, bool inlineImage = FALSE)
+                          const QCString &height, const QCString &alt = QCString(""), bool inlineImage = FALSE)
 {
   t << "<" << cmd;
   if (writeType)
@@ -68,6 +68,10 @@ static void visitPreStart(FTextStream &t, const char *cmd, bool doCaption,
   {
     t << " height=\"" << convertToXML(height) << "\"";
   }
+  if (!alt.isEmpty())
+  {
+    t << " alt=\"" << convertToXML(alt) << "\"";
+  }
   if (inlineImage)
   {
     t << " inline=\"yes\"";
@@ -774,7 +778,17 @@ void XmlDocVisitor::visitPre(DocHtmlTable *t)
 {
   if (m_hide) return;
   m_t << "<table rows=\"" << t->numRows()
-      << "\" cols=\"" << t->numColumns() << "\">" ;
+      << "\" cols=\"" << t->numColumns() << "\"" ;
+  HtmlAttribListIterator li(t->attribs());
+  HtmlAttrib* opt;
+  for (li.toFirst(); (opt = li.current()); ++li)
+  {
+    if (opt->name=="width")
+    {
+      m_t << " " << opt->name << "=\"" << opt->value << "\"";
+    }
+  }
+  m_t << ">";
 }
 
 void XmlDocVisitor::visitPost(DocHtmlTable *)
@@ -812,6 +826,15 @@ void XmlDocVisitor::visitPre(DocHtmlCell *c)
     {
       m_t << " align=\"" << opt->value << "\"";
     }
+    else if (opt->name=="valign" &&
+      (opt->value == "bottom" || opt->value == "top" || opt->value == "middle"))
+    {
+      m_t << " valign=\"" << opt->value << "\"";
+    }
+    else if (opt->name=="width")
+    {
+      m_t << " width=\"" << opt->value << "\"";
+    }
     else if (opt->name=="class") // handle markdown generated attributes
     {
       if (opt->value.left(13)=="markdownTable") // handle markdown generated attributes
@@ -907,7 +930,7 @@ void XmlDocVisitor::visitPre(DocImage *img)
   {
     baseName = correctURL(url,img->relPath());
   }
-  visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height(), img ->isInlineImage());
+  visitPreStart(m_t, "image", FALSE, this, img->children(), baseName, TRUE, img->type(), img->width(), img->height(), img->attribs().find("alt"), img->isInlineImage());
 
   // copy the image to the output dir
   FileDef *fd;
index 8ffaca2..70fcd70 100644 (file)
@@ -1054,7 +1054,7 @@ static bool memberVisible(const Definition *d,const MemberDef *md)
 }
 
 static void generateXMLSection(const Definition *d,FTextStream &ti,FTextStream &t,
-                      MemberList *ml,const char *kind,const char *header=0,
+                      const MemberList *ml,const char *kind,const char *header=0,
                       const char *documentation=0)
 {
   if (ml==0) return;
@@ -1180,36 +1180,26 @@ static void writeInnerFiles(const FileList *fl,FTextStream &t)
   }
 }
 
-static void writeInnerPages(const PageSDict *pl,FTextStream &t)
+static void writeInnerPages(const PageLinkedRefMap &pl,FTextStream &t)
 {
-  if (pl)
+  for (const auto &pd : pl)
   {
-    PageSDict::Iterator pli(*pl);
-    PageDef *pd;
-    for (pli.toFirst();(pd=pli.current());++pli)
+    t << "    <innerpage refid=\"" << pd->getOutputFileBase();
+    if (pd->getGroupDef())
     {
-      t << "    <innerpage refid=\"" << pd->getOutputFileBase();
-      if (pd->getGroupDef())
-      {
-        t << "_" << pd->name();
-      }
-      t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
+      t << "_" << pd->name();
     }
+    t << "\">" << convertToXML(pd->title()) << "</innerpage>" << endl;
   }
 }
 
-static void writeInnerGroups(const GroupList *gl,FTextStream &t)
+static void writeInnerGroups(const GroupList &gl,FTextStream &t)
 {
-  if (gl)
+  for (const auto &sgd : gl)
   {
-    GroupListIterator gli(*gl);
-    const GroupDef *sgd;
-    for (gli.toFirst();(sgd=gli.current());++gli)
-    {
-      t << "    <innergroup refid=\"" << sgd->getOutputFileBase()
-        << "\">" << convertToXML(sgd->groupTitle())
-        << "</innergroup>" << endl;
-    }
+    t << "    <innergroup refid=\"" << sgd->getOutputFileBase()
+      << "\">" << convertToXML(sgd->groupTitle())
+      << "</innergroup>" << endl;
   }
 }
 
@@ -1365,24 +1355,17 @@ static void generateXMLForClass(const ClassDef *cd,FTextStream &ti)
   writeInnerClasses(cd->getClasses(),t);
 
   writeTemplateList(cd,t);
-  if (cd->getMemberGroupSDict())
+  for (const auto &mg : cd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
-          mg->documentation());
-    }
+    generateXMLSection(cd,ti,t,mg->members(),"user-defined",mg->header(),
+        mg->documentation());
   }
 
-  QListIterator<MemberList> mli(cd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : cd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_detailedLists)==0)
     {
-      generateXMLSection(cd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+      generateXMLSection(cd,ti,t,ml.get(),g_xmlSectionMapper.find(ml->listType()));
     }
   }
 
@@ -1469,24 +1452,17 @@ static void generateXMLForNamespace(const NamespaceDef *nd,FTextStream &ti)
   writeInnerClasses(nd->getClasses(),t);
   writeInnerNamespaces(nd->getNamespaces(),t);
 
-  if (nd->getMemberGroupSDict())
+  for (const auto &mg : nd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
+    generateXMLSection(nd,ti,t,mg->members(),"user-defined",mg->header(),
           mg->documentation());
-    }
   }
 
-  QListIterator<MemberList> mli(nd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : nd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_declarationLists)!=0)
     {
-      generateXMLSection(nd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+      generateXMLSection(nd,ti,t,ml.get(),g_xmlSectionMapper.find(ml->listType()));
     }
   }
 
@@ -1600,24 +1576,17 @@ static void generateXMLForFile(FileDef *fd,FTextStream &ti)
   writeInnerClasses(fd->getClasses(),t);
   writeInnerNamespaces(fd->getNamespaces(),t);
 
-  if (fd->getMemberGroupSDict())
+  for (const auto &mg : fd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
-          mg->documentation());
-    }
+    generateXMLSection(fd,ti,t,mg->members(),"user-defined",mg->header(),
+        mg->documentation());
   }
 
-  QListIterator<MemberList> mli(fd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : fd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_declarationLists)!=0)
     {
-      generateXMLSection(fd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+      generateXMLSection(fd,ti,t,ml.get(),g_xmlSectionMapper.find(ml->listType()));
     }
   }
 
@@ -1680,24 +1649,17 @@ static void generateXMLForGroup(const GroupDef *gd,FTextStream &ti)
   writeInnerPages(gd->getPages(),t);
   writeInnerGroups(gd->getSubGroups(),t);
 
-  if (gd->getMemberGroupSDict())
+  for (const auto &mg : gd->getMemberGroups())
   {
-    MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
-    MemberGroup *mg;
-    for (;(mg=mgli.current());++mgli)
-    {
-      generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
-          mg->documentation());
-    }
+    generateXMLSection(gd,ti,t,mg->members(),"user-defined",mg->header(),
+        mg->documentation());
   }
 
-  QListIterator<MemberList> mli(gd->getMemberLists());
-  MemberList *ml;
-  for (mli.toFirst();(ml=mli.current());++mli)
+  for (const auto &ml : gd->getMemberLists())
   {
     if ((ml->listType()&MemberListType_declarationLists)!=0)
     {
-      generateXMLSection(gd,ti,t,ml,g_xmlSectionMapper.find(ml->listType()));
+      generateXMLSection(gd,ti,t,ml.get(),g_xmlSectionMapper.find(ml->listType()));
     }
   }
 
@@ -1757,6 +1719,7 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
   // + name
   // + title
   // + documentation
+  // + location
 
   const char *kindName = isExample ? "example" : "page";
 
@@ -1790,7 +1753,7 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
   t << "    <compoundname>" << convertToXML(pd->name())
     << "</compoundname>" << endl;
 
-  if (pd==Doxygen::mainPage) // main page is special
+  if (pd==Doxygen::mainPage.get()) // main page is special
   {
     QCString title;
     if (mainPageHasTitle())
@@ -1882,6 +1845,8 @@ static void generateXMLForPage(PageDef *pd,FTextStream &ti,bool isExample)
   }
   t << "    </detaileddescription>" << endl;
 
+  t << "    <location file=\"" << convertToXML(stripFromPath(pd->getDefFileName())) << "\"/>" << endl;
+
   t << "  </compounddef>" << endl;
   t << "</doxygen>" << endl;
 
@@ -1975,44 +1940,30 @@ void generateXML()
       generateXMLForFile(fd.get(),t);
     }
   }
-  GroupSDict::Iterator gli(*Doxygen::groupSDict);
-  const GroupDef *gd;
-  for (;(gd=gli.current());++gli)
+  for (const auto &gd : *Doxygen::groupLinkedMap)
   {
     msg("Generating XML output for group %s\n",gd->name().data());
-    generateXMLForGroup(gd,t);
+    generateXMLForGroup(gd.get(),t);
   }
+  for (const auto &pd : *Doxygen::pageLinkedMap)
   {
-    PageSDict::Iterator pdi(*Doxygen::pageSDict);
-    PageDef *pd=0;
-    for (pdi.toFirst();(pd=pdi.current());++pdi)
-    {
-      msg("Generating XML output for page %s\n",pd->name().data());
-      generateXMLForPage(pd,t,FALSE);
-    }
+    msg("Generating XML output for page %s\n",pd->name().data());
+    generateXMLForPage(pd.get(),t,FALSE);
   }
+  for (const auto &dd : *Doxygen::dirLinkedMap)
   {
-    DirDef *dir;
-    DirSDict::Iterator sdi(*Doxygen::directories);
-    for (sdi.toFirst();(dir=sdi.current());++sdi)
-    {
-      msg("Generate XML output for dir %s\n",dir->name().data());
-      generateXMLForDir(dir,t);
-    }
+    msg("Generate XML output for dir %s\n",dd->name().data());
+    generateXMLForDir(dd.get(),t);
   }
+  for (const auto &pd : *Doxygen::exampleLinkedMap)
   {
-    PageSDict::Iterator pdi(*Doxygen::exampleSDict);
-    PageDef *pd=0;
-    for (pdi.toFirst();(pd=pdi.current());++pdi)
-    {
-      msg("Generating XML output for example %s\n",pd->name().data());
-      generateXMLForPage(pd,t,TRUE);
-    }
+    msg("Generating XML output for example %s\n",pd->name().data());
+    generateXMLForPage(pd.get(),t,TRUE);
   }
   if (Doxygen::mainPage)
   {
     msg("Generating XML output for the main page\n");
-    generateXMLForPage(Doxygen::mainPage,t,FALSE);
+    generateXMLForPage(Doxygen::mainPage.get(),t,FALSE);
   }
 
   //t << "  </compoundlist>" << endl;
index 254b5e7..830a23b 100644 (file)
@@ -204,12 +204,14 @@ a.SRScope:focus, a.SRScope:active {
 
 span.SRScope {
     padding-left: 4px;
+    font-family: Arial, Verdana, sans-serif;
 }
 
 .SRPage .SRStatus {
     padding: 2px 5px;
     font-size: 8pt;
     font-style: italic;
+    font-family: Arial, Verdana, sans-serif;
 }
 
 .SRResult {
index 974a43c..400bea5 100644 (file)
     </xsd:sequence>
     <xsd:attribute name="rows" type="xsd:integer" />
     <xsd:attribute name="cols" type="xsd:integer" />
+    <xsd:attribute name="width" type="xsd:string" />
   </xsd:complexType>
 
   <xsd:complexType name="docRowType">
     <xsd:attribute name="colspan" type="xsd:integer" />
     <xsd:attribute name="rowspan" type="xsd:integer" />
     <xsd:attribute name="align" type="DoxAlign" />
+    <xsd:attribute name="valign" type="DoxVerticalAlign" />
+    <xsd:attribute name="width" type="xsd:string" />
     <xsd:attribute name="class" type="xsd:string" />
     <xsd:anyAttribute processContents="skip"/>
   </xsd:complexType>
     <xsd:attribute name="name" type="xsd:string" use="optional"/>
     <xsd:attribute name="width" type="xsd:string" use="optional"/>
     <xsd:attribute name="height" type="xsd:string" use="optional"/>
+    <xsd:attribute name="alt" type="xsd:string" use="optional"/>
     <xsd:attribute name="inline" type="DoxBool" use="optional"/>
     <xsd:attribute name="caption" type="xsd:string" use="optional"/>
   </xsd:complexType>
     </xsd:restriction>
   </xsd:simpleType>
 
+  <xsd:simpleType name="DoxVerticalAlign">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="bottom"/>
+      <xsd:enumeration value="top"/>
+      <xsd:enumeration value="middle"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+
 </xsd:schema>
 
index df18edd..7c4a448 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>Text <emphasis>argument</emphasis> more text. </para>
     </detaileddescription>
+    <location file="001_a.dox"/>
   </compounddef>
 </doxygen>
index c74349b..bde0d33 100644 (file)
@@ -13,5 +13,6 @@
         </indexentry>
       </para>
     </detaileddescription>
+    <location file="002_addindex.dox"/>
   </compounddef>
 </doxygen>
index b1caea6..23c1867 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para><ref refid="index_1myanchor" kindref="member">See Anchor</ref> Some text. <anchor id="index_1myanchor"/>More text. </para>
     </detaileddescription>
+    <location file="003_anchor.dox"/>
   </compounddef>
 </doxygen>
index 9ab6ae4..5585cf7 100644 (file)
@@ -11,5 +11,6 @@ No other types of alignment are supported.</para>
       <para><itemizedlist><listitem><para><computeroutput>AlignLeft</computeroutput> left alignment. </para></listitem><listitem><para><computeroutput>AlignCenter</computeroutput> center alignment. </para></listitem><listitem><para><computeroutput>AlignRight</computeroutput> right alignment</para></listitem></itemizedlist>
 No other types of alignment are supported. </para>
     </detaileddescription>
+    <location file="004_arg.dox"/>
   </compounddef>
 </doxygen>
index 5a3d36a..8268925 100644 (file)
@@ -33,5 +33,6 @@
         </simplesect>
       </para>
     </detaileddescription>
+    <location file="005_attention.dox"/>
   </compounddef>
 </doxygen>
index b3c66ef..fe2086d 100644 (file)
@@ -24,5 +24,6 @@
         </simplesect>
       </para>
     </detaileddescription>
+    <location file="006_author.dox"/>
   </compounddef>
 </doxygen>
index 62f3636..c332c4d 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>Text <bold>bold</bold> normal text. </para>
     </detaileddescription>
+    <location file="007_b.dox"/>
   </compounddef>
 </doxygen>
index ebafb9a..e7aff1d 100644 (file)
@@ -23,5 +23,6 @@
         </variablelist>
       </para>
     </detaileddescription>
+    <location file="bug"/>
   </compounddef>
 </doxygen>
index e25331d..32438e4 100644 (file)
@@ -23,5 +23,6 @@
         </variablelist>
       </para>
     </detaileddescription>
+    <location file="deprecated"/>
   </compounddef>
 </doxygen>
index ccdedf1..fe05e27 100644 (file)
@@ -23,5 +23,6 @@
         </variablelist>
       </para>
     </detaileddescription>
+    <location file="reminders"/>
   </compounddef>
 </doxygen>
index 04d615c..c3a8b83 100644 (file)
@@ -23,5 +23,6 @@
         </variablelist>
       </para>
     </detaileddescription>
+    <location file="test"/>
   </compounddef>
 </doxygen>
index 7cdaea6..892c616 100644 (file)
@@ -23,5 +23,6 @@
         </variablelist>
       </para>
     </detaileddescription>
+    <location file="todo"/>
   </compounddef>
 </doxygen>
index 6deac96..35dd4f0 100644 (file)
@@ -9,5 +9,6 @@
       <para>Text <computeroutput>code</computeroutput> normal text.</para>
       <para>Text <computeroutput>code</computeroutput> normal text. </para>
     </detaileddescription>
+    <location file="010_c.dox"/>
   </compounddef>
 </doxygen>
index f5addb1..c409ae1 100644 (file)
@@ -39,5 +39,6 @@
         </variablelist>
       </para>
     </detaileddescription>
+    <location file="citelist"/>
   </compounddef>
 </doxygen>
index 26e588c..493d138 100644 (file)
@@ -9,5 +9,6 @@
       <para>See <ref refid="citelist_1CITEREF_knuth79" kindref="member">[3]</ref> for more info.</para>
       <para>Other references with cross references see <ref refid="citelist_1CITEREF_Be09" kindref="member">[1]</ref> and <ref refid="citelist_1CITEREF_BertholdHeinzVigerske2009" kindref="member">[2]</ref> for more info. </para>
     </detaileddescription>
+    <location file="012_cite.dox"/>
   </compounddef>
 </doxygen>
index 0d60a80..3f9510c 100644 (file)
@@ -47,5 +47,6 @@
         </programlisting>
       </para>
     </detaileddescription>
+    <location file="014_code.dox"/>
   </compounddef>
 </doxygen>
index c6739e9..884091e 100644 (file)
@@ -15,5 +15,6 @@
         </simplesect>
       </para>
     </detaileddescription>
+    <location file="017_copyright.dox"/>
   </compounddef>
 </doxygen>
index 863a088..f31986b 100644 (file)
@@ -22,5 +22,6 @@ XML
 DocBook
 </docbookonly> More text. </para>
     </detaileddescription>
+    <location file="020_only.dox"/>
   </compounddef>
 </doxygen>
index 477f206..473482a 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para> Our main function starts like this: <programlisting filename="example_test.cpp"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline></programlisting> First we create a object <computeroutput>t</computeroutput> of the <ref refid="class_test" kindref="compound">Test</ref> class. <programlisting filename="example_test.cpp"><codeline><highlight class="normal"><sp/><sp/><ref refid="class_test" kindref="compound">Test</ref><sp/>t;</highlight></codeline></programlisting> Then we call the example member function <programlisting filename="example_test.cpp"><codeline><highlight class="normal"><sp/><sp/>t.<ref refid="class_test_1a47b775f65718978f1ffcd96376f8ecfa" kindref="member">example</ref>();</highlight></codeline></programlisting> After that our little test routine ends. <programlisting filename="example_test.cpp"><codeline><highlight class="normal">}</highlight></codeline></programlisting> </para>
     </detaileddescription>
+    <location file="021_dontinclude.cpp"/>
   </compounddef>
 </doxygen>
index 581130a..3d80cb2 100644 (file)
@@ -16,5 +16,6 @@ digraph example {
 </dot>
  </para>
     </detaileddescription>
+    <location file="022_dot.cpp"/>
   </compounddef>
 </doxygen>
index 3f605db..a0c4e55 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>Normal <emphasis>emphasis</emphasis> and more <emphasis>emphasis</emphasis> back to normal. </para>
     </detaileddescription>
+    <location file="023_e.dox"/>
   </compounddef>
 </doxygen>
index bd94eb8..026ae8c 100644 (file)
@@ -22,5 +22,6 @@
         <para>test1test3. </para>
       </sect1>
     </detaileddescription>
+    <location file="024_if.dox"/>
   </compounddef>
 </doxygen>
index 55bcfd6..880d7f1 100644 (file)
@@ -8,5 +8,6 @@
       <para>This is an example of how to use the <ref refid="class_test" kindref="compound">Test</ref> class.</para>
       <para>More details about this example. <programlisting filename="example_test.cpp"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keyword">const</highlight><highlight class="normal"><sp/></highlight><highlight class="keywordtype">char</highlight><highlight class="normal">*<sp/>a<sp/>=<sp/></highlight><highlight class="stringliteral">"Some<sp/>special<sp/>character<sp/>here:<sp/><sp value="7"/><sp/>"</highlight><highlight class="normal">;</highlight></codeline><codeline><highlight class="normal"/></codeline><codeline><highlight class="normal"><sp/><sp/><ref refid="class_test" kindref="compound">Test</ref><sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.<ref refid="class_test_1a47b775f65718978f1ffcd96376f8ecfa" kindref="member">example</ref>();</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline><codeline><highlight class="normal"/></codeline></programlisting> </para>
     </detaileddescription>
+    <location file="025_example.cpp"/>
   </compounddef>
 </doxygen>
index 11d3932..93485c4 100644 (file)
@@ -9,5 +9,6 @@
       <para>Here are some formulas:<orderedlist><listitem><para>The distance between <formula id="0">$(x_1,y_1)$</formula> and <formula id="1">$(x_2,y_2)$</formula> is <formula id="2">$\sqrt{(x_2-x_1)^2+(y_2-y_1)^2}$</formula>.</para></listitem><listitem><para>Unnumbered formula: <formula id="3">\[ |I_2|=\left| \int_{0}^T \psi(t) \left\{ u(a,t)- \int_{\gamma(t)}^a \frac{d\theta}{k(\theta,t)} \int_{a}^\theta c(\xi)u_t(\xi,t)\,d\xi \right\} dt \right| \]</formula></para></listitem><listitem><para>Formula in different environment <formula id="4">\begin{eqnarray*} g &amp;=&amp; \frac{Gm_2}{r^2} \\ &amp;=&amp; \frac{(6.673 \times 10^{-11}\,\mbox{m}^3\,\mbox{kg}^{-1}\, \mbox{s}^{-2})(5.9736 \times 10^{24}\,\mbox{kg})}{(6371.01\,\mbox{km})^2} \\ &amp;=&amp; 9.82066032\,\mbox{m/s}^2 \end{eqnarray*}</formula> </para></listitem></orderedlist>
 </para>
     </detaileddescription>
+    <location file="028_formula.c"/>
   </compounddef>
 </doxygen>
index 646a128..8bbf660 100644 (file)
@@ -9,5 +9,6 @@
       <para>Some text. <htmlonly block="yes">&lt;h1&gt;Hello world&lt;/h1&gt;
 </htmlonly> More text. </para>
     </detaileddescription>
+    <location file="030_htmlinclude.dox"/>
   </compounddef>
 </doxygen>
index fc030f6..0690560 100644 (file)
@@ -29,26 +29,27 @@ This image is inline <image type="html" name="https://raster.shields.io/badge/li
 This image is inline <image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.png" inline="yes">MIT license</image>
  within the text.</para>
       <para>Markdown style linked SVG image:<linebreak/>
-<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.svg" inline="yes"/></ulink></para>
+<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.svg" alt="MIT license" inline="yes"/></ulink></para>
       <para>Markdown style linked PNG image:<linebreak/>
-<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.png" inline="yes"/></ulink></para>
+<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.png" alt="MIT license" inline="yes"/></ulink></para>
       <para>HTML style linked SVG image:<linebreak/>
-<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.svg" inline="yes"/></ulink></para>
+<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.svg" alt="MIT license" inline="yes"/></ulink></para>
       <para>HTML style linked PNG image:<linebreak/>
-<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.png" inline="yes"/></ulink></para>
+<ulink url="https://opensource.org/licenses/MIT"><image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.png" alt="MIT license" inline="yes"/></ulink></para>
       <para>HTML style unlinked SVG image:<linebreak/>
-<image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.svg" inline="yes"/>
+<image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.svg" alt="MIT license" inline="yes"/>
 </para>
       <para>HTML style unlinked PNG image:<linebreak/>
-<image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.png" inline="yes"/>
+<image type="html" name="https://raster.shields.io/badge/license-MIT-brightgreen.png" alt="MIT license" inline="yes"/>
 </para>
       <para>Some markdown image tests<linebreak/>
-<image type="html" name="https://raster.shields.io/badge/docs-Doxygen-blue.svg?foo&amp;bar" inline="yes"/>
+<image type="html" name="https://raster.shields.io/badge/docs-Doxygen-blue.svg?foo&amp;bar" alt="Some SVG image" inline="yes"/>
  <ulink url="https://www.doxygen.nl/index.html?foo&amp;bar">Some normal link</ulink></para>
       <para>
-        <image type="html" name="https://raster.shields.io/badge/docs-Doxygen-blue.svg?foo&amp;bar" inline="yes"/>
+        <image type="html" name="https://raster.shields.io/badge/docs-Doxygen-blue.svg?foo&amp;bar" alt="Some SVG image" inline="yes"/>
         <ulink url="https://www.doxygen.nl/index.html?foo&amp;bar">Some normal link</ulink>
       </para>
     </detaileddescription>
+    <location file="031_image.dox"/>
   </compounddef>
 </doxygen>
index 742c401..f33c8b2 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>Some text. <programlisting filename="example_test.cpp"><codeline><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline><highlight class="normal">{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keyword">const</highlight><highlight class="normal"><sp/></highlight><highlight class="keywordtype">char</highlight><highlight class="normal">*<sp/>a<sp/>=<sp/></highlight><highlight class="stringliteral">"Some<sp/>special<sp/>character<sp/>here:<sp/><sp value="7"/><sp/>"</highlight><highlight class="normal">;</highlight></codeline><codeline><highlight class="normal"/></codeline><codeline><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline><codeline><highlight class="normal">}</highlight></codeline><codeline><highlight class="normal"/></codeline></programlisting> More text. <programlisting filename="example_test.cpp"><codeline lineno="1"><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/>main()</highlight></codeline><codeline lineno="2"><highlight class="normal">{</highlight></codeline><codeline lineno="3"><highlight class="normal"><sp/><sp/></highlight><highlight class="keyword">const</highlight><highlight class="normal"><sp/></highlight><highlight class="keywordtype">char</highlight><highlight class="normal">*<sp/>a<sp/>=<sp/></highlight><highlight class="stringliteral">"Some<sp/>special<sp/>character<sp/>here:<sp/><sp value="7"/><sp/>"</highlight><highlight class="normal">;</highlight></codeline><codeline lineno="4"><highlight class="normal"/></codeline><codeline lineno="5"><highlight class="normal"><sp/><sp/>Test<sp/>t;</highlight></codeline><codeline lineno="6"><highlight class="normal"><sp/><sp/>t.example();</highlight></codeline><codeline lineno="7"><highlight class="normal">}</highlight></codeline><codeline lineno="8"><highlight class="normal"/></codeline></programlisting> End. </para>
     </detaileddescription>
+    <location file="032_include.cpp"/>
   </compounddef>
 </doxygen>
index 8894e6c..e00c009 100644 (file)
@@ -9,5 +9,6 @@
       <para>Some text.</para>
       <para>More visible text. </para>
     </detaileddescription>
+    <location file="033_internal.dox"/>
   </compounddef>
 </doxygen>
index 409298d..404fa20 100644 (file)
@@ -27,5 +27,6 @@
         <para>Visible text. </para>
       </sect1>
     </detaileddescription>
+    <location file="034_internal.dox"/>
   </compounddef>
 </doxygen>
index 3309dda..01a8c5d 100644 (file)
@@ -10,5 +10,6 @@
 New line<linebreak/>
 Another line </para>
     </detaileddescription>
+    <location file="038_n.dox"/>
   </compounddef>
 </doxygen>
index 66688bd..8a74545 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>Another page's text. </para>
     </detaileddescription>
+    <location file="043_page.dox"/>
   </compounddef>
 </doxygen>
index c02b4c4..d1a65bd 100644 (file)
@@ -62,5 +62,6 @@
         </para>
       </sect1>
     </detaileddescription>
+    <location file="043_page.dox"/>
   </compounddef>
 </doxygen>
index aaa8934..2a1b8c7 100644 (file)
@@ -19,5 +19,6 @@
         <para>Section 1 text. </para>
       </sect1>
     </detaileddescription>
+    <location file="045_refitem.dox"/>
   </compounddef>
 </doxygen>
index c5ae30f..2b78363 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>A bubble sort algorithm First get the inputs <programlisting filename="snippet_test.cpp"><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>printf(</highlight><highlight class="stringliteral">"<sp/>Array[%d]<sp/>=<sp/>"</highlight><highlight class="normal">,i);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>scanf(</highlight><highlight class="stringliteral">"%d"</highlight><highlight class="normal">,&amp;arr[i]);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting>Then do the bubbling <programlisting filename="snippet_test.cpp"><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(j=0<sp/>;<sp/>j&lt;n-i-1<sp/>;<sp/>j++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal">(arr[j]&gt;arr[j+1])<sp/></highlight><highlight class="comment">//Swapping<sp/>Condition<sp/>is<sp/>Checked</highlight><highlight class="normal"/></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>temp=arr[j];</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>arr[j]=arr[j+1];</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/><sp/><sp/>arr[j+1]=temp;</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/><sp/><sp/>}</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>}</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting>Then write the result <programlisting filename="snippet_test.cpp"><codeline><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">for</highlight><highlight class="normal">(i=0<sp/>;<sp/>i&lt;n<sp/>;<sp/>i++)</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>{</highlight></codeline><codeline><highlight class="normal"><sp/><sp/><sp/><sp/>printf(</highlight><highlight class="stringliteral">"<sp/>%4d"</highlight><highlight class="normal">,arr[i]);</highlight></codeline><codeline><highlight class="normal"><sp/><sp/>}</highlight></codeline></programlisting></para>
     </detaileddescription>
+    <location file="049_snippet.cpp"/>
   </compounddef>
 </doxygen>
index 1987274..f2414ce 100644 (file)
@@ -41,5 +41,6 @@
 }
 </verbatim> More text after the verbatim section. </para>
     </detaileddescription>
+    <location file="050_verbatim.dox"/>
   </compounddef>
 </doxygen>
index 63f2d91..2fcf5ac 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>Dollar $ At @ Backslash \ Ampersand &amp; Less &lt; Greater &gt; Hash # Percent % Quote " Dot . Double colon :: Pipe | Plus + Minus - </para>
     </detaileddescription>
+    <location file="051_escape.dox"/>
   </compounddef>
 </doxygen>
index 0306320..5f5d78f 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>This is English. Output for all languages. </para>
     </detaileddescription>
+    <location file="052_tilde.dox"/>
   </compounddef>
 </doxygen>
index 9f33bcf..8698375 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>Dit is Nederlands. Output for all languages. </para>
     </detaileddescription>
+    <location file="053_tilde.dox"/>
   </compounddef>
 </doxygen>
index 423a28c..8423c35 100644 (file)
@@ -33,5 +33,6 @@
         </sect2>
       </sect1>
     </detaileddescription>
+    <location file="055_markdown.md"/>
   </compounddef>
 </doxygen>
index ac89900..2cfff91 100644 (file)
@@ -9,5 +9,6 @@
       <para>Some text. <latexonly>\section{Hello world}
 </latexonly> More text. </para>
     </detaileddescription>
+    <location file="056_latexinclude.dox"/>
   </compounddef>
 </doxygen>
index e86dcff..c8eb957 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>これは日本語(en)です. Output for all languages. </para>
     </detaileddescription>
+    <location file="065_tilde.dox"/>
   </compounddef>
 </doxygen>
index f2ec00e..3b6fd6c 100644 (file)
  <emoji name="zzz" unicode="&amp;#x1f4a4;"/> <emoji name="zzz" unicode="&amp;#x1f4a4;"/> from "zzz"<linebreak/>
  </para>
     </detaileddescription>
+    <location file="076_emojis.cpp"/>
   </compounddef>
 </doxygen>
index 3c753c1..3af5afb 100644 (file)
@@ -8,5 +8,6 @@
     <detaileddescription>
       <para>With an empty TOC. </para>
     </detaileddescription>
+    <location file="079_tableofcontents.dox"/>
   </compounddef>
 </doxygen>
index 8a208b4..76089bd 100644 (file)
@@ -37,5 +37,6 @@
         <para>Yay! </para>
       </sect1>
     </detaileddescription>
+    <location file="079_tableofcontents.dox"/>
   </compounddef>
 </doxygen>
index fde252d..f981c55 100755 (executable)
@@ -52,7 +52,7 @@ def clean_header(errmsg):
                        if (cnt > 0):
                                cnt-=1
                        else:
-                               rtnmsg+=0
+                               rtnmsg+=o
        return rtnmsg
  
 class Tester: