% +---------------------------------------- % | new commands needed in the new mechamism % | 03.08.1995 Berlin Lutz Kettner % | $Revision$ % | $Date$ % +---------------------------------------- { \catcode`\$=12 \def\cs #1$#2${\gdef#1{#2}}% \cs\CCrevision$Revision$% \cs\CCdate$Date$% } %\tracingmacros=1 % +-------------------------------------------------------------------------- % | A handy macro to define macros for RCS entries in a TeX file % +-------------------------------------------------------------------------- % #1 the macro name for the RCS entry % #2 the RCS entry \newcommand{\RCSdef}{\begingroup\catcode`\$=12 \RCSdefSet} { \catcode`\$=12 \gdef\RCSdefSet #1$#2${\gdef#1{#2}\endgroup}% } % +-------------------------------------------------------------------------- % | Customization tags for the style: here are the defaults defined. % +-------------------------------------------------------------------------- \newcommand{\CCtagChapterAuthor}{\CCtrue} % true -> the author is shown. \newcommand{\CCtagReplacePrefix}{\CCfalse} % true -> prefixes are replaced. \newcommand{\CCtagReplaceInclude}{\CCfalse} % true -> include file prefixes % are replaced when % \CCtagReplacePrefix is also true. \newcommand{\CCtagRmTrailingConst}{\CCtrue} % true -> trailing const declarat. % for member fct's are removed. \newcommand{\CCtagRmEigenClassName}{\CCtrue} % true -> removes own class name % when it appears in parameter % list. \newcommand{\CCtagRmConstRefPair}{\CCtrue} % true -> removes const & pairs % when it appearing in parameters % and return values. % +-------------------------------------------------------------------------- % | Dimensions (from the LEDA Manual): % +-------------------------------------------------------------------------- %\hoffset=-0.5truemm \voffset=0.5truecm %\hsize=16truecm \vsize=23.5truecm %\hsize=13.3truecm \vsize=19.8truecm \baselineskip 14pt \spaceskip .4em plus .25em minus .25em \xspaceskip .65em \parskip 11pt plus 1pt minus 1pt \parindent 0pt % +-------------------------------------------------------------------------- % | New Dimensions (for the CGAL Manual): % | Especially to format all multi column declarations. % | % | The dimensions \CCfirst and \CCsecond are set to the appropriate % | values. Afterwards, the \CCinitWidths does the rest. % +-------------------------------------------------------------------------- % redefine this macro to be \CCtrue to switch the alternative % three column formatting on. \def\CCalternateThreeColumn{\CCtrue} \newdimen\CCWindent \newdimen\CCWfirst \newdimen\CCWfirstlong \newdimen\CCWsecond \newdimen\CCWsecondlong \newdimen\CCWcomment \newdimen\CCWbetween \newdimen\CCWparam \newdimen\CCWparamindent \newdimen\CCWfunctionfirst \newdimen\CCWfunctionsecond \newdimen\CCWconstructorfirst \newdimen\CCWconstructorsecond % init them % --------- \CCWindent = 0pt \CCWbetween = 0.5cm \CCWparamindent = 1.2cm \CCWfunctionfirst = 2.5cm \CCWfunctionsecond = 4.5cm \CCWconstructorfirst = -1\CCWbetween \CCWconstructorsecond = 2.5cm \def\CCinitWidths{% \CCWfirstlong = \textwidth \advance\CCWfirstlong -\CCWindent \CCWsecondlong = \CCWfirstlong \advance\CCWsecondlong -\CCWfirst \advance\CCWsecondlong -\CCWbetween \CCWcomment = \CCWsecondlong \advance\CCWcomment -\CCWsecond \advance\CCWcomment -\CCWbetween \CCWparam = \CCWfirst \advance\CCWparam \CCWbetween \advance\CCWparam \CCWparamindent } \CCinitWidths % define macros for the vertical structuring % ------------------------------------------ \def\CCtopskip{\smallskip} \def\CCreturnskip{\par\hspace*{\CCWindent}\hspace*{\CCWfirst}% \hspace*{\CCWbetween}} \def\CCmiddleskip{\par\hspace*{1cm}\hfill} % aligns commentblock to the right \def\CCbottomskip{\par\smallskip} \def\CCbottombigskip{\par\bigskip} % +-------------------------------------------------------------------------- % | Original LEDA Manual macros (shortcuts): % | Several new shortcuts for CGAL % | % | \CC, \gcc, \nat, \real, \boxit % | \leda, \cgal, \protocgal, \plageo % +-------------------------------------------------------------------------- % selfmade \def\CC{C\raise.08ex\hbox{\tt ++}} \def\gcc{g\hbox{\tt ++}} \def\nat{\hbox{\rm I\kern-0.045em N}} \def\real{\hbox{\rm I\kern-0.035em R}} % \def\boxit#1{\vbox{\hrule\hbox{\vrule\kern3pt\vbox{#1}\kern3pt\vrule}\hrule}} % (older) AMS-TeX style \def\R{\mbox{$\mathbb R$}} %% zusammen mit usepackage{amssymb} \def\N{\mbox{$\mathbb N$}} %% zusammen mit usepackage{amssymb} \def\Z{\mbox{$\mathbb Z$}} %% zusammen mit usepackage{amssymb} \def\Q{\mbox{$\mathbb Q$}} %% zusammen mit usepackage{amssymb} \def\E{\mbox{$\mathbb E$}} %% zusammen mit usepackage{amssymb} % actual AMS-TeX style (according to Kopka LaTeX Ergaenzungsband S.92) %\def\R{\mbox{$\Bbb{R}$}} %% zusammen mit usepackage{amssymb} %\def\N{\mbox{$\Bbb{N}$}} %% zusammen mit usepackage{amssymb} %\def\Z{\mbox{$\Bbb{Z}$}} %% zusammen mit usepackage{amssymb} %\def\Q{\mbox{$\Bbb{Q}$}} %% zusammen mit usepackage{amssymb} %\def\E{\mbox{$\Bbb{E}$}} %% zusammen mit usepackage{amssymb} \newcommand{\leda}{{\sc Leda}} \newcommand{\cgal}{{\sc Cgal}} \newcommand{\protocgal}{{\sc C++gal}} \newcommand{\plageo}{{\sc Plageo}} % +-------------------------------------------------------------------------- % | Support macros for HTML manual generation: % | % | \begin{TexOnly} ..., \begin{HtmlOnly} ..., \LatexHtml{}{} % +-------------------------------------------------------------------------- \gdef\HTMLcatcode {% \CCcatcode \catcode`\{=12 \catcode`\}=12 \catcode`\\=12 } \gdef\HTMLdefcatcode {% \catcode`\|=0 \catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12 \catcode`\\=12 } \def\LatexHtml #1#2{#1} \def\Anchor #1#2{#2} \newenvironment{TexOnly}{}{} \newenvironment{HtmlOnly}{\begingroup\HTMLcatcode \ParseHtmlOnlyBody}{ \endgroup} % Take care: catcodes changes a lot here!! \begingroup \HTMLdefcatcode |gdef|ParseHtmlOnlyBody #1\end{HtmlOnly}[% |csname endHtmlOnly|endcsname|@checkend[HtmlOnly]% |expandafter|endgroup|if@endpe|@doendpe|fi |if@ignore|global|@ignorefalse|ignorespaces|fi ] |endgroup % +-------------------------------------------------------------------------- % | Structuring macros (similar to LEDA Manual): % | % | \CCsection, \definition, \constants, \types, \creation, \operations, % | \implementation, \example, \precond, \postcond, \chapterauthor % +-------------------------------------------------------------------------- \newcommand{\CCchapterAuthor}[1]{% \ifnum\CCtagChapterAuthor=\CCtrue \noindent\setlength{\unitlength}{1mm}% \begin{picture}(0,0)% \put(0,11){{\em #1}}% \end{picture}% \fi} \def\CCsection #1{% \section[#1 (\protect\CCprintSingleTokenSemi \pureclassname;)]{#1 (\classname)} \label{#1}} \def\CCsubsection #1{% \subsection[#1 (\protect\CCprintSingleToken \pureclassname\end)]{#1 (\classname)} \label{#1}} \def\cgalheading #1{\bigskip\pagebreak[1] {\bf #1} \par\nopagebreak } \def\cgalcommentheading #1{\par{\it #1}: } \def\definition {\cgalheading{Definition}} \def\synopsis {\cgalheading{Synopsis}} \def\parameters {\cgalheading{Parameters}} \def\constants {\cgalheading{Constants}} \def\types {\cgalheading{Types}} \def\creation {\cgalheading{Creation} } \def\operations {\cgalheading{Operations}} \def\implementation {\cgalheading{Implementation}} \def\example {\cgalheading{Example}} \def\precond {\cgalcommentheading{Precondition}} \def\postcond {\cgalcommentheading{Postcondition}} % +-------------------------------------------------------------------------- % | C++ declarations for different C++ language elements: % | % | \begin{class}, \begin{classtemplate}, \end... % | \creationvariable, \threecolumns, \constructorcolumn, \constructor, % | \method, \function % | \CCstyle % +-------------------------------------------------------------------------- \newenvironment{class}{% \begingroup\CCcatcode \classX% }{ \gdef\pureclassname{}% \gdef\puretemplatename{}% \gdef\classname{}% \gdef\classtemplatename{}% \gdef\purevar{}% \gdef\var{}% } \def\classX #1{% \endgroup \classXX #1<\end} \def\classXX #1<#2\end{% \def\xparams{#2}\ifx\xparams\empty \classXXX{#1}% \else \errmessage{Template parameters are not allowed in a normal class. Use \begin{classtemplate} instead}>% \classXXX{#1}% \fi} \def\classXXX #1{% \gdef\pureclassname{#1}% \gdef\puretemplatename{#1}% \gdef\pureparameters{}% \gdef\classname{\hbox{{\CCfont \CCprintTokens #1\end\CCendfont}}}% \gdef\classtemplatename{\hbox{{\CCfont \CCprintTokens #1\end\CCendfont}}}% } \newenvironment{classtemplate}{% \begingroup\CCcatcode \classtemplateX% }{ \gdef\pureclassname{}% \gdef\puretemplatename{}% \gdef\pureparameters{}% \gdef\classname{}% \gdef\classtemplatename{}% \gdef\purevar{}% \gdef\var{}% } \def\classtemplateX #1{% \endgroup \classtemplateXX #1<\end} \def\classtemplateXX #1<#2\end{% \def\xparams{#2}\ifx\xparams\empty \errmessage{Template parameters missed for class template}>% \classtemplateXXX{#1}<\end% \else \classtemplateXXX{#1}<#2\end% \fi} \def\classtemplateXXX #1#2<\end{% \gdef\pureclassname{#1}% \gdef\puretemplatename{#1#2}% \gdef\pureparameters{#2}% \gdef\classname{\hbox{{\CCfont \CCprintTokens #1\end\CCendfont}}}% \gdef\classtemplatename{\hbox{{\CCfont \CCprintTokens #1#2\end\CCendfont}}}% } \def\creationvariable {% \begingroup\CCcatcode\creationvariableX} \def\creationvariableX #1{% \gdef\var{{\CCfont\CCprintTokens #1\end\CCendfont}} \gdef\purevar{#1} \endgroup} \newcommand{\CCsetTwoOfThreeColumns}[2]{% \global\CCWfunctionfirst=#1 \global\CCWfunctionsecond=#2 } \newcommand{\threecolumns}[2]{% \CCsetTwoOfThreeColumns{#1}{#2} } \newdimen\CCWtmp \newcommand{\CCsetThreeColumns}[3]{% \isEmpty{#3}\ifnum\CCbool=\CCtrue \setbox0=\hbox{\mbox{\CCstyle{#1}}}\setbox1=\hbox{\mbox{\CCstyle{#2}}}% \CCsetTwoOfThreeColumns{\wd0}{\wd1}% \else\isEmpty{#2}\ifnum\CCbool=\CCtrue \setbox0=\hbox{\mbox{\CCstyle{#1}}}\setbox1=\hbox{\mbox{#3}}% \CCWtmp=\textwidth \advance\CCWtmp -\wd0 \advance\CCWtmp -\wd1 \advance\CCWtmp -\CCWindent \advance\CCWtmp -\CCWbetween \advance\CCWtmp -\CCWbetween \CCsetTwoOfThreeColumns{\wd0}{\CCWtmp}% \else\isEmpty{#1}\ifnum\CCbool=\CCtrue \setbox0=\hbox{\mbox{\CCstyle{#2}}}\setbox1=\hbox{\mbox{#3}}% \CCWtmp=\textwidth \advance\CCWtmp -\wd0 \advance\CCWtmp -\wd1 \advance\CCWtmp -\CCWindent \advance\CCWtmp -\CCWbetween \advance\CCWtmp -\CCWbetween \CCsetTwoOfThreeColumns{\CCWtmp}{\wd0}% \else \errmessage{\CCsetThreeColumns expects one empty parameter. Go ahead, the old settings will remain active.}% \fi\fi\fi } \newcommand{\CCsetOneOfTwoColumns}[1]{% \global\CCWconstructorsecond=#1 } \def\constructorcolumn #1{% \CCsetOneOfTwoColumns{#1} } \newcommand{\CCsetTwoColumns}[2]{% \isEmpty{#2}\ifnum\CCbool=\CCtrue \setbox0=\hbox{\mbox{\CCstyle{#1}}}% \CCsetOneOfTwoColumns{\wd0}% \else\isEmpty{#1}\ifnum\CCbool=\CCtrue \setbox0=\hbox{\mbox{#2}}% \CCWtmp=\textwidth \advance\CCWtmp -\wd0 \advance\CCWtmp -\CCWindent \advance\CCWtmp -\CCWbetween % \CCWconstructorfirst = -1\CCWbetween \CCsetOneOfTwoColumns{\CCWtmp}% \else \errmessage{\CCsetTwoColumns expects one empty parameter. Go ahead, the old settings will remain active.}% \fi\fi } \def\constructor {% \begingroup\CCcatcode\constructorX} \def\constructorX #1{% \endgroup \constructorXX{#1}} \long\def\constructorXX #1#2{% \constructorcall {#2}#1\end} % \CCglobalContinuation and \CCglobalDecl is used to fiddle an empty % comment behind the other parameters of a declaration without parsing % these parameters as arguments (the catcodes are not set yet). % Compare the normal and the global version of a declaration macro. \gdef\CCglobalDecl{\CCfalse} \gdef\CCglobalContinuation #1{% \ifnum\CCglobalDecl=\CCtrue \def\CClocalCont{#1{}} \let\continuation=\CClocalCont \else \def\CClocalCont{#1} \let\continuation=\CClocalCont \fi \gdef\CCglobalDecl{\CCfalse} \continuation } % Methods and functions can contain the active character or the comment % character % of TeX's own character set. Therefore, we assign new % \catcode values to them and parse the first argument after that, close % the group and parse the second argument with the \CCcommentX macro. \def\method {% \begingroup\CCcatcode \functionX{0}} \def\function {% \begingroup\CCcatcode \functionX{1}} \def\functionX #1#2{% \endgroup \CCglobalContinuation{\CCcomment{#1}{#2}}} \long\def\CCcomment #1#2#3{% \functioncall{#1}{#3}#2;\end} % A three! parameter macro to format template functions % o The 1st parameter contains the template parameters. % o The 2nd parameter contains the function declaration. % o The 3rd parameter contains the comment. \def\functiontemplate #1{\function} % typedef's, variables, and constants are like functions without parameters. \def\variable {% \begingroup\CCcatcode \variableX} \def\variableX #1{% \endgroup \CCglobalContinuation{\variableXX{#1}}} \long\def\variableXX #1#2{% \CCvariableDeclaration{#2}#1;\end} \def\typedef {\variable} \def\nestedtype {% \begingroup\CCcatcode \nestedtypeX} \def\nestedtypeX #1{% \endgroup \CCglobalContinuation{% \nestedtypeXX{#1}}} \long\def\nestedtypeXX #1#2{% \CCWfirst =\CCWconstructorfirst \CCWsecond =\CCWconstructorsecond \CCinitWidths \setbox\returntypebox=\hbox{}% \setbox\callnamebox=\hbox{\classtemplatename \CCfont\CCprintTokens ::\end}% \setbox\functioncallbox=\hbox{\unhcopy\callnamebox \ \CCfont\CCprintTokens #1\end} \CClayoutThreeColumns{}{}{}{#2}% } % Enum's are formatted like constructors. There is exact one matching % pair of braces in the declaration. \def\enum {% \begingroup\CCcatcode \catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12 \enumX} \begingroup \catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12 \gdef\enumX {#1{#2}#3}[% \endgroup \CCglobalContinuation[\enumXX[#1\{#2\}#3]]] \endgroup \long\def\enumXX #1#2{% \CCenumDeclaration {#2}#1\end} % a struct is formatted like an enum (needs the parantheses parsing) \def\struct {% \begingroup\CCcatcode \catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12 \enumX} % A \declaration accepts one parameter. The style will ignore it, while % the checker tests if it exists one to one in the C++ code. % It is intended for declarations that are somehow implied by the % surrounded text, but should not be explicitly visible. \def\declaration {\begingroup\CCcatcode\declarationX} \def\declarationX #1{\endgroup} % A \hidden macro can be prepended to each macro with two parameters. % It will remove the macro and its parameters from the manual. % Again, the checker tests the macro as usual. \def\hidden #1{\begingroup\CCcatcode\hiddenX} \def\hiddenX #1{\endgroup\hiddenXX} \long\def\hiddenXX #1{} % If these non visible parts of the code should be made visible once, % the following macro switches it on. \def\CCmakeAllVisible{% \gdef\declaration{\CCstyle}% \gdef\hidden{}% } % An \unchecked macro expands to nothing. It is used by the checker tool % where it denotes that the following declarations is not subject of any % check. \def\unchecked{} % All simple macros work also at the global level. The following % `global' versions are only shortcuts to omit the comment parameter, % so that global declarations are always commented inbetween and not in % the last column. Note hat declarations always can extend in the last % column, so the previous column has not to be reshaped. \def\globalfunction {\gdef\CCglobalDecl{\CCtrue}\function} \def\globalfunctiontemplate {\gdef\CCglobalDecl{\CCtrue}\functiontemplate} \def\globalenum {\gdef\CCglobalDecl{\CCtrue}\enum} \def\globalstruct {\gdef\CCglobalDecl{\CCtrue}\struct} \def\globalvariable {\gdef\CCglobalDecl{\CCtrue}\variable} \def\globaltypedef {\gdef\CCglobalDecl{\CCtrue}\typedef} % Print one parameter in C++ style (including spaces). \def\CCstyle {% \begingroup\CCcatcode\CCstyleX} \def\CCstyleX #1{% {\CCfont \CCprintTokens #1\end\CCendfont}\endgroup} % print CC programs. Encapsulate cprog with better spacing at the top % and bottom \newenvironment{CCprog}{% \smallskip\begin{cprog}}{% \end{cprog}\smallskip} % +-------------------------------------------------------------------------- % | Formatting styles: % | % | The style of the C++ formatting can be customized by redefining the % | following macros. % +-------------------------------------------------------------------------- \gdef\CCfont{\it} % font or style changing command in which all C++ % tokens will be typeset, including the variable names. \gdef\CCendfont{\/} % will be used after a C++ text. For slanted fonts, % here should stay \/ macro. The C++ code will be % grouped, so this macros has not to restore the old % font. % The special characters in typical C++ declarations: \gdef\CCopenangle {\CCendfont {\tt <}} \gdef\CCcloseangle {\CCendfont {\tt >}} \gdef\CCampersand {\CCendfont {\tt \&}} \gdef\CCunderscore {\raisebox{-.05ex}{\_}\kern.05em} % \gdef\CCunderscore {\kern.05em\raisebox{.5ex}{\_}\kern-.1em} \gdef\CChat {{\large $\;\,\hat{}\,\,$}} \gdef\CCtilde {{\lower.3ex \hbox{\large$\,\tilde{}\,$}}} \gdef\CChash {{\rm \#}} % The sign for an empty parameter (i.e. of the type of the current class). \gdef\CCemptyParameter {$\diamondsuit$} % Set the catcodes according to the C++ character set (including operators). \gdef\CCcatcode {% \catcode`\~=12 \catcode`\_=12 \catcode`\^=12 \catcode`\#=12 \catcode`\%=12 } % +-------------------------------------------------------------------------- % | Predicates: % | % | isEmpty, isLetter, isUnderscore, hasLeadingSpace, isTemplate, % | isLastAlpha, isOperator, isParenthesisOperator, isConversionOperator % | % | All predicates uses pattern matching of TeX. The original predicate uses % | a single parameter that should be in braces like in LaTeX. Internally, % | they use a second, auxiliary macro with pattern matching where the % | parameter has to be terminated by an \end token. % | % | Result is stored in the counter \CCbool. \CCfalse, \CCtrue are also % | counters that are used in the \ifnum statement to test the result. % +-------------------------------------------------------------------------- % The counter \CCbool contains the result of a couple of predicates \newcount\CCbool % either 0 for false or 1 for true. \newcount\CCfalse \CCfalse=0 % This must be constant 0 !!! \newcount\CCtrue \CCtrue=1 % This must be constant 1 !!! % A small macro to invert \CCbool \def\CCinvert {% \ifnum\CCbool=\CCfalse \CCbool=\CCtrue \else\CCbool=\CCfalse \fi} % This macro test wheather its argument is empty or contains only spaces. \def\isEmpty #1{% \isEmptyX #1;\end} \def\isEmptyX #1#2\end{% \def\xparams{#2}\ifx\xparams\empty \CCbool=\CCtrue \else \CCbool=\CCfalse \fi} % This macro test wheather its argument starts (after leading spaces) % with a valid C++ letter. \def\isLetter #1{% \def\qparams{#1}\ifx\qparams\empty\CCbool=\CCfalse \else\isLetterX #1\end\fi} \def\isLetterX #1#2\end{% \CCbool=\CCfalse \ifx#1\_\CCbool=\CCtrue\else \ifcat#1A\CCbool=\CCtrue \else\ifnum`#1>`/\ifnum`#1<`:\CCbool=\CCtrue \fi\fi \if#1_\CCbool=\CCtrue \fi \fi\fi} % Test for a leading underscore, either _ with changed catcode, or \_ \def\isUnderscore #1{% \def\qparams{#1}\ifx\qparams\empty\CCbool=\CCfalse \else\isUnderscoreX #1\end\fi} \def\isUnderscoreX #1#2\end{% \CCbool=\CCfalse \ifx#1\_\CCbool=\CCtrue\else \if#1_\CCbool=\CCtrue \fi \fi} % Test for a leading underscore, either _ with changed catcode, or \_, % or the / character. Used to validate the character after a prefix. \def\isPrefixFollowChar #1{% \def\qparams{#1}\ifx\qparams\empty\CCbool=\CCfalse \else\isPrefixFollowCharX #1\end\fi} \def\isPrefixFollowCharX #1#2\end{% \CCbool=\CCfalse \ifx#1\_\CCbool=\CCtrue\else \if#1_\CCbool=\CCtrue \else \if#1/\CCbool=\CCtrue\fi \fi \fi} % These macros allow the characterwise parsing of an argument, where normally % the spaces are ignored. % Here, the first macro can be applied to the rest of the argument and % will return \CCtrue in the \CCbool iff the rest starts with a space. % The second macro will produce a space "\ " iff the rest starts with a space. % The space of the rest will be skipped automatically in the next round. \def\hasLeadingSpace #1{% \def\qparams{#1}\ifx\qparams\empty\CCbool=\CCfalse \else\compareSpace{#1}#1\end\fi} \def\compareSpace #1#2#3\end{% \def\xxparams{#1}\def\xxxparams{#2#3}\ifx\xxparams\xxxparams\CCbool=\CCfalse \else\CCbool=\CCtrue \fi} \def\testAndCopySpace #1{% \def\qparams{#1}\ifx\qparams\empty\else\compareAndCopySpace{#1}#1\end\fi} \def\compareAndCopySpace #1#2#3\end{% \def\xxparams{#1}\def\xxxparams{#2#3}\ifx\xxparams\xxxparams\else\ \fi} % This macro gets a complete C++ declaration and decides weather % it starts with a template declaration or not. \def\isTemplate #1{% \isTemplateX #1template\end} % Note: these macros has to test for characters directly following % the template keyword, because it is allowed as an identifier substring. \def\isTemplateX #1template#2\end{% \isEmpty{#2}\ifnum\CCbool=\CCtrue \CCbool=\CCfalse \else\hasLeadingSpace{#2}\ifnum\CCbool=\CCfalse \isLetter{#2}\CCinvert \fi \fi \ifnum\CCbool=\CCtrue \isEmpty{#1}% \fi} % This macro gets a complete C++ declaration and decides weather % it is an operator declaration or not. \def\isOperator #1{% \isOperatorX #1operator\end} % Note: these macros has to test for characters directly surrounding % the operator keyword, because it is allowed as an identifier substring. \def\isOperatorX #1operator#2\end{% \isEmpty{#2}\ifnum\CCbool=\CCtrue \CCbool=\CCfalse \else\hasLeadingSpace{#2}\ifnum\CCbool=\CCfalse \isLetter{#2}\CCinvert \fi \fi \ifnum\CCbool=\CCtrue \isEmpty{#1}\ifnum\CCbool=\CCfalse \isLastAlphaX #1\end \CCinvert \fi \fi} % Check the last character in the parameter. If it is a character (or _) % return \CCtrue, else return \CCfalse. \def\isLastAlpha #1{% \isEmpty{#1}\ifnum\CCbool=\CCtrue\CCinvert \else\isLastAlphaX #1\end \fi} \def\isLastAlphaX #1#2\end{% \def\xbody{\isLastAlphaX #2\end}% \isLetterX #1\end \def\qqparams{#2}\ifx\qqparams\empty\let\xnext=\relax \else\isEmpty{#2}\ifnum\CCbool=\CCtrue \CCinvert \let\xnext=\relax \else \let\xnext=\xbody \fi \fi \xnext} % This macro gets a complete C++ declaration for an operator and has to % decide weather it is the parenthesis () operator declaration or not. \def\isParenthesisOperator #1{% \isParenthesisOperatorX #1 ()\end} \def\isParenthesisOperatorX #1operator#2(#3)#4(#5)#6\end{% % if and only if #6 is non empty, we have the () operator. \isEmpty{#6}\CCinvert} % This macro gets a complete C++ declaration for an operator and has to % decide weather it is the conversion operator declaration or not. \def\isConversionOperator #1{% \isConversionOperatorX #1\end} \def\isConversionOperatorX #1operator#2\end{% % if and only if #1 is empty, we have the conversion operator. \isEmpty{#1}} % +-------------------------------------------------------------------------- % | Toplevel declaration formatting: % | % | Here, constructors, methods, and functions are separated in there % | building blocks: the return type, their name, and the parameter % | list. An operator declaration will be detected. % +-------------------------------------------------------------------------- % This box contains the formatting result. Its width influences the % column layout for longish declarations. \newbox\functioncallbox \newbox\returntypebox % contains the return type \newbox\functionnamebox % contains the function name \newbox\callnamebox % contains the fct. name incl. variable for methods \newbox\trailingconstbox % contains the trailing const after member functions % or is empty according to \CCtagRmTrailingConst % Formats a constructor call. % o The 1st parameter contains the comment text (maybe empty). % o The 2st parameter contains the name of the constructor % o The 3rd parameter contains the parameter list (maybe empty). % o The 4th parameter contains the optional const specifier for methods. % The declaration has to be terminated with "\end". \def\constructorcall #1#2(#3)#4\end {% % check for template function \isTemplate{#2}\ifnum\CCbool=\CCtrue \CCseparateTemplate{\CCtemplateLine}{% \constructorcall{#1}}#2(#3)#4\end \else \CCWfirst =\CCWconstructorfirst \CCWsecond =\CCWconstructorsecond \CCinitWidths \setbox\callnamebox=\hbox{% \classtemplatename\ \ \CCfont\var}% \setbox\functioncallbox=\hbox{\unhcopy\callnamebox \isEmpty{#3}\ifnum\CCbool=\CCfalse ( \CCprintParamList{#3)#4})% \fi ;}% \setbox\returntypebox=\hbox{}% \CClayoutThreeColumns{(}{#3)#4}{)}{#1}% \fi } % Formats a method or a function call. % o The 1st parameter contains a 0 for a method call, a 1 for a function. % o The 2nd parameter contains the comment text (maybe empty). % o The 3rd parameter contains the beginning of the type declaration. % o The 4th parameter contains the rest of the type and the function name. % o The 5th parameter contains the parameter list (maybe empty). % o The 6th parameter contains the optional const specifier for methods. % The declaration has to be terminated with ";;\end" where the first ";" % has to be from the original call notation. The 7th parameter is there % to check for this ";". \def\functioncall #1#2#3 #4(#5)#6;#7\end{% \CCWfirst =\CCWfunctionfirst \CCWsecond =\CCWfunctionsecond \CCinitWidths \def\xparam{#7}\ifx\xparam\empty \errmessage{Missing ";" at the end of the declaration. A method or function declaration has to end with a ";". Go ahead, I've inserted one}% \fi % check for template function \isTemplate{#3 #4}\ifnum\CCbool=\CCtrue \CCseparateTemplate{\CCtemplateLine}{% \functioncall{#1}{#2}}#3 #4(#5)#6;#7\end \else \def\CCextendedFormat{\ }% Switches ext. format OFF. \CCseparateTrailingConst #6)\end \isOperator{#3 #4(#5)#6}\ifnum\CCbool=\CCtrue \isConversionOperator{#3 #4(#5)#6} \ifnum\CCbool=\CCtrue \CCprintConversionOperator #3 #4(#5)#6\end \else \CCseparateOperator #3 #4\end% \isParenthesisOperator{#3 #4(#5)#6}% \ifnum\CCbool=\CCtrue \setbox\functioncallbox=\hbox{{\CCfont \CCprintParOperator #1#3 #4(#5)#6\end}} \else \setbox\functioncallbox=\hbox{{\CCfont \CCprintOperator #1#3 #4(#5)#6\end}} \fi \fi \else \CCseparateFunction{}#3 #4::\end% \setbox\functioncallbox=\hbox{{\CCfont \ifnum#1=0 \var.\fi \unhcopy\functionnamebox(% \isEmpty{#5}\ifnum\CCbool=\CCfalse \ \CCprintParamList{#5)#6}% \fi)\unhcopy\trailingconstbox}} \fi \setbox\callnamebox=\hbox{{\CCfont \ifnum#1=0 \var.\fi \unhbox\functionnamebox}}% \CClayoutThreeColumns{(}{#5)#6}{)\unhbox \trailingconstbox}{#2}% \fi % from \isTemplate } \def\CCextendedFormat{\ }% Default: Extended Format switched OFF. % Formats a variable, typedef or constant. % o The 1st parameter contains the comment text (maybe empty). % o The 2nd parameter contains the beginning of the type declaration. % o The 3rd parameter contains the rest of the type and the function name. % The declaration has to be terminated with ";;\end" where the first ";" % has to be from the original call notation. The 4th parameter is there % to check for this ";". \def\CCvariableDeclaration #1#2 #3;#4\end{% \CCWfirst =\CCWfunctionfirst \CCWsecond =\CCWfunctionsecond \CCinitWidths \def\xparam{#4}\ifx\xparam\empty \errmessage{Missing ";" at the end of the declaration. A variable, typedef, or constant declaration has to end with a ";". Go ahead, I've inserted one}% \fi \CCseparateVariable #2 #3=\end% \setbox\functioncallbox=\hbox{{\CCfont \unhcopy\functionnamebox;}} \setbox\callnamebox=\hbox{{\CCfont \unhbox\functionnamebox}}% \CClayoutThreeColumns{}{}{}{#1}% } \def\CCseparateVariable #1 #2=#3\end{% \CCseparateFunction{}#1 #2::\end% \def\xparam{#3}\ifx\xparam\empty \else \CCseparateVariableX #3\end \fi } \def\CCseparateVariableX #1=\end{% {\setbox0=\hbox{\unhbox\functionnamebox\ =#1}% \global\setbox\functionnamebox=\hbox{\unhbox0}}% } % Formats a enum declaration. % o The 1st parameter contains the comment text (maybe empty). % o The 2st parameter contains the `enum' keyword name. % o The 3rd parameter contains the parameter list (maybe empty). % o The 4th parameter contains an optional variable name. % The declaration has to be terminated with "\end". \def\CCenumDeclaration #1#2\{#3\}#4\end {% \CCWfirst =\CCWconstructorfirst \CCWsecond =\CCWconstructorsecond \CCinitWidths \setbox\returntypebox=\hbox{}% \setbox\callnamebox=\hbox{\CCfont\CCprintTokens #2\end}% \setbox\functioncallbox=\hbox{\CCfont \CCprintTokens #2\end\{\ \isEmpty{#3}\ifnum\CCbool=\CCfalse \CCprintParamList{#3)}% \fi \};}% \CClayoutThreeColumns{\CCendfont\{}{#3)}{\CCendfont\}}{#1}% } % Manual layout: generalized three column format % o The 1st parameter contains the opening brace. % o The 2nd parameter contains the parameter list, comma separated, % including the closing parantheses which will not be printed. % o The 3rd parameter contains the closing brace. % o The 4th parameter contains the comment. % All paramters might be empty. % Global variables: % o \returntypebox contains the formatted returntype (maybe empty) % o \callnamebox contains the function/method/constructorname. % For methods, the variable is just prepended. % o \functioncallbox contains the complete functioncall incl. parameters % as a oneliner. \def\CClayoutThreeColumns #1#2#3#4{% \CCtopskip \hspace*{\CCWindent}% \ifdim\CCWfirst>0pt % check for constructors \ifdim\wd\returntypebox>\CCWfirst \unhbox\returntypebox\nopagebreak\CCreturnskip \else \parbox[t]{\CCWfirst}{\sloppy \unhbox\returntypebox}% \hspace*{\CCWbetween}% \fi \fi \ifdim\wd\functioncallbox>\CCWsecondlong % Operators are assumed to fit in \CCWsecondlong. % Otherwise, they are formatted as functions. \ifnum\CCalternateThreeColumn=\CCtrue % Switches ext. format ON. {\setbox0=\hbox{\CCfont\unhcopy\callnamebox #1 }% \global\CCWparam=\wd0}% \ifdim\CCWfirst>0pt % check for constructors \global\advance\CCWparam \CCWfirst \global\advance\CCWparam \CCWbetween \fi \def\CCextendedFormat{\nopagebreak\\ \hspace*{\CCWparam}}% {\CCfont\unhbox\callnamebox #1 }% \else % Switches ext. format ON. \def\CCextendedFormat{\nopagebreak\\ \hspace*{\CCWparam}}% {\CCfont \unhbox\callnamebox #1}% \CCextendedFormat \fi {\CCfont \isEmpty{#2}\ifnum\CCbool=\CCfalse \CCprintParamList{#2}% \fi #3}\hfill \isEmpty{#4}\ifnum\CCbool=\CCfalse \nopagebreak\CCmiddleskip \parbox[t]{\CCWcomment}{\sloppy #4}\hfill \fi \def\CCextendedFormat{\ }% Switches ext. format OFF. \CCbottombigskip \else\ifdim\wd\functioncallbox>\CCWsecond \parbox[t]{\CCWsecondlong}{\unhbox\functioncallbox}% \hfill \isEmpty{#4}\ifnum\CCbool=\CCfalse \nopagebreak\CCmiddleskip \parbox[t]{\CCWcomment}{\sloppy #4}% \CCbottombigskip \else \CCbottomskip \fi \else \parbox[t]{\CCWsecond}{\unhbox\functioncallbox}% \hspace*{\CCWbetween}% \parbox[t]{\CCWcomment}{\sloppy #4}\hfill \CCbottomskip \fi\fi } % \CCtemplateLine: extends the \CClayoutThreeColumns with an additional % line above the three columns that contains the template declaration % for functions or methods (if any) % % #1 the template declaration, delimited with \end \def\CCtemplateLine #1\end{% \CCprintTokens #1\end \\ } % Set the two boxes, returntype and functionname, for an operator declaration. \def\CCseparateOperator #1operator#2\end{% \setbox\returntypebox=\hbox{{\CCfont \CCprintReturnType #1const.&.\end}}% \setbox\functionnamebox=\hbox{{\CCfont \CCprintTokens operator#2\end}}% } % Set the two boxes, returntype and functionname, for a function declaration. % The part of the declaration has to be terminated with "::\end". \def\CCseparateFunction #1#2::#3\end{% \isEmpty{#3}\ifnum\CCbool=\CCtrue \CCseparateFunctionXX{#1}#2 .\end% \else \hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue \CCseparateFunction{#1#2:: }#3\end% \else \CCseparateFunction{#1#2::}#3\end% \fi \fi} % Set the two boxes, returntype and functionname, for a function declaration. % This macro scans through the token list space by space. If the operators % & or * occurs on the right side, they are shifted to the left. % o The 1st parameter is the first part of the type. % o The 2nd parameter is the next part of the type name. % o The 3rd and 4th parameter are the next part of the return type or % the name, if #4 is empty. Then, the 3rd parameter is the first % character of it. % The part of the declaration has to be terminated with " .\end". \def\CCseparateFunctionXX #1#2 #3#4\end{% \isEmpty{#4}\ifnum\CCbool=\CCtrue \setbox\returntypebox=\hbox{{\CCfont \CCprintReturnType #1const.&.\end}}% \setbox\functionnamebox=\hbox{{\CCfont \CCprintTokens #2\end}}% \else \def\xparams{#1}\ifx\xparams\empty \if#3&% \CCseparateFunctionXX{#2#3}#4\end% \else\if#3*% \CCseparateFunctionXX{#2#3}#4\end% \else \CCseparateFunctionXX{#2 }#3#4\end% \fi\fi \else \if#3&% \CCseparateFunctionXX{#1#2#3}#4\end% \else\if#3*% \CCseparateFunctionXX{#1#2#3}#4\end% \else \CCseparateFunctionXX{#1#2 }#3#4\end% \fi\fi \fi \fi} % Set the \trailingconstbox appropriately to \CCtagRmTrailingConst. % If #2 is empty we have found the trailing part in #1, % else apply this recursivly. \def\CCseparateTrailingConst #1)#2\end{% \ifnum\CCtagRmTrailingConst=\CCtrue \setbox\trailingconstbox=\hbox{}% \else \isEmpty{#1}\ifnum\CCbool=\CCtrue \setbox\trailingconstbox=\hbox{}% \else \def\xparams{#2}\ifx\xparams\empty \setbox\trailingconstbox=\hbox{{ % here is one space ! \CCfont\CCprintTokens #1\end}}% \else \CCseparateFunctionXX #2\end \fi \fi \fi } % +-------------------------------------------------------------------------- % | Formatting of simple C++ code: % | % | \CCprintChar, \CCprintSingleToken, \CCprintTokens % +-------------------------------------------------------------------------- % Print a character of a C++ declaration. Special handling of _<>&. \def\CCprintChar #1{% \if_#1\CCunderscore \else\ifx\_#1\CCunderscore \else\if<#1\CCopenangle \else\if>#1\CCcloseangle \else\if\CCampersand \else\ifx\\CCampersand \else\if^#1\CChat \else\ifx\^#1\CChat \else\if###1\CChash \else\ifx\##1\CChash \else #1% \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} % Print a single C++ token (without spaces inbetween). Skip leading spaces. % The token has to be delimited by "\end". \def\CCprintSingleTokenSemi #1;{% \CCprintSingleToken #1\end } \def\CCprintSingleToken #1\end{% \ifnum\CCtagReplacePrefix=\CCtrue \CCreplacePrefix{#1}{\CCprintSingleTokenX}% \else\CCprintSingleTokenX #1\end \fi } \def\CCprintSingleTokenX #1#2\end{%CCtrue \CCprintChar #1% \def\xbody{\CCprintSingleTokenX #2\end}% \isEmpty{#2}\ifnum\CCbool=\CCtrue \let\xnext=\relax \else\let\xnext=\xbody\fi \xnext} % Print C++ tokens (separated with spaces). Skip leading spaces. % The tokens have to be delimited by "\end". \def\CCprintTokens #1\end{% \ifnum\CCtagReplacePrefix=\CCtrue \CCreplacePrefix{#1}{\CCprintTokensX}% \else\CCprintTokensX #1\end \fi } \def\CCprintTokensX #1#2\end{% \CCprintChar #1% \def\xbody{\CCprintTokensX #2\end}% \isEmpty{#2}\ifnum\CCbool=\CCtrue \let\xnext=\relax \else \compareAndCopySpace{#2}#2\end \let\xnext=\xbody \fi \xnext} % +-------------------------------------------------------------------------- % | Replacement of Prefixes % | % | \CCsrcPrefix contains the old prefix % | \CCtargetPrefix contains the new prefix % | % | \CCreplacePrefix #1#2 replaces all prefixes in #1 and applies #2 to % | the partial results that have to be terminated % | by \end. % +-------------------------------------------------------------------------- \gdef\CCsrcPrefix{CGAL} \gdef\CCtargetPrefix{CGAL} \def\CCreplacePrefix #1#2{% \edef\CCpair{{\CCsrcPrefix}{\CCtargetPrefix}}% \expandafter\CCreplacePrefixX\CCpair{#1}{#2}% } % Does the actual work: #1 is the old prefix % #2 is the new prefix % #3 the text to process % #4 the macro to be applied to the partial results \def\CCreplacePrefixX #1#2#3#4{% \def\repminusone ##1##2\end{% \isEmpty{##2}\ifnum\CCbool=\CCfalse \rep ##2\end \fi }% % local macro to do the parsing: ##1 is the text before the old prefix % ##2 is the text after the old prefix \def\rep ##1#1##2\end{% set up a recursive loop \def\repbody{\rep ##2\end}% \isEmpty{##2}\ifnum\CCbool=\CCtrue \isEmpty{##1}\ifnum\CCbool=\CCfalse #4##1\end \fi \let\repnext=\relax \else % figure out whether it is a real prefix \isPrefixFollowChar{##2}\ifnum\CCbool=\CCtrue \isLastAlpha{##1}\CCinvert \else\if \fi\fi \ifnum\CCbool=\CCtrue % it is a real prefix \isUnderscore{##2}\ifnum\CCbool=\CCtrue \isEmpty{#2}\ifnum\CCbool=\CCtrue \def\repbody{\repminusone ##2\end}% \fi \isEmpty{##1#2}\ifnum\CCbool=\CCfalse #4##1#2\end \fi \else \ifnum\CCtagReplaceInclude=\CCtrue \isEmpty{#2}\ifnum\CCbool=\CCtrue \def\repbody{\repminusone ##2\end}% \fi \isEmpty{##1#2}\ifnum\CCbool=\CCfalse #4##1#2\end \fi \else #4##1#1\end \fi \fi \else \isEmpty{##1#1}\ifnum\CCbool=\CCfalse #4##1#1\end \fi \fi \let\repnext=\repbody \fi \repnext }% % call the above definition with at least one old prefix \rep #3#1\end } % +-------------------------------------------------------------------------- % | Formatting of operator declarations: % | % | To distinguish all operators, the number of given parameters is % | counted and two of the three possible operator characters are used. % +-------------------------------------------------------------------------- % Formats an operator declaration: % o The first parameter contains a 0 for a method call, a 1 for a function. % o The second parameter contains the return type. % o The third parameter contains the operator name. % o The fourth parameter contains the parameter list (maybe empty). % o The fifth parameter contains the optional const specifier for methods. % The declaration has to be terminated with "\end". \def\CCprintOperator #1#2operator#3(#4)#5\end{% \ifnum#1=0 \isEmpty{#4}\ifnum\CCbool=\CCtrue \CCprintOperatorOne{#1}{\var}{#4}#3\end \else \CCprintOperatorOne{#1}{\var,}{#4}#3\end \fi \else \CCprintOperatorOne{#1}{}{#4}#3\end \fi} % Formats a parenthesis () operator declaration: % o The #1 parameter contains a 0 for a method call, a 1 for a function. % o The #2 parameter contains the return type. % o The #3, #4, #5 parameters have to be empty. % o The #6 parameter contains the parameter list (maybe empty). % o The #7 parameter contains the optional const specifier for methods. % The declaration has to be terminated with "\end". \def\CCprintParOperator #1#2operator#3(#4)#5(#6)#7\end{% \isEmpty{#3}\ifnum\CCbool=\CCfalse\errmessage{Malformed parenthesis operator}\fi \isEmpty{#4}\ifnum\CCbool=\CCfalse\errmessage{Malformed parenthesis operator}\fi \isEmpty{#5}\ifnum\CCbool=\CCfalse\errmessage{Malformed parenthesis operator}\fi \ifnum#1=0 \isEmpty{#6}\ifnum\CCbool=\CCtrue \CCprintOperatorOne{#1}{\var}{#6}()\end \else \CCprintOperatorOne{#1}{\var,}{#6}()\end \fi \else \CCprintOperatorOne{#1}{}{#6}()\end \fi} % Formats a conversion operator. % Uses the returntypebox and the functioncallbox. % The declaration ends with "\end". \def\CCprintConversionOperator #1operator #2(#3)#4\end{% \setbox\returntypebox=\hbox{{\CCfont \CCprintTokens #2\end}} \setbox\functioncallbox=\hbox{{\CCfont \CCprintTokens #2(\var)\end}} } % An operator is detected and can be printed. % o The first parameter contains a 0 for a method call, a 1 for a function. % o The second parameter contains the \var if it is a method. % o The third parameter contains the (maybe empty) parameter list. % o The fourth parameter is the first character of the operator. % o The fifth parameter contains the rest of the operator. % The declaration ends with "\end". \newcount\operatorerror { \CCcatcode \catcode`\#=6 \catcode`\@=14 \gdef\CCprintOperatorOne #1#2#3#4#5\end{@ \CCextractParamList{#2#3)}@ \operatorerror=1 \isEmpty{#5}\ifnum\CCbool=\CCtrue @ single character operations \ifcase\NParameters @ no parameter \or @ 1 parameter \if~#4\CCoperatorpraefix{\mbox{\CCtilde}}\fi \if!#4\CCoperatorpraefix{#4\,}\fi \if-#4\CCoperatorpraefix{#4}\fi \if+#4\CCoperatorpraefix{#4}\fi \if\CCoperatorpraefix{\mbox{{\CCfont \CCampersand}}}\fi \if*#4\CCoperatorpraefix{#4}\fi \or @ 2 parameters \if*#4\CCoperatorinfix{#4}\fi \if/#4\CCoperatorinfix{\,#4}\fi \if%#4\CCoperatorinfix{\,#4\,}\fi \if+#4\CCoperatorinfix{#4}\fi \if-#4\CCoperatorinfix{#4}\fi \if<#4\CCoperatorinfix{#4}\fi \if>#4\CCoperatorinfix{#4}\fi \if\CCoperatorinfix{\mbox{{ \CCfont \CCampersand} }}\fi \if^#4\CCoperatorinfix{\mbox{\CChat}}\fi \if|#4\CCoperatorinfix{\;#4\;}\fi \if=#4\CCoperatorinfix{#4}\fi \if,#4\CCoperatorinfix{#4}\fi \else @ 3 parameters \fi \else @ two or more character operations \CCprintOperatorTwo #4#5\end \fi \ifnum\operatorerror=1 \errmessage{Unknown operator detected. Look out for the legal operator overloading in C++. Maybe, not all operators are currently supported by this style, sorry. Go ahead, and I format it as a function}@ \ifnum#1=0 {\CCfont \var.}\fi \CCprintTokens operator #4#5\end@ (\isEmpty{#3}\ifnum\CCbool=\CCfalse \CCprintParamList{#3)}\fi )@ \fi } @ An operator with two or more characters is detected and can be printed. @ o The first parameter is the first character of the operator. @ o The second parameter is the second character of the operator. @ o The third parameter contains the rest of the operator. @ The declaration ends with "\end". \gdef\CCprintOperatorTwo #1#2#3\end{@ \isEmpty{#3}\ifnum\CCbool=\CCtrue @ two character operations \ifcase\NParameters @ no parameter \or @ 1 parameter \if-#1\if>#2\CCoperatorpostfix{\:#1\!\!\!#2}\fi\fi \if(#1\if)#2\CCoperatorparX{(}{)}\fi\fi \if+#1\if+#2\CCoperatorpraefix{#1\!#2}\fi\fi \if-#1\if-#2\CCoperatorpraefix{#1\!#2}\fi\fi \or @ 2 parameters \if[#1\if]#2\CCoperatorparXX{\CCendfont{\rm [} }{\CCendfont{\rm ]}}\fi\fi \if(#1\if)#2\CCoperatorparXX{( }{)}\fi\fi \if+#1\if+#2\CCoperatorpostfix{#1\!#2}\fi\fi \if-#1\if-#2\CCoperatorpostfix{#1\!#2}\fi\fi \if>#1\if>#2\CCoperatorinfix{#1\!#2}\fi\fi \if<#1\if<#2\CCoperatorinfix{#1\!#2}\fi\fi \if<#1\if=#2\CCoperatorinfix{#1#2}\fi\fi \if>#1\if=#2\CCoperatorinfix{#1#2}\fi\fi \if=#1\if=#2\CCoperatorinfix{#1#2}\fi\fi \if!#1\if=#2\CCoperatorinfix{\;#1\!#2}\fi\fi \if\if\CCoperatorinfix{\mbox{ {\CCfont \CCampersand}}\mbox{{\CCfont \CCampersand} }}\fi\fi \if|#1\if|#2\CCoperatorinfix{\;#1#2\;}\fi\fi \if*#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi \if/#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi \if%#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi \if+#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi \if-#1\if=#2\CCoperatorinfix{\,#1\!#2}\fi\fi \if\if=#2\CCoperatorinfix{\mbox{ {\CCfont \CCampersand}}\!#2}\fi\fi \if|#1\if=#2\CCoperatorinfix{\;#1\!#2}\fi\fi \if^#1\if=#2\CCoperatorinfix{\mbox{\CChat{}}\!\! #2}\fi\fi \else @ 3 parameters \if(#1\if)#2\CCoperatorparXXX{( }{)}\fi\fi \fi \else @ three or more character operations \ifcase\NParameters @ no parameter \or @ 1 parameter \if-#1\if>#2\CCoperatorpostfix{\:#1\!\!\!#2\! #3}\fi\fi \or @ 2 parameters \if#1n\if#2e\CCoperatornew{#1#2#3}\fi\fi \if>#1\if>#2\CCoperatorinfix{#1\!#2#3}\fi\fi \if<#1\if<#2\CCoperatorinfix{#1\!#2#3}\fi\fi \else @ 3 parameters \if#1d\if#2e\CCoperatordelete{#1#2#3}\fi\fi \fi \fi } } \def\CCoperatorpraefix #1{% $#1 \mbox{\unhbox\parameterX}$\operatorerror=0 } \def\CCoperatorinfix #1{% $\mbox{\unhbox\parameterX\CCendfont} #1 \mbox{\unhbox\parameterXX}$\operatorerror=0 } \def\CCoperatorpostfix #1{% $\mbox{\unhbox\parameterX} #1$\operatorerror=0 } \def\CCoperatorappend #1#2{% $\mbox{\unhbox\parameterX} #1#2$\operatorerror=0 } \def\CCoperatorparX #1#2{% \unhbox\parameterX#1#2\operatorerror=0 } \def\CCoperatorparXX #1#2{% \unhbox\parameterX#1\unhbox\parameterXX#2\operatorerror=0 } \def\CCoperatorparXXX #1#2{% \unhbox\parameterX\CCendfont#1\unhbox\parameterXX, \unhbox\parameterXXX#2\operatorerror=0 } \def\CCoperatornew #1{% $ \mbox{{\CCfont #1} \classtemplatename}$\operatorerror=0 } % $ * \mbox{{\CCfont ptr\_}\unhbox\parameterX} = \mbox{{\CCfont #1} % \classtemplatename}$\operatorerror=0 } \def\CCoperatordelete #1{% $ \mbox{{\CCfont #1} \unhbox\parameterXX}$\operatorerror=0 } % +-------------------------------------------------------------------------- % | Template declaration separation % | % | The input starts with a template declaration. This and including % | its parameter list will be separated from the rest of the declaration. % | The macro in argument #1 will be applied to them, delimited with \end. The % | rest will be handed over to the command in argument #2, also delimited % | with \end. % +-------------------------------------------------------------------------- % #1 macro to be applied to the template declaration % #2 macro to be applied to the rest of the declaration % #3 should be empty % #4 the declaration, delimited by \end. \def\CCseparateTemplate #1#2#3template#4\end{% \nestinglevel=0 \hasLeadingSpace{#4}\ifnum\CCbool=\CCtrue \CCseparateTemplateX{#1}{#2}{template }#4\end \else \CCseparateTemplateX{#1}{#2}{template}#4\end \fi} % #1 macro to be applied to the template declaration % #2 macro to be applied to the rest of the declaration % #3 accumulator for the template declaration % #4 first character of declaration % #5 rest of declaration, delimited by \end. \def\CCseparateTemplateX #1#2#3#4#5\end{% \if<#4\advance\nestinglevel by1 \fi \if(#4\advance\nestinglevel by1 \fi \if)#4\advance\nestinglevel by-1 \fi \if>#4\advance\nestinglevel by-1 \fi \ifnum\nestinglevel<1 \ifnum\nestinglevel<0 \errmessage{Unbalanced angles detected in template parameters of template declaration. I'll try.}% \fi #1#3#4\end #2#5\end \fi \hasLeadingSpace{#5}\ifnum\CCbool=\CCtrue \def\xxbody{\CCseparateTemplateX{#1}{#2}{#3#4 }#5\end}% \else \def\xxbody{\CCseparateTemplateX{#1}{#2}{#3#4}#5\end}% \fi \ifnum\nestinglevel<1 \let\xxnext=\relax \else\let\xxnext=\xxbody\fi \xxnext} % +-------------------------------------------------------------------------- % | Parameter list parsing: % | % | Parameter lists are commata separated parameters. Template % | instantiation nesting is considered. Parentheses nesting % | from default initializers are also considered. % +-------------------------------------------------------------------------- % Print a C++ parameter list (separated with commatas). The output formats % with a space between commata and the parameter text. \def\CCprintParamList #1{% \nestinglevel=0 \CCprintParamListX{}#1\end} % Support function: % o The first parameter accumulates the so far parsed first parameter. % o The second parameter contains the next character. % o The third parameter contains the rest. % The parsing process iterates characterwise. % The parameter list has to be terminated with "\end". \def\CCprintParamListX #1#2#3\end{% \if<#2\advance\nestinglevel by1 \fi \if>#2\advance\nestinglevel by-1 \fi \if(#2\advance\nestinglevel by1 \fi \if)#2\advance\nestinglevel by-1 \fi \if,#2% \ifnum\nestinglevel=0 \CCprintParameter #1const.&.\end,\CCextendedFormat \def\xxbody{\CCprintParamListX{}#3\end}% \else\ifnum\nestinglevel<0 \errmessage{Unbalanced angles detected in template types in the C++ parameter list}% \def\xxbody{\CCprintParamListX{}#3\end}% \else% comma within template parameter detected \hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue \def\xxbody{\CCprintParamListX{#1#2 }#3\end}% \else \def\xxbody{\CCprintParamListX{#1#2}#3\end}% \fi \fi\fi \else% old: \isEmpty{#3}\ifnum\CCbool=\CCtrue \ifnum\nestinglevel<0 \ifnum\nestinglevel=-1 \CCprintParameter #1const.&.\end% \else \errmessage{Unbalanced angles detected in template types in the C++ parameter list}% \fi \def\xxbody{\CCprintParamListX{}#3\end}% \else \hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue \def\xxbody{\CCprintParamListX{#1#2 }#3\end}% \else \def\xxbody{\CCprintParamListX{#1#2}#3\end}% \fi \fi\fi % old: \isEmpty{#3}\ifnum\CCbool=\CCtrue \ifnum\nestinglevel<0 \let\xxnext=\relax \else\let\xxnext=\xxbody\fi \xxnext} % If an operator is used, a specialized parameter parsing macro counts % the number of parameters and store the result in the three following boxes. % \NParameters is one of 0,1,2,3. In the case of 3, there are three or more % parameters, as it was possible for the ()-operator. Thei are all together % stored in \box\parameterXXX. \newcount\NParameters % counts number of parameters for operators \newbox\parameterX % first parameter \newbox\parameterXX % second parameter \newbox\parameterXXX % third and rest of parameters % Extract up to three parameters from a C++ parameter list % (separated with commatas) within the \parameterX.. boxes. \def\CCextractParamList #1{% \nestinglevel=0 \NParameters=0 \isEmpty{#1}\ifnum\CCbool=\CCfalse \CCextractParamListX{}#1\end\fi} % Support function: % o The first parameter accumulates the so far parsed first parameter. % o The second parameter contains the next character. % o The third parameter contains the rest. % The parsing process iterates characterwise. % The parameter list has to be terminated with "\end". \def\CCextractParamListX #1#2#3\end{% \if<#2\advance\nestinglevel by1 \fi \if>#2\advance\nestinglevel by-1 \fi \if(#2\advance\nestinglevel by1 \fi \if)#2\advance\nestinglevel by-1 \fi \if,#2% \ifnum\nestinglevel=0 \advance\NParameters by1 \ifnum\NParameters=1 \setbox\parameterX=% \hbox{\CCprintParameter #1const.&.\end}% \def\xxxbody{\CCextractParamListX{}#3\end}% \else\advance\NParameters by1 \setbox\parameterXX=% \hbox{\CCprintParameter #1const.&.\end}% \setbox\parameterXXX=% \hbox{\CCprintParamList{#3}}% \def\xxxbody{\relax}% \fi \else\ifnum\nestinglevel<-1 \errmessage{Unbalanced angles or parantheses detected in template types in the C++ parameter list}% \def\xxxbody{\CCextractParamListX{}#3\end}% \else% comma within template parameter detected \hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue \def\xxxbody{\CCextractParamListX{#1#2 }#3\end}% \else \def\xxxbody{\CCextractParamListX{#1#2}#3\end}% \fi \fi\fi \else\ifnum\nestinglevel<0 \ifnum\nestinglevel=-1 \advance\NParameters by1 \ifnum\NParameters=1 \setbox\parameterX=% \hbox{\CCprintParameter #1const.&.\end}% \else\ifnum\NParameters=2 \setbox\parameterXX=% \hbox{\CCprintParameter #1const.&.\end}% \else\setbox\parameterXXX=% \hbox{\CCprintParameter #1const.&.\end}% \fi\fi \else \errmessage{Unbalanced angles or parantheses detected in template types in the C++ parameter list}% \fi \def\xxxbody{\CCextractParamListX{}#3\end}% \else \hasLeadingSpace{#3}\ifnum\CCbool=\CCtrue \def\xxxbody{\CCextractParamListX{#1#2 }#3\end}% \else \def\xxxbody{\CCextractParamListX{#1#2}#3\end}% \fi \fi\fi \ifnum\nestinglevel<0 \let\xxxnext=\relax \else\let\xxxnext=\xxxbody\fi \xxxnext} % +-------------------------------------------------------------------------- % | Parameter Parsing: % | % | A single parameter consists of a type and optional of a variable name. % | If the type contains a "const ... &" pair, it is removed. If the % | the type is similar to the class that is currently declared, it is % | also removed. (In that case it might result in an empty parameter % | if no variable name is given. Then, a dummy "#" is printed instead. % | % | The return type of a method or function has no `variable name', so % | only "const ... &" removal is done and no classname elimination. % +-------------------------------------------------------------------------- % The parameter parsing macros counts the nesting level of % template parameter instantiations. \newcount\nestinglevel \newcount\xnestinglevel % Print a parameter where "const ...&" pairs are eliminated. Strips a % leading type that equals the \classname. It is a four step process: % 1. strip all in front of a "<" character. % 2. extract the leading token without any space in it to decide, % weather the type given is a templated type or not. % 3. Compare the leading token with \classname % 4. If true, strip the possible following template parameter. % The parameter has to be delimited with "<>\end". % Ignore leading spaces. \def\CCprintOwnClassParameter #1#2<#3#4\end{% \ifnum\CCtagRmEigenClassName=\CCfalse \CCprintOwnClassXQX #1#2<#3#4\end% \else \ifx\pureparameters\empty \if>#3% \CCprintOwnClassX #1#2 \end% no template case \else \CCprintOwnClassXQX #1#2<#3#4\end% \fi \else\if>#3% \CCprintOwnClassX #1#2 \end% no template case \else \CCprintOwnClassXX{#1#2}<#3#4\end% template case ? \fi\fi \fi } \def\CCprintOwnClassXQX #1#2<>\end{% strip the unneccessary <> from the end \CCprintTokens #1#2\end} \def\CCprintOwnClassX #1 #2\end{% check for \classname \def\xparams{#1}\ifx\xparams\pureclassname \isEmpty{#2}\ifnum\CCbool=\CCtrue \CCemptyParameter \else \CCprintTokens #2\end% \fi \else \CCprintTokens #1 #2\end% \fi} \def\CCprintOwnClassXX #1#2<>\end{% strip the unneccessary <> from the end \CCprintOwnClassXXX {#2}#1 \end} \def\CCprintOwnClassXXX #1#2 #3\end{% % check \classname in the possible template case % #1 is the parameter tail starting with the template params % #2 is the leading class name % #3 is inbetween and should be empty \def\qqparams{#3}\ifx\qqparams\empty \def\xparams{#2}\ifx\xparams\pureclassname \xnestinglevel=0 \CCprintOwnClassXXXX #1\end% strip the template parameters \else \CCprintTokens #2#1\end% nothing stripped \fi \else \CCprintTokens #2\ \end \CCprintOwnClassXXX {#1}#3\end \fi} \def\CCprintOwnClassXXXX #1#2\end{% strip a leading template parameter \if<#1\advance\xnestinglevel by1 \fi \if>#1\advance\xnestinglevel by-1 \fi \ifnum\xnestinglevel=0 \isEmpty{#2}\ifnum\CCbool=\CCtrue \CCemptyParameter \else \CCprintTokens #2\end% \fi \let\xnext=\relax \else \def\xparams{#2}% \ifx\xparams\empty \errmessage{Mismatching angles in template parameter list}% \fi \def\xbody{\CCprintOwnClassXXXX #2\end}% \let\xnext=\xbody \fi \xnext} % Print a C++ function or method parameter. Strips a matching % "const ...&" pair. % The parameter has to be delimited with "const.&.\end". \def\CCprintParameter #1const#2\end{% \ifnum\CCtagRmConstRefPair=\CCfalse \CCprintParameterXQ #1const#2\end% \else \if.#2\isEmpty{#1}\ifnum\CCbool=\CCfalse \CCprintOwnClassParameter #1<>\end% \fi \else \if\CCprintParameter #1\end% \else \if.#3\CCprintParameterXQ #1const#2\end% \else\hasLeadingSpace{#2}\ifnum\CCbool=\CCfalse \isLetter{#2}\CCinvert \fi \ifnum\CCbool=\CCtrue \CCprintParameter #1#2 #3\end% \else \CCprintParameterXQ #1const#2\end% \fi \fi \fi \fi \fi} \def\CCprintParameterXQ #1const.&.\end{\CCprintOwnClassParameter #1<>\end} % Print a C++ function or method return type. Strips a matching % "const ...&" pair. % The parameter has to be delimited with "const.&.\end". \def\CCprintReturnType #1const#2\end{% \ifnum\CCtagRmConstRefPair=\CCfalse \CCprintReturnTypeXQ #1const#2\end% \else \if.#2\isEmpty{#1}\ifnum\CCbool=\CCfalse \CCprintTokens #1\end% \fi \else \if\CCprintReturnType #1\end% \else \if.#3\CCprintReturnTypeXQ #1const#2\end% \else\hasLeadingSpace{#2}\ifnum\CCbool=\CCfalse \isLetter{#2}\CCinvert \fi \ifnum\CCbool=\CCtrue \CCprintReturnType #1#2 #3\end% \else \CCprintReturnTypeXQ #1const#2\end% \fi \fi \fi \fi \fi} \def\CCprintReturnTypeXQ #1const.&.\end{\CCprintTokens #1\end}