summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2019-08-11 17:57:34 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2019-08-11 17:57:34 (GMT)
commit3e8fe63473b047bf3d48c734750334244e9981a8 (patch)
tree3d2f224b78898feb3c4b88cc5e904f5da4284f06
parent09c263e70a2ac9afbe8f7cc7a0a07c5ab069645a (diff)
downloadDoxygen-3e8fe63473b047bf3d48c734750334244e9981a8.zip
Doxygen-3e8fe63473b047bf3d48c734750334244e9981a8.tar.gz
Doxygen-3e8fe63473b047bf3d48c734750334244e9981a8.tar.bz2
Reduce boilerplate code by using C++11 variadic templates and perfect forwarding
-rw-r--r--src/index.h75
-rw-r--r--src/outputlist.cpp159
-rw-r--r--src/outputlist.h79
3 files changed, 32 insertions, 281 deletions
diff --git a/src/index.h b/src/index.h
index c6baba5..f571375 100644
--- a/src/index.h
+++ b/src/index.h
@@ -18,6 +18,7 @@
#ifndef INDEX_H
#define INDEX_H
+#include <utility>
#include <qlist.h>
#include <qcstring.h>
@@ -55,61 +56,17 @@ class IndexList : public IndexIntf
private:
QList<IndexIntf> m_intfs;
- // --- foreach implementations for various number of arguments
-
- void foreach(void (IndexIntf::*methodPtr)())
- {
- QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)();
- }
-
- template<typename A1>
- void foreach(void (IndexIntf::*methodPtr)(A1),A1 a1)
- {
- QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1);
- }
-
- template<typename A1,typename A2,typename A3>
- void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3),A1 a1,A2 a2,A3 a3)
- {
- QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3);
- }
-
- template<typename A1,typename A2,typename A3,typename A4>
- void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4),A1 a1,A2 a2,A3 a3,A4 a4)
- {
- QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4);
- }
-
- template<typename A1,typename A2,typename A3,typename A4,typename A5>
- void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5)
- {
- QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5);
- }
-
- template<typename A1,typename A2,typename A3,typename A4,typename A5,typename A6>
- void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5,A6),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6)
- {
- QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5,a6);
- }
-
- template<typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8>
- void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5,A6,A7,A8),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8)
- {
- QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5,a6,a7,a8);
- }
-
- template<typename A1,typename A2,typename A3,typename A4,typename A5,typename A6,typename A7,typename A8,typename A9>
- void foreach(void (IndexIntf::*methodPtr)(A1,A2,A3,A4,A5,A6,A7,A8,A9),A1 a1,A2 a2,A3 a3,A4 a4,A5 a5,A6 a6,A7 a7,A8 a8,A9 a9)
+ // For each index format we forward the method call.
+ // We use C++11 variadic templates and perfect forwarding to implement foreach() generically,
+ // and split the types of the methods from the arguments passed to allow implicit conversions.
+ template<class... Ts,class... As>
+ void foreach(void (IndexIntf::*methodPtr)(Ts...),As&&... args)
{
QListIterator<IndexIntf> li(m_intfs);
- for (li.toFirst();li.current();++li) (li.current()->*methodPtr)(a1,a2,a3,a4,a5,a6,a7,a8,a9);
+ for (li.toFirst();li.current();++li)
+ {
+ (li.current()->*methodPtr)(std::forward<As>(args)...);
+ }
}
public:
@@ -137,17 +94,15 @@ class IndexList : public IndexIntf
void addContentsItem(bool isDir, const char *name, const char *ref,
const char *file, const char *anchor,bool separateIndex=FALSE,bool addToNavIndex=FALSE,
const Definition *def=0)
- { if (m_enabled) foreach<bool,const char *,const char *,const char *,const char*,bool,bool,const Definition *>
- (&IndexIntf::addContentsItem,isDir,name,ref,file,anchor,separateIndex,addToNavIndex,def); }
+ { if (m_enabled) foreach(&IndexIntf::addContentsItem,isDir,name,ref,file,anchor,separateIndex,addToNavIndex,def); }
void addIndexItem(const Definition *context,const MemberDef *md,const char *sectionAnchor=0,const char *title=0)
- { if (m_enabled) foreach<const Definition *,const MemberDef *,const char *,const char *>
- (&IndexIntf::addIndexItem,context,md,sectionAnchor,title); }
+ { if (m_enabled) foreach(&IndexIntf::addIndexItem,context,md,sectionAnchor,title); }
void addIndexFile(const char *name)
- { if (m_enabled) foreach<const char *>(&IndexIntf::addIndexFile,name); }
+ { if (m_enabled) foreach(&IndexIntf::addIndexFile,name); }
void addImageFile(const char *name)
- { if (m_enabled) foreach<const char *>(&IndexIntf::addImageFile,name); }
+ { if (m_enabled) foreach(&IndexIntf::addImageFile,name); }
void addStyleSheetFile(const char *name)
- { if (m_enabled) foreach<const char *>(&IndexIntf::addStyleSheetFile,name); }
+ { if (m_enabled) foreach(&IndexIntf::addStyleSheetFile,name); }
private:
bool m_enabled;
diff --git a/src/outputlist.cpp b/src/outputlist.cpp
index daf3270..c47c1c9 100644
--- a/src/outputlist.cpp
+++ b/src/outputlist.cpp
@@ -196,163 +196,4 @@ void OutputList::parseText(const QCString &textStr)
delete root;
}
-
-//--------------------------------------------------------------------------
-// Create some overloaded definitions of the forall function.
-// Using template functions here would have made it a little less
-// portable (I guess).
-
-// zero arguments
-void OutputList::forall(void (OutputGenerator::*func)())
-{
- QListIterator<OutputGenerator> it(m_outputs);
- OutputGenerator *og;
- for (it.toFirst();(og=it.current());++it)
- {
- if (og->isEnabled()) (og->*func)();
- }
-}
-
-// one argument
-#define FORALL1(a1,p1) \
-void OutputList::forall(void (OutputGenerator::*func)(a1),a1) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1); \
- } \
-}
-
-// two arguments
-#define FORALL2(a1,a2,p1,p2) \
-void OutputList::forall(void (OutputGenerator::*func)(a1,a2),a1,a2) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1,p2); \
- } \
-}
-
-// three arguments
-#define FORALL3(a1,a2,a3,p1,p2,p3) \
-void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3),a1,a2,a3) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1,p2,p3); \
- } \
-}
-
-// four arguments
-#define FORALL4(a1,a2,a3,a4,p1,p2,p3,p4) \
-void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4),a1,a2,a3,a4) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1,p2,p3,p4); \
- } \
-}
-
-// five arguments
-#define FORALL5(a1,a2,a3,a4,a5,p1,p2,p3,p4,p5) \
-void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5),a1,a2,a3,a4,a5) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5); \
- } \
-}
-
-// six arguments
-#define FORALL6(a1,a2,a3,a4,a5,a6,p1,p2,p3,p4,p5,p6) \
-void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6),a1,a2,a3,a4,a5,a6) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5,p6); \
- } \
-}
-
-// seven arguments
-#define FORALL7(a1,a2,a3,a4,a5,a6,a7,p1,p2,p3,p4,p5,p6,p7) \
-void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6,a7),a1,a2,a3,a4,a5,a6,a7) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5,p6,p7); \
- } \
-}
-
-
-// eight arguments
-#define FORALL8(a1,a2,a3,a4,a5,a6,a7,a8,p1,p2,p3,p4,p5,p6,p7,p8) \
-void OutputList::forall(void (OutputGenerator::*func)(a1,a2,a3,a4,a5,a6,a7,a8),a1,a2,a3,a4,a5,a6,a7,a8) \
-{ \
- QListIterator<OutputGenerator> it(m_outputs); \
- OutputGenerator *og; \
- for (it.toFirst();(og=it.current());++it) \
- { \
- if (og->isEnabled()) (og->*func)(p1,p2,p3,p4,p5,p6,p7,p8); \
- } \
-}
-
-// now instantiate only the ones we need.
-
-FORALL1(const char *a1,a1)
-FORALL1(char a1,a1)
-FORALL1(int a1,a1)
-FORALL1(DotClassGraph &a1,a1)
-FORALL1(DotInclDepGraph &a1,a1)
-FORALL1(DotCallGraph &a1,a1)
-FORALL1(DotDirDeps &a1,a1)
-FORALL1(DotGfxHierarchyTable &a1,a1)
-FORALL1(DotGroupCollaboration &a1,a1)
-FORALL1(SectionTypes a1,a1)
-#if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE)
-FORALL1(bool a1,a1)
-FORALL2(bool a1,int a2,a1,a2)
-FORALL2(bool a1,bool a2,a1,a2)
-FORALL2(const char *a1,bool a2,a1,a2)
-FORALL4(const char *a1,const char *a2,const char *a3,bool a4,a1,a2,a3,a4)
-#endif
-FORALL2(int a1,bool a2,a1,a2)
-FORALL2(bool a1,const char *a2,a1,a2)
-FORALL2(ParamListTypes a1,const char *a2,a1,a2)
-FORALL1(IndexSections a1,a1)
-FORALL2(const char *a1,const char *a2,a1,a2)
-FORALL2(const char *a1,int a2,a1,a2)
-FORALL2(const char *a1,SectionInfo::SectionType a2,a1,a2)
-FORALL3(bool a1,HighlightedItem a2,const char *a3,a1,a2,a3)
-FORALL3(bool a1,bool a2,bool a3,a1,a2,a3)
-FORALL3(const ClassDiagram &a1,const char *a2,const char *a3,a1,a2,a3)
-FORALL3(const char *a1,const char *a2,const char *a3,a1,a2,a3)
-FORALL3(const char *a1,const char *a2,bool a3,a1,a2,a3)
-FORALL3(const char *a1,int a2,const char *a3,a1,a2,a3)
-FORALL3(const char *a1,const char *a2,SectionInfo::SectionType a3,a1,a2,a3)
-FORALL3(uchar a1,uchar a2,uchar a3,a1,a2,a3)
-FORALL3(const Definition *a1,const char *a2,bool a3,a1,a2,a3)
-FORALL4(SectionTypes a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4)
-FORALL4(const char *a1,const char *a2,const char *a3,const char *a4,a1,a2,a3,a4)
-FORALL4(const char *a1,const char *a2,const char *a3,int a4,a1,a2,a3,a4)
-FORALL5(const char *a1,const char *a2,const char *a3,const char *a4,const char *a5,a1,a2,a3,a4,a5)
-FORALL5(const char *a1,const char *a2,const char *a3,const char *a4,bool a5,a1,a2,a3,a4,a5)
-FORALL6(const char *a1,const char *a2,const char *a3,const char *a4,const char *a5,const char *a6,a1,a2,a3,a4,a5,a6)
-FORALL6(const char *a1,const DocLinkInfo &a2,const char *a3,const char *a4,const SourceLinkInfo &a5,const SourceLinkInfo &a6,a1,a2,a3,a4,a5,a6)
-FORALL7(const char *a1,const char *a2,const char *a3,const char *a4,int a5,int a6,bool a7,a1,a2,a3,a4,a5,a6,a7)
-
-
//--------------------------------------------------------------------------
diff --git a/src/outputlist.h b/src/outputlist.h
index 2a83020..cfd3773 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -18,6 +18,7 @@
#ifndef OUTPUTLIST_H
#define OUTPUTLIST_H
+#include <utility>
#include <qlist.h>
#include "index.h" // for IndexSections
#include "outputgen.h"
@@ -109,8 +110,6 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::startTitle); }
void endTitle()
{ forall(&OutputGenerator::endTitle); }
- //void newParagraph()
- //{ forall(&OutputGenerator::newParagraph); }
void startParagraph(const char *classDef=0)
{ forall(&OutputGenerator::startParagraph,classDef); }
void endParagraph()
@@ -176,8 +175,6 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::startGroupHeader,extraLevels); }
void endGroupHeader(int extraLevels=0)
{ forall(&OutputGenerator::endGroupHeader,extraLevels); }
- //void writeListItem()
- //{ forall(&OutputGenerator::writeListItem); }
void startItemListItem()
{ forall(&OutputGenerator::startItemListItem); }
void endItemListItem()
@@ -492,70 +489,28 @@ class OutputList : public OutputDocInterface
{ forall(&OutputGenerator::addWord,word,hiPriority); }
void startPlainFile(const char *name)
- {
- QListIterator<OutputGenerator> it(m_outputs);
- OutputGenerator *og;
- for (;(og=it.current());++it)
- {
- if (og->isEnabled()) (og->startPlainFile)(name);
- }
- }
+ { forall(&OutputGenerator::startPlainFile,name); }
void endPlainFile()
- {
- QListIterator<OutputGenerator> it(m_outputs);
- OutputGenerator *og;
- for (;(og=it.current());++it)
- {
- if (og->isEnabled()) (og->endPlainFile)();
- }
- }
+ { forall(&OutputGenerator::endPlainFile); }
private:
void debug();
void clear();
- void forall(void (OutputGenerator::*func)());
- FORALLPROTO1(const char *);
- FORALLPROTO1(char);
- FORALLPROTO1(IndexSections);
- FORALLPROTO1(int);
- FORALLPROTO1(DotClassGraph &);
- FORALLPROTO1(DotInclDepGraph &);
- FORALLPROTO1(DotCallGraph &);
- FORALLPROTO1(DotGroupCollaboration &);
- FORALLPROTO1(DotDirDeps &);
- FORALLPROTO1(DotGfxHierarchyTable &);
- FORALLPROTO1(SectionTypes);
-#if defined(HAS_BOOL_TYPE) || defined(Q_HAS_BOOL_TYPE)
- FORALLPROTO1(bool);
- FORALLPROTO2(bool,int);
- FORALLPROTO2(bool,bool);
- FORALLPROTO2(const char *,bool);
- FORALLPROTO4(const char *,const char *,const char *,int);
-#endif
- FORALLPROTO2(int,bool);
- FORALLPROTO2(bool,const char *);
- FORALLPROTO2(ParamListTypes,const char *);
- FORALLPROTO2(const char *,const char *);
- FORALLPROTO2(const char *,int);
- FORALLPROTO2(const char *,SectionInfo::SectionType);
- FORALLPROTO3(bool,HighlightedItem,const char *);
- FORALLPROTO3(bool,bool,bool);
- FORALLPROTO3(const char *,const char *,bool);
- FORALLPROTO3(const char *,int,const char *);
- FORALLPROTO3(const char *,const char *,SectionInfo::SectionType);
- FORALLPROTO3(uchar,uchar,uchar);
- FORALLPROTO3(const char *,const char *,const char *);
- FORALLPROTO3(const ClassDiagram &,const char *,const char *);
- FORALLPROTO3(const Definition*,const char *,bool);
- FORALLPROTO4(SectionTypes,const char *,const char *,const char *);
- FORALLPROTO4(const char *,const char *,const char *,const char *);
- FORALLPROTO4(const char *,const char *,const char *,bool);
- FORALLPROTO5(const char *,const char *,const char *,const char *,const char *);
- FORALLPROTO5(const char *,const char *,const char *,const char *,bool);
- FORALLPROTO6(const char *,const char *,const char *,const char *,const char *,const char *);
- FORALLPROTO6(const char *,const DocLinkInfo &,const char *,const char *,const SourceLinkInfo &,const SourceLinkInfo &);
- FORALLPROTO7(const char *,const char *,const char *,const char *,int,int,bool);
+ // For each output format that is enabled (OutputGenerator::isEnabled()) we forward
+ // the method call.
+ // We use C++11 variadic templates and perfect forwarding to implement forall() generically,
+ // and split the types of the methods from the arguments passed to allow implicit conversions.
+ template<typename T,class... Ts,class... As>
+ void forall(void (T::*methodPtr)(Ts...),As&&... args)
+ {
+ QListIterator<OutputGenerator> li(m_outputs);
+ OutputGenerator *og;
+ for (li.toFirst();(og=li.current());++li)
+ {
+ if (og->isEnabled()) (og->*methodPtr)(std::forward<As>(args)...);
+ }
+ }
OutputList(const OutputList &ol);
QList<OutputGenerator> m_outputs;