1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2020 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #ifndef OUTPUTLIST_H
17 #define OUTPUTLIST_H
18 
19 #include <utility>
20 #include <vector>
21 #include <memory>
22 
23 #include "index.h" // for IndexSections
24 #include "outputgen.h"
25 
26 class ClassDiagram;
27 class DotClassGraph;
28 class DotDirDeps;
29 class DotInclDepGraph;
30 class DotGfxHierarchyTable;
31 class DotGroupCollaboration;
32 class DocRoot;
33 
34 /** Class representing a list of output generators that are written to
35  *  in parallel.
36  */
37 class OutputList : public OutputDocInterface
38 {
39   public:
40     OutputList();
41     OutputList(const OutputList &ol);
42     OutputList &operator=(const OutputList &ol);
43     virtual ~OutputList();
44 
45     template<class Generator>
add()46     void add()
47     {
48       m_outputs.emplace_back(std::make_unique<Generator>());
49     }
50 
size()51     size_t size() const { return m_outputs.size(); }
id()52     int id() const { return m_id; }
53 
54     void disableAllBut(OutputGenerator::OutputType o);
55     void enableAll();
56     void disableAll();
57     void disable(OutputGenerator::OutputType o);
58     void enable(OutputGenerator::OutputType o);
59     bool isEnabled(OutputGenerator::OutputType o);
60     void pushGeneratorState();
61     void popGeneratorState();
62 
63 
64     //////////////////////////////////////////////////
65     // OutputDocInterface implementation
66     //////////////////////////////////////////////////
67 
68     void generateDoc(const QCString &fileName,int startLine,
69                      const Definition *ctx,const MemberDef *md,const QCString &docStr,
70                      bool indexWords,bool isExample,const QCString &exampleName /*=0*/,
71                      bool singleLine /*=FALSE*/,bool linkFromIndex /*=FALSE*/,
72                      bool markdownSupport /*=FALSE*/);
73     void writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *md,int id=0);
74     void parseText(const QCString &textStr);
75 
startIndexSection(IndexSections is)76     void startIndexSection(IndexSections is)
77     { forall(&OutputGenerator::startIndexSection,is); }
endIndexSection(IndexSections is)78     void endIndexSection(IndexSections is)
79     { forall(&OutputGenerator::endIndexSection,is); }
writePageLink(const QCString & name,bool first)80     void writePageLink(const QCString &name,bool first)
81     { forall(&OutputGenerator::writePageLink,name,first); }
startProjectNumber()82     void startProjectNumber()
83     { forall(&OutputGenerator::startProjectNumber); }
endProjectNumber()84     void endProjectNumber()
85     { forall(&OutputGenerator::endProjectNumber); }
writeStyleInfo(int part)86     void writeStyleInfo(int part)
87     { forall(&OutputGenerator::writeStyleInfo,part); }
startFile(const QCString & name,const QCString & manName,const QCString & title)88     void startFile(const QCString &name,const QCString &manName,const QCString &title)
89     {
90       newId();
91       forall(&OutputGenerator::startFile,name,manName,title,m_id);
92     }
writeSearchInfo()93     void writeSearchInfo()
94     { forall(&OutputGenerator::writeSearchInfo); }
writeFooter(const QCString & navPath)95     void writeFooter(const QCString &navPath)
96     { forall(&OutputGenerator::writeFooter,navPath); }
endFile()97     void endFile()
98     { forall(&OutputGenerator::endFile); }
startTitleHead(const QCString & fileName)99     void startTitleHead(const QCString &fileName)
100     { forall(&OutputGenerator::startTitleHead,fileName); }
endTitleHead(const QCString & fileName,const QCString & name)101     void endTitleHead(const QCString &fileName,const QCString &name)
102     { forall(&OutputGenerator::endTitleHead,fileName,name); }
startTitle()103     void startTitle()
104     { forall(&OutputGenerator::startTitle); }
endTitle()105     void endTitle()
106     { forall(&OutputGenerator::endTitle); }
107     void startParagraph(const QCString &classDef=QCString())
108     { forall(&OutputGenerator::startParagraph,classDef); }
endParagraph()109     void endParagraph()
110     { forall(&OutputGenerator::endParagraph); }
writeString(const QCString & text)111     void writeString(const QCString &text)
112     { forall(&OutputGenerator::writeString,text); }
startIndexListItem()113     void startIndexListItem()
114     { forall(&OutputGenerator::startIndexListItem); }
endIndexListItem()115     void endIndexListItem()
116     { forall(&OutputGenerator::endIndexListItem); }
startIndexList()117     void startIndexList()
118     { forall(&OutputGenerator::startIndexList); }
endIndexList()119     void endIndexList()
120     { forall(&OutputGenerator::endIndexList); }
startIndexKey()121     void startIndexKey()
122     { forall(&OutputGenerator::startIndexKey); }
endIndexKey()123     void endIndexKey()
124     { forall(&OutputGenerator::endIndexKey); }
startIndexValue(bool b)125     void startIndexValue(bool b)
126     { forall(&OutputGenerator::startIndexValue,b); }
endIndexValue(const QCString & name,bool b)127     void endIndexValue(const QCString &name,bool b)
128     { forall(&OutputGenerator::endIndexValue,name,b); }
startItemList()129     void startItemList()
130     { forall(&OutputGenerator::startItemList); }
endItemList()131     void endItemList()
132     { forall(&OutputGenerator::endItemList); }
startIndexItem(const QCString & ref,const QCString & file)133     void startIndexItem(const QCString &ref,const QCString &file)
134     { forall(&OutputGenerator::startIndexItem,ref,file); }
endIndexItem(const QCString & ref,const QCString & file)135     void endIndexItem(const QCString &ref,const QCString &file)
136     { forall(&OutputGenerator::endIndexItem,ref,file); }
docify(const QCString & s)137     void docify(const QCString &s)
138     { forall(&OutputGenerator::docify,s); }
codify(const QCString & s)139     void codify(const QCString &s)
140     { forall(&OutputGenerator::codify,s); }
writeObjectLink(const QCString & ref,const QCString & file,const QCString & anchor,const QCString & name)141     void writeObjectLink(const QCString &ref,const QCString &file,
142                          const QCString &anchor, const QCString &name)
143     { forall(&OutputGenerator::writeObjectLink,ref,file,anchor,name); }
writeCodeLink(CodeSymbolType type,const QCString & ref,const QCString & file,const QCString & anchor,const QCString & name,const QCString & tooltip)144     void writeCodeLink(CodeSymbolType type,
145                        const QCString &ref,const QCString &file,
146                        const QCString &anchor,const QCString &name,
147                        const QCString &tooltip)
148     { forall(&OutputGenerator::writeCodeLink,type,ref,file,anchor,name,tooltip); }
writeTooltip(const QCString & id,const DocLinkInfo & docInfo,const QCString & decl,const QCString & desc,const SourceLinkInfo & defInfo,const SourceLinkInfo & declInfo)149     void writeTooltip(const QCString &id, const DocLinkInfo &docInfo, const QCString &decl,
150                       const QCString &desc, const SourceLinkInfo &defInfo, const SourceLinkInfo &declInfo)
151     { forall(&OutputGenerator::writeTooltip,id,docInfo,decl,desc,defInfo,declInfo); }
startTextLink(const QCString & file,const QCString & anchor)152     void startTextLink(const QCString &file,const QCString &anchor)
153     { forall(&OutputGenerator::startTextLink,file,anchor); }
endTextLink()154     void endTextLink()
155     { forall(&OutputGenerator::endTextLink); }
startHtmlLink(const QCString & url)156     void startHtmlLink(const QCString &url)
157     { forall(&OutputGenerator::startHtmlLink,url); }
endHtmlLink()158     void endHtmlLink()
159     { forall(&OutputGenerator::endHtmlLink); }
writeStartAnnoItem(const QCString & type,const QCString & file,const QCString & path,const QCString & name)160     void writeStartAnnoItem(const QCString &type,const QCString &file,
161                             const QCString &path,const QCString &name)
162     { forall(&OutputGenerator::writeStartAnnoItem,type,file,path,name); }
writeEndAnnoItem(const QCString & name)163     void writeEndAnnoItem(const QCString &name)
164     { forall(&OutputGenerator::writeEndAnnoItem,name); }
startTypewriter()165     void startTypewriter()
166     { forall(&OutputGenerator::startTypewriter); }
endTypewriter()167     void endTypewriter()
168     { forall(&OutputGenerator::endTypewriter); }
169     void startGroupHeader(int extraLevels=0)
170     { forall(&OutputGenerator::startGroupHeader,extraLevels); }
171     void endGroupHeader(int extraLevels=0)
172     { forall(&OutputGenerator::endGroupHeader,extraLevels); }
startItemListItem()173     void startItemListItem()
174     { forall(&OutputGenerator::startItemListItem); }
endItemListItem()175     void endItemListItem()
176     { forall(&OutputGenerator::endItemListItem); }
startMemberSections()177     void startMemberSections()
178     { forall(&OutputGenerator::startMemberSections); }
endMemberSections()179     void endMemberSections()
180     { forall(&OutputGenerator::endMemberSections); }
startHeaderSection()181     void startHeaderSection()
182     { forall(&OutputGenerator::startHeaderSection); }
endHeaderSection()183     void endHeaderSection()
184     { forall(&OutputGenerator::endHeaderSection); }
185     void startMemberHeader(const QCString &anchor, int typ = 2)
186     { forall(&OutputGenerator::startMemberHeader,anchor,typ); }
endMemberHeader()187     void endMemberHeader()
188     { forall(&OutputGenerator::endMemberHeader); }
startMemberSubtitle()189     void startMemberSubtitle()
190     { forall(&OutputGenerator::startMemberSubtitle); }
endMemberSubtitle()191     void endMemberSubtitle()
192     { forall(&OutputGenerator::endMemberSubtitle); }
startMemberDocList()193     void startMemberDocList()
194     { forall(&OutputGenerator::startMemberDocList); }
endMemberDocList()195     void endMemberDocList()
196     { forall(&OutputGenerator::endMemberDocList); }
startMemberList()197     void startMemberList()
198     { forall(&OutputGenerator::startMemberList); }
endMemberList()199     void endMemberList()
200     { forall(&OutputGenerator::endMemberList); }
startInlineHeader()201     void startInlineHeader()
202     { forall(&OutputGenerator::startInlineHeader); }
endInlineHeader()203     void endInlineHeader()
204     { forall(&OutputGenerator::endInlineHeader); }
startAnonTypeScope(int i1)205     void startAnonTypeScope(int i1)
206     { forall(&OutputGenerator::startAnonTypeScope,i1); }
endAnonTypeScope(int i1)207     void endAnonTypeScope(int i1)
208     { forall(&OutputGenerator::endAnonTypeScope,i1); }
209     void startMemberItem(const QCString &anchor,int i1,const QCString &id=QCString())
210     { forall(&OutputGenerator::startMemberItem,anchor,i1,id); }
endMemberItem()211     void endMemberItem()
212     { forall(&OutputGenerator::endMemberItem); }
startMemberTemplateParams()213     void startMemberTemplateParams()
214     { forall(&OutputGenerator::startMemberTemplateParams); }
endMemberTemplateParams(const QCString & anchor,const QCString & inheritId)215     void endMemberTemplateParams(const QCString &anchor,const QCString &inheritId)
216     { forall(&OutputGenerator::endMemberTemplateParams,anchor,inheritId); }
startCompoundTemplateParams()217     void startCompoundTemplateParams()
218     { forall(&OutputGenerator::startCompoundTemplateParams); }
endCompoundTemplateParams()219     void endCompoundTemplateParams()
220     { forall(&OutputGenerator::endCompoundTemplateParams); }
startMemberGroupHeader(bool b)221     void startMemberGroupHeader(bool b)
222     { forall(&OutputGenerator::startMemberGroupHeader,b); }
endMemberGroupHeader()223     void endMemberGroupHeader()
224     { forall(&OutputGenerator::endMemberGroupHeader); }
startMemberGroupDocs()225     void startMemberGroupDocs()
226     { forall(&OutputGenerator::startMemberGroupDocs); }
endMemberGroupDocs()227     void endMemberGroupDocs()
228     { forall(&OutputGenerator::endMemberGroupDocs); }
startMemberGroup()229     void startMemberGroup()
230     { forall(&OutputGenerator::startMemberGroup); }
endMemberGroup(bool last)231     void endMemberGroup(bool last)
232     { forall(&OutputGenerator::endMemberGroup,last); }
233     void insertMemberAlign(bool templ=FALSE)
234     { forall(&OutputGenerator::insertMemberAlign,templ); }
235     void insertMemberAlignLeft(int typ=0, bool templ=FALSE)
236     { forall(&OutputGenerator::insertMemberAlignLeft,typ,templ); }
writeRuler()237     void writeRuler()
238     { forall(&OutputGenerator::writeRuler); }
writeAnchor(const QCString & fileName,const QCString & name)239     void writeAnchor(const QCString &fileName,const QCString &name)
240     { forall(&OutputGenerator::writeAnchor,fileName,name); }
startCodeFragment(const QCString & style)241     void startCodeFragment(const QCString &style)
242     { forall(&OutputGenerator::startCodeFragment,style); }
endCodeFragment(const QCString & style)243     void endCodeFragment(const QCString &style)
244     { forall(&OutputGenerator::endCodeFragment,style); }
startCodeLine(bool hasLineNumbers)245     void startCodeLine(bool hasLineNumbers)
246     { forall(&OutputGenerator::startCodeLine,hasLineNumbers); }
endCodeLine()247     void endCodeLine()
248     { forall(&OutputGenerator::endCodeLine); }
writeLineNumber(const QCString & ref,const QCString & file,const QCString & anchor,int lineNumber,bool writeLineAnchor)249     void writeLineNumber(const QCString &ref,const QCString &file,const QCString &anchor,
250                          int lineNumber, bool writeLineAnchor)
251     { forall(&OutputGenerator::writeLineNumber,ref,file,anchor,lineNumber,writeLineAnchor); }
startEmphasis()252     void startEmphasis()
253     { forall(&OutputGenerator::startEmphasis); }
endEmphasis()254     void endEmphasis()
255     { forall(&OutputGenerator::endEmphasis); }
writeChar(char c)256     void writeChar(char c)
257     { forall(&OutputGenerator::writeChar,c); }
startMemberDoc(const QCString & clName,const QCString & memName,const QCString & anchor,const QCString & title,int memCount,int memTotal,bool showInline)258     void startMemberDoc(const QCString &clName,const QCString &memName,
259                         const QCString &anchor,const QCString &title,
260                         int memCount,int memTotal,bool showInline)
261     { forall(&OutputGenerator::startMemberDoc,clName,memName,anchor,title,memCount,memTotal,showInline); }
endMemberDoc(bool hasArgs)262     void endMemberDoc(bool hasArgs)
263     { forall(&OutputGenerator::endMemberDoc,hasArgs); }
startDoxyAnchor(const QCString & fName,const QCString & manName,const QCString & anchor,const QCString & name,const QCString & args)264     void startDoxyAnchor(const QCString &fName,const QCString &manName,
265                          const QCString &anchor, const QCString &name,
266                          const QCString &args)
267     { forall(&OutputGenerator::startDoxyAnchor,fName,manName,anchor,name,args); }
endDoxyAnchor(const QCString & fn,const QCString & anchor)268     void endDoxyAnchor(const QCString &fn,const QCString &anchor)
269     { forall(&OutputGenerator::endDoxyAnchor,fn,anchor); }
writeLatexSpacing()270     void writeLatexSpacing()
271     { forall(&OutputGenerator::writeLatexSpacing); }
startDescription()272     void startDescription()
273     { forall(&OutputGenerator::startDescription); }
endDescription()274     void endDescription()
275     { forall(&OutputGenerator::endDescription); }
startDescItem()276     void startDescItem()
277     { forall(&OutputGenerator::startDescItem); }
endDescItem()278     void endDescItem()
279     { forall(&OutputGenerator::endDescItem); }
startDescForItem()280     void startDescForItem()
281     { forall(&OutputGenerator::startDescForItem); }
endDescForItem()282     void endDescForItem()
283     { forall(&OutputGenerator::endDescForItem); }
startSubsection()284     void startSubsection()
285     { forall(&OutputGenerator::startSubsection); }
endSubsection()286     void endSubsection()
287     { forall(&OutputGenerator::endSubsection); }
startSubsubsection()288     void startSubsubsection()
289     { forall(&OutputGenerator::startSubsubsection); }
endSubsubsection()290     void endSubsubsection()
291     { forall(&OutputGenerator::endSubsubsection); }
startCenter()292     void startCenter()
293     { forall(&OutputGenerator::startCenter); }
endCenter()294     void endCenter()
295     { forall(&OutputGenerator::endCenter); }
startSmall()296     void startSmall()
297     { forall(&OutputGenerator::startSmall); }
endSmall()298     void endSmall()
299     { forall(&OutputGenerator::endSmall); }
300     void lineBreak(const QCString &style=QCString())
301     { forall(&OutputGenerator::lineBreak,style); }
startBold()302     void startBold()
303     { forall(&OutputGenerator::startBold); }
endBold()304     void endBold()
305     { forall(&OutputGenerator::endBold); }
306     void startMemberDescription(const QCString &anchor,const QCString &inheritId=QCString(), bool typ = false)
307     { forall(&OutputGenerator::startMemberDescription,anchor,inheritId, typ); }
endMemberDescription()308     void endMemberDescription()
309     { forall(&OutputGenerator::endMemberDescription); }
startMemberDeclaration()310     void startMemberDeclaration()
311     { forall(&OutputGenerator::startMemberDeclaration); }
endMemberDeclaration(const QCString & anchor,const QCString & inheritId)312     void endMemberDeclaration(const QCString &anchor,const QCString &inheritId)
313     { forall(&OutputGenerator::endMemberDeclaration,anchor,inheritId); }
writeInheritedSectionTitle(const QCString & id,const QCString & ref,const QCString & file,const QCString & anchor,const QCString & title,const QCString & name)314     void writeInheritedSectionTitle(const QCString &id,   const QCString &ref,
315                                     const QCString &file, const QCString &anchor,
316                                     const QCString &title,const QCString &name)
317     { forall(&OutputGenerator::writeInheritedSectionTitle,id,ref,
318                                     file,anchor,title,name); }
startExamples()319     void startExamples()
320     { forall(&OutputGenerator::startExamples); }
endExamples()321     void endExamples()
322     { forall(&OutputGenerator::endExamples); }
startParamList(ParamListTypes t,const QCString & title)323     void startParamList(ParamListTypes t,const QCString &title)
324     { forall(&OutputGenerator::startParamList,t,title); }
endParamList()325     void endParamList()
326     { forall(&OutputGenerator::endParamList); }
startIndent()327     void startIndent()
328     { forall(&OutputGenerator::startIndent); }
endIndent()329     void endIndent()
330     { forall(&OutputGenerator::endIndent); }
startSection(const QCString & lab,const QCString & title,SectionType t)331     void startSection(const QCString &lab,const QCString &title,SectionType t)
332     { forall(&OutputGenerator::startSection,lab,title,t); }
endSection(const QCString & lab,SectionType t)333     void endSection(const QCString &lab,SectionType t)
334     { forall(&OutputGenerator::endSection,lab,t); }
addIndexItem(const QCString & s1,const QCString & s2)335     void addIndexItem(const QCString &s1,const QCString &s2)
336     { forall(&OutputGenerator::addIndexItem,s1,s2); }
writeSynopsis()337     void writeSynopsis()
338     { forall(&OutputGenerator::writeSynopsis); }
startClassDiagram()339     void startClassDiagram()
340     { forall(&OutputGenerator::startClassDiagram); }
endClassDiagram(const ClassDiagram & d,const QCString & f,const QCString & n)341     void endClassDiagram(const ClassDiagram &d,const QCString &f,const QCString &n)
342     { forall(&OutputGenerator::endClassDiagram,d,f,n); }
startPageRef()343     void startPageRef()
344     { forall(&OutputGenerator::startPageRef); }
endPageRef(const QCString & c,const QCString & a)345     void endPageRef(const QCString &c,const QCString &a)
346     { forall(&OutputGenerator::endPageRef,c,a); }
startQuickIndices()347     void startQuickIndices()
348     { forall(&OutputGenerator::startQuickIndices); }
endQuickIndices()349     void endQuickIndices()
350     { forall(&OutputGenerator::endQuickIndices); }
writeSplitBar(const QCString & name)351     void writeSplitBar(const QCString &name)
352     { forall(&OutputGenerator::writeSplitBar,name); }
writeNavigationPath(const QCString & s)353     void writeNavigationPath(const QCString &s)
354     { forall(&OutputGenerator::writeNavigationPath,s); }
writeLogo()355     void writeLogo()
356     { forall(&OutputGenerator::writeLogo); }
writeQuickLinks(bool compact,HighlightedItem hli,const QCString & file)357     void writeQuickLinks(bool compact,HighlightedItem hli,const QCString &file)
358     { forall(&OutputGenerator::writeQuickLinks,compact,hli,file); }
writeSummaryLink(const QCString & file,const QCString & anchor,const QCString & title,bool first)359     void writeSummaryLink(const QCString &file,const QCString &anchor,const QCString &title,bool first)
360     { forall(&OutputGenerator::writeSummaryLink,file,anchor,title,first); }
startContents()361     void startContents()
362     { forall(&OutputGenerator::startContents); }
endContents()363     void endContents()
364     { forall(&OutputGenerator::endContents); }
startPageDoc(const QCString & pageTitle)365     void startPageDoc(const QCString &pageTitle)
366     { forall(&OutputGenerator::startPageDoc, pageTitle); }
endPageDoc()367     void endPageDoc()
368     { forall(&OutputGenerator::endPageDoc); }
writeNonBreakableSpace(int num)369     void writeNonBreakableSpace(int num)
370     { forall(&OutputGenerator::writeNonBreakableSpace,num); }
startDescTable(const QCString & title)371     void startDescTable(const QCString &title)
372     { forall(&OutputGenerator::startDescTable,title); }
endDescTable()373     void endDescTable()
374     { forall(&OutputGenerator::endDescTable); }
startDescTableRow()375     void startDescTableRow()
376     { forall(&OutputGenerator::startDescTableRow); }
endDescTableRow()377     void endDescTableRow()
378     { forall(&OutputGenerator::endDescTableRow); }
startDescTableTitle()379     void startDescTableTitle()
380     { forall(&OutputGenerator::startDescTableTitle); }
endDescTableTitle()381     void endDescTableTitle()
382     { forall(&OutputGenerator::endDescTableTitle); }
startDescTableData()383     void startDescTableData()
384     { forall(&OutputGenerator::startDescTableData); }
endDescTableData()385     void endDescTableData()
386     { forall(&OutputGenerator::endDescTableData); }
startDotGraph()387     void startDotGraph()
388     { forall(&OutputGenerator::startDotGraph); }
endDotGraph(DotClassGraph & g)389     void endDotGraph(DotClassGraph &g)
390     { forall(&OutputGenerator::endDotGraph,g); }
startInclDepGraph()391     void startInclDepGraph()
392     { forall(&OutputGenerator::startInclDepGraph); }
endInclDepGraph(DotInclDepGraph & g)393     void endInclDepGraph(DotInclDepGraph &g)
394     { forall(&OutputGenerator::endInclDepGraph,g); }
startCallGraph()395     void startCallGraph()
396     { forall(&OutputGenerator::startCallGraph); }
endCallGraph(DotCallGraph & g)397     void endCallGraph(DotCallGraph &g)
398     { forall(&OutputGenerator::endCallGraph,g); }
startDirDepGraph()399     void startDirDepGraph()
400     { forall(&OutputGenerator::startDirDepGraph); }
endDirDepGraph(DotDirDeps & g)401     void endDirDepGraph(DotDirDeps &g)
402     { forall(&OutputGenerator::endDirDepGraph,g); }
startGroupCollaboration()403     void startGroupCollaboration()
404     { forall(&OutputGenerator::startGroupCollaboration); }
endGroupCollaboration(DotGroupCollaboration & g)405     void endGroupCollaboration(DotGroupCollaboration &g)
406     { forall(&OutputGenerator::endGroupCollaboration,g); }
writeGraphicalHierarchy(DotGfxHierarchyTable & g)407     void writeGraphicalHierarchy(DotGfxHierarchyTable &g)
408     { forall(&OutputGenerator::writeGraphicalHierarchy,g); }
409     void startTextBlock(bool dense=FALSE)
410     { forall(&OutputGenerator::startTextBlock,dense); }
411     void endTextBlock(bool paraBreak=FALSE)
412     { forall(&OutputGenerator::endTextBlock,paraBreak); }
lastIndexPage()413     void lastIndexPage()
414     { forall(&OutputGenerator::lastIndexPage); }
startMemberDocPrefixItem()415     void startMemberDocPrefixItem()
416     { forall(&OutputGenerator::startMemberDocPrefixItem); }
endMemberDocPrefixItem()417     void endMemberDocPrefixItem()
418     { forall(&OutputGenerator::endMemberDocPrefixItem); }
startMemberDocName(bool align)419     void startMemberDocName(bool align)
420     { forall(&OutputGenerator::startMemberDocName,align); }
endMemberDocName()421     void endMemberDocName()
422     { forall(&OutputGenerator::endMemberDocName); }
startParameterType(bool first,const QCString & key)423     void startParameterType(bool first,const QCString &key)
424     { forall(&OutputGenerator::startParameterType,first,key); }
endParameterType()425     void endParameterType()
426     { forall(&OutputGenerator::endParameterType); }
startParameterName(bool one)427     void startParameterName(bool one)
428     { forall(&OutputGenerator::startParameterName,one); }
endParameterName(bool last,bool one,bool bracket)429     void endParameterName(bool last,bool one,bool bracket)
430     { forall(&OutputGenerator::endParameterName,last,one,bracket); }
startParameterList(bool openBracket)431     void startParameterList(bool openBracket)
432     { forall(&OutputGenerator::startParameterList,openBracket); }
endParameterList()433     void endParameterList()
434     { forall(&OutputGenerator::endParameterList); }
exceptionEntry(const QCString & prefix,bool closeBracket)435     void exceptionEntry(const QCString &prefix,bool closeBracket)
436     { forall(&OutputGenerator::exceptionEntry,prefix,closeBracket); }
437 
startConstraintList(const QCString & header)438     void startConstraintList(const QCString &header)
439     { forall(&OutputGenerator::startConstraintList,header); }
startConstraintParam()440     void startConstraintParam()
441     { forall(&OutputGenerator::startConstraintParam); }
endConstraintParam()442     void endConstraintParam()
443     { forall(&OutputGenerator::endConstraintParam); }
startConstraintType()444     void startConstraintType()
445     { forall(&OutputGenerator::startConstraintType); }
endConstraintType()446     void endConstraintType()
447     { forall(&OutputGenerator::endConstraintType); }
startConstraintDocs()448     void startConstraintDocs()
449     { forall(&OutputGenerator::startConstraintDocs); }
endConstraintDocs()450     void endConstraintDocs()
451     { forall(&OutputGenerator::endConstraintDocs); }
endConstraintList()452     void endConstraintList()
453     { forall(&OutputGenerator::endConstraintList); }
454 
startMemberDocSimple(bool b)455     void startMemberDocSimple(bool b)
456     { forall(&OutputGenerator::startMemberDocSimple,b); }
endMemberDocSimple(bool b)457     void endMemberDocSimple(bool b)
458     { forall(&OutputGenerator::endMemberDocSimple,b); }
startInlineMemberType()459     void startInlineMemberType()
460     { forall(&OutputGenerator::startInlineMemberType); }
endInlineMemberType()461     void endInlineMemberType()
462     { forall(&OutputGenerator::endInlineMemberType); }
startInlineMemberName()463     void startInlineMemberName()
464     { forall(&OutputGenerator::startInlineMemberName); }
endInlineMemberName()465     void endInlineMemberName()
466     { forall(&OutputGenerator::endInlineMemberName); }
startInlineMemberDoc()467     void startInlineMemberDoc()
468     { forall(&OutputGenerator::startInlineMemberDoc); }
endInlineMemberDoc()469     void endInlineMemberDoc()
470     { forall(&OutputGenerator::endInlineMemberDoc); }
471 
startLabels()472     void startLabels()
473     { forall(&OutputGenerator::startLabels); }
writeLabel(const QCString & l,bool isLast)474     void writeLabel(const QCString &l,bool isLast)
475     { forall(&OutputGenerator::writeLabel,l,isLast); }
endLabels()476     void endLabels()
477     { forall(&OutputGenerator::endLabels); }
478 
cleanup()479     void cleanup()
480     { forall(&OutputGenerator::cleanup); }
481 
startFontClass(const QCString & c)482     void startFontClass(const QCString &c)
483     { forall(&OutputGenerator::startFontClass,c); }
endFontClass()484     void endFontClass()
485     { forall(&OutputGenerator::endFontClass); }
writeCodeAnchor(const QCString & name)486     void writeCodeAnchor(const QCString &name)
487     { forall(&OutputGenerator::writeCodeAnchor,name); }
setCurrentDoc(const Definition * context,const QCString & anchor,bool isSourceFile)488     void setCurrentDoc(const Definition *context,const QCString &anchor,bool isSourceFile)
489     { forall(&OutputGenerator::setCurrentDoc,context,anchor,isSourceFile); }
addWord(const QCString & word,bool hiPriority)490     void addWord(const QCString &word,bool hiPriority)
491     { forall(&OutputGenerator::addWord,word,hiPriority); }
492 
startPlainFile(const QCString & name)493     void startPlainFile(const QCString &name)
494     { forall(&OutputGenerator::startPlainFile,name); }
endPlainFile()495     void endPlainFile()
496     { forall(&OutputGenerator::endPlainFile); }
497 
498   private:
499     void debug();
500     void clear();
501     void newId();
502 
503     // For each output format that is enabled (OutputGenerator::isEnabled()) we forward
504     // the method call.
505     // We use C++11 variadic templates and perfect forwarding to implement forall() generically,
506     // and split the types of the methods from the arguments passed to allow implicit conversions.
507     template<typename T,class... Ts,class... As>
forall(void (T::* methodPtr)(Ts...),As &&...args)508     void forall(void (T::*methodPtr)(Ts...),As&&... args)
509     {
510       for (const auto &og : m_outputs)
511       {
512         if (og->isEnabled()) (og.get()->*methodPtr)(std::forward<As>(args)...);
513       }
514     }
515 
516     std::vector< std::unique_ptr<OutputGenerator> > m_outputs;
517     int m_id;
518 
519 };
520 
521 #endif
522