summaryrefslogtreecommitdiffstats
path: root/src/groupdef.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/groupdef.cpp')
-rw-r--r--src/groupdef.cpp143
1 files changed, 89 insertions, 54 deletions
diff --git a/src/groupdef.cpp b/src/groupdef.cpp
index 57e2226..5dfc0ae 100644
--- a/src/groupdef.cpp
+++ b/src/groupdef.cpp
@@ -15,8 +15,12 @@
*
*/
+#include <algorithm>
+#include <vector>
+
#include <ctype.h>
#include <qregexp.h>
+
#include "groupdef.h"
#include "classdef.h"
#include "filedef.h"
@@ -97,7 +101,7 @@ class GroupDefImpl : public DefinitionMixin<GroupDef>
virtual MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; }
virtual FileList * getFiles() const { return m_fileList; }
- virtual ClassSDict * getClasses() const { return m_classSDict; }
+ virtual ClassLinkedRefMap getClasses() const { return m_classes; }
virtual NamespaceSDict * getNamespaces() const { return m_namespaceSDict; }
virtual GroupList * getSubGroups() const { return m_groupList; }
virtual PageSDict * getPages() const { return m_pageDict; }
@@ -136,7 +140,7 @@ class GroupDefImpl : public DefinitionMixin<GroupDef>
bool m_titleSet; // true if title is not the same as the name
QCString m_fileName; // base name of the generated file
FileList * m_fileList; // list of files in the group
- ClassSDict * m_classSDict; // list of classes in the group
+ ClassLinkedRefMap m_classes; // list of classes in the group
NamespaceSDict * m_namespaceSDict; // list of namespaces in the group
GroupList * m_groupList; // list of sub groups.
PageSDict * m_pageDict; // list of pages in the group
@@ -164,7 +168,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_classSDict = new ClassSDict(17);
m_groupList = new GroupList;
m_namespaceSDict = new NamespaceSDict(17);
m_pageDict = new PageSDict(17);
@@ -191,7 +194,6 @@ GroupDefImpl::GroupDefImpl(const char *df,int dl,const char *na,const char *t,
GroupDefImpl::~GroupDefImpl()
{
delete m_fileList;
- delete m_classSDict;
delete m_groupList;
delete m_namespaceSDict;
delete m_pageDict;
@@ -261,47 +263,12 @@ void GroupDefImpl::addFile(const FileDef *def)
bool GroupDefImpl::addClass(const ClassDef *cd)
{
- static bool sortBriefDocs = Config_getBool(SORT_BRIEF_DOCS);
if (cd->isHidden()) return FALSE;
updateLanguage(cd);
QCString qn = cd->name();
- if (m_classSDict->find(qn)==0)
+ if (m_classes.find(qn)==0)
{
- //printf("--- addClass %s sort=%d\n",qn.data(),sortBriefDocs);
- if (sortBriefDocs)
- {
- m_classSDict->inSort(qn,cd);
- }
- else
- {
- int i=qn.findRev("::");
- if (i==-1) i=qn.find('.');
- bool found=FALSE;
- //printf("i=%d\n",i);
- if (i>0)
- {
- // add nested classes (e.g. A::B, A::C) after their parent (A) in
- // order of insertion
- QCString scope = qn.left(i);
- int j=m_classSDict->findAt(scope);
- if (j!=-1)
- {
- while (j<(int)m_classSDict->count() &&
- m_classSDict->at(j)->qualifiedName().left(i)==scope)
- {
- //printf("skipping over %s\n",classSDict->at(j)->qualifiedName().data());
- j++;
- }
- //printf("Found scope at index %d\n",j);
- m_classSDict->insertAt(j,qn,cd);
- found=TRUE;
- }
- }
- if (!found) // no insertion point found -> just append
- {
- m_classSDict->append(qn,cd);
- }
- }
+ m_classes.add(qn,cd);
return TRUE;
}
return FALSE;
@@ -653,7 +620,7 @@ void GroupDefImpl::countMembers()
int GroupDefImpl::numDocMembers() const
{
return m_fileList->count()+
- m_classSDict->count()+
+ m_classes.size()+
m_namespaceSDict->count()+
m_groupList->count()+
m_allMemberList->count()+
@@ -683,17 +650,12 @@ void GroupDefImpl::writeTagFile(FTextStream &tagFile)
{
case LayoutDocEntry::GroupClasses:
{
- if (m_classSDict)
+ for (const auto &cd : m_classes)
{
- SDict<ClassDef>::Iterator ci(*m_classSDict);
- ClassDef *cd;
- for (ci.toFirst();(cd=ci.current());++ci)
+ if (cd->isLinkableInProject())
{
- if (cd->isLinkableInProject())
- {
- tagFile << " <class kind=\"" << cd->compoundTypeString()
- << "\">" << convertToXML(cd->name()) << "</class>" << endl;
- }
+ tagFile << " <class kind=\"" << cd->compoundTypeString()
+ << "\">" << convertToXML(cd->name()) << "</class>" << endl;
}
}
}
@@ -1050,12 +1012,12 @@ void GroupDefImpl::writeDirs(OutputList &ol,const QCString &title)
void GroupDefImpl::writeClasses(OutputList &ol,const QCString &title)
{
// write list of classes
- m_classSDict->writeDeclaration(ol,0,title,FALSE);
+ m_classes.writeDeclaration(ol,0,title,FALSE);
}
void GroupDefImpl::writeInlineClasses(OutputList &ol)
{
- m_classSDict->writeDocumentation(ol);
+ m_classes.writeDocumentation(ol);
}
void GroupDefImpl::writePageDocumentation(OutputList &ol)
@@ -1152,7 +1114,7 @@ void GroupDefImpl::writeSummaryLinks(OutputList &ol) const
SrcLangExt lang = getLanguage();
for (eli.toFirst();(lde=eli.current());++eli)
{
- if ((lde->kind()==LayoutDocEntry::GroupClasses && m_classSDict->declVisible()) ||
+ if ((lde->kind()==LayoutDocEntry::GroupClasses && m_classes.declVisible()) ||
(lde->kind()==LayoutDocEntry::GroupNamespaces && m_namespaceSDict->declVisible()) ||
(lde->kind()==LayoutDocEntry::GroupFiles && m_fileList->count()>0) ||
(lde->kind()==LayoutDocEntry::GroupNestedGroups && m_groupList->count()>0) ||
@@ -1697,6 +1659,67 @@ void GroupDefImpl::addMemberToList(MemberListType lt,MemberDef *md)
ml->append(md);
}
+// performs a partial reordering to group elements together with the same scope
+template<class Vec>
+static void groupClassesWithSameScope(Vec &vec)
+{
+ bool done=false;
+ while (!done) // for each iteration
+ {
+ done=true;
+ for (size_t i=0; i<vec.size(); i++) // go through all items
+ {
+ std::string qni = vec[i]->name().str();
+ size_t posi = qni.rfind("::");
+ if (posi!=std::string::npos)
+ {
+ std::string scope = qni.substr(0,posi);
+ auto it = std::find_if( vec.begin(), vec.end(),
+ [&](typename Vec::Ptr &cd)
+ { return cd->name().str()==scope; });
+ if (it!=vec.end())
+ {
+ size_t idx = std::distance(vec.begin(),it);
+ if (i<idx) // parent scope located after child scope
+ {
+ // to avoid reordering elements with the same parent
+ // we skip to the last one with the same scope
+ size_t k = idx;
+ while (k<vec.size() && vec[k]->name().str().substr(0,posi)==scope)
+ {
+ 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++)
+ {
+ std::swap(vec[j],vec[j+1]);
+ }
+ done=false;
+ }
+ else if (idx<i && vec[i-1]->name().str().substr(0,posi)!=scope)
+ {
+ // parent scope is found before the item, and the item
+ // has some other item with a different scope in front of it
+ // move idx to the end of range with the same scope
+ while (idx<i && vec[idx]->name().str().substr(0,posi)==scope)
+ {
+ idx++;
+ }
+ // swap the items such that i is just after idx
+ for (size_t j=idx; j<i; j++)
+ {
+ std::swap(vec[j],vec[j+1]);
+ }
+ done=false;
+ }
+ }
+ }
+ }
+ }
+}
+
void GroupDefImpl::sortMemberLists()
{
QListIterator<MemberList> mli(m_memberLists);
@@ -1708,6 +1731,18 @@ void GroupDefImpl::sortMemberLists()
if (Config_getBool(SORT_BRIEF_DOCS))
{
std::sort(m_dirList.begin(), m_dirList.end(), compareDirDefs);
+
+ auto classComp = [](const ClassLinkedRefMap::Ptr &c1,const ClassLinkedRefMap::Ptr &c2)
+ {
+ return Config_getBool(SORT_BY_SCOPE_NAME) ?
+ qstricmp(c1->name(), c2->name())<0 :
+ qstricmp(c1->className(), c2->className())<0;
+ };
+ std::sort(m_classes.begin(), m_classes.end(), classComp);
+ }
+ else
+ {
+ groupClassesWithSameScope(m_classes);
}
}