% +----------------------------------------
% | 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&#1\CCampersand
                   \else\ifx\&#1\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&#4\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&#4\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&#1\if&#2\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&#1\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&#3\end{%
    \ifnum\CCtagRmConstRefPair=\CCfalse
        \CCprintParameterXQ #1const#2&#3\end%
    \else
        \if.#2\isEmpty{#1}\ifnum\CCbool=\CCfalse 
            \CCprintOwnClassParameter #1<>\end%
            \fi
        \else
            \if&#2\CCprintParameter #1&#3\end%
            \else
                \if.#3\CCprintParameterXQ #1const#2&#3\end%
                \else\hasLeadingSpace{#2}\ifnum\CCbool=\CCfalse
                        \isLetter{#2}\CCinvert
                    \fi
                    \ifnum\CCbool=\CCtrue
                        \CCprintParameter #1#2 #3\end%
                    \else
                        \CCprintParameterXQ #1const#2&#3\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&#3\end{%
    \ifnum\CCtagRmConstRefPair=\CCfalse
        \CCprintReturnTypeXQ #1const#2&#3\end%
    \else
        \if.#2\isEmpty{#1}\ifnum\CCbool=\CCfalse 
            \CCprintTokens #1\end%
            \fi
        \else
            \if&#2\CCprintReturnType #1&#3\end%
            \else
                \if.#3\CCprintReturnTypeXQ #1const#2&#3\end%
                \else\hasLeadingSpace{#2}\ifnum\CCbool=\CCfalse
                        \isLetter{#2}\CCinvert
                    \fi
                    \ifnum\CCbool=\CCtrue
                        \CCprintReturnType #1#2 #3\end%
                    \else 
                        \CCprintReturnTypeXQ #1const#2&#3\end%
                    \fi
                \fi
            \fi
        \fi
    \fi}
\def\CCprintReturnTypeXQ #1const.&.\end{\CCprintTokens #1\end}

