mirror of https://github.com/CGAL/cgal
327 lines
13 KiB
TeX
327 lines
13 KiB
TeX
% =============================================================================
|
|
% The CGAL Developers' Manual
|
|
% Chapter: Namespaces
|
|
% -----------------------------------------------------------------------------
|
|
% file : namespaces.tex
|
|
% authors: Stefan Schirra <stschirr@mpi-sb.mpg.de>
|
|
% -----------------------------------------------------------------------------
|
|
% $Revision$
|
|
% $Date$
|
|
% =============================================================================
|
|
|
|
\chapter{Namespaces}
|
|
\label{chap:namespaces}
|
|
\ccChapterAuthor{Stefan Schirra ({\tt stschirr@mpi-sb.mpg.de})}
|
|
|
|
Names, in particular (member) function names and class names should
|
|
be descriptive and easily remembered. So it is not surprising that
|
|
different libraries or packages choose the same name for corresponding
|
|
or similar classes and functions. A common approach to solving the
|
|
naming problem is to add a prefix,\ccIndexMainItem{prefix} for example,
|
|
OpenGL adds \ccc{gl}
|
|
and FLTK adds \ccc{fl}. \leda\ uses prefix \ccc{leda_}%
|
|
\ccIndexSubitem{prefix}{\ccFont leda_}
|
|
\ccIndexSubitem{\leda}{prefix}
|
|
to some extent,
|
|
but you have to tell \leda\ not to make the corresponding unprefixed names
|
|
available as well.\footnote{\cgal's
|
|
makefile does this by setting \ccc{-DLEDA_PREFIX}.} Initially, \cgal\ used
|
|
prefix \ccc{CGAL_}.
|
|
At the beginning of 1999, it was decided to drop prefix \ccc{CGAL_} and to
|
|
introduce namespace \ccc{CGAL}.
|
|
|
|
\section{What are namespaces}
|
|
A namespace\ccIndexMainItemDef{namespace}
|
|
is a scope with a name.\footnote{There are also unnamed namespaces.
|
|
They are intented to replace file scope.} Inside the namespace, \ie, the
|
|
named scope, all names defined in that scope (and made known to the compiler)
|
|
can be used directly. Outside a namespace, a name defined in the namespace
|
|
has to be qualified\footnote{This is a somewhat simplified view; read further
|
|
for more details.} by the namespace name, for example \ccc{CGAL::Object},%
|
|
\ccIndexSubitem{qualification}{of names}
|
|
or they have to be made usable without qualificiation by a so-called
|
|
{\em using declaration},
|
|
\ccIndexMainItem{using declaration}
|
|
\begin{verbatim}
|
|
using CGAL::Object;
|
|
Object obj; // name is now known
|
|
\end{verbatim}
|
|
There is also a statement to make all names from a namespace available in
|
|
another scope, but this is a bad idea. Actually, in order not to set a bad
|
|
example, we recommend not to use this in \cgal's example and demo programs.
|
|
|
|
\section{Namespace std}
|
|
\ccIndexSubitem{namespace}{\ccFont std}
|
|
The names form the standard \CC\ library, especially those from the standard
|
|
template library, are (supposed to be) in namespace \ccc{std}. This subsumes
|
|
the I/O-library%
|
|
\index{IO library@I/O library!and namespace std@and namespace \texttt{std}}
|
|
and also the C-library%
|
|
\index{C standard library!and namespace std@and namespace \ccStyle{std}}
|
|
functions.
|
|
If rules are applied strictly\footnote{Not all compilers do that, but some
|
|
at least have a flag to force strict application of the rules.}, you have to
|
|
qualify streams and so by \ccc{std::}, too. That is:
|
|
\begin{verbatim}
|
|
std::cout << "Hello CGAL" << std::endl;
|
|
\end{verbatim}
|
|
or you have to add \ccc{using} declarations for the names you want to use
|
|
without \ccc{std::} qualification. Developers should of course assume that
|
|
the rules will be applied strictly. Whenever a platform does not put names
|
|
in namespace \ccc{std}, \cgal\ adds the names it needs to namespace \ccc{std}.
|
|
This is done by the configuration tools!
|
|
\ccIndexMainItem{configuration}
|
|
|
|
As for the C-library functions, you should use the macro
|
|
\texttt{CGAL\_CLIB\_STD} instead of \texttt{std}:
|
|
\begin{verbatim}
|
|
CGAL_CLIB_STD::isspace(c)
|
|
\end{verbatim}
|
|
\index{cgal_clib_std macro@{\tt CGAL\_CLIB\_STD} macro}
|
|
|
|
\section{Namespace CGAL}
|
|
\ccIndexSubitem{namespace}{\ccFont CGAL}
|
|
All names introduced by \cgal\ should be in namespace \ccc{CGAL}, \eg:
|
|
\begin{verbatim}
|
|
#include <something>
|
|
|
|
namespace CGAL {
|
|
|
|
class My_new_cgal_class {};
|
|
|
|
My_new_cgal_class
|
|
my_new_function( My_new_cgal_class& );
|
|
|
|
} // namespace CGAL
|
|
\end{verbatim}
|
|
Make sure not to have include statements nested between
|
|
\verb+ namespace CGAL { + and \verb+ } // namespace CGAL+.
|
|
Otherwise all names defined in the file included will be
|
|
added to namespace \ccc{CGAL}. (Some people use the macros
|
|
\ccc{CGAL_BEGIN_NAMESPACE} and \ccc{CGAL_END_NAMEPACE}
|
|
in place of the \texttt{namespace CGAL \{} and
|
|
\texttt{\} // namespace CGAL}, respectively for better readability.)
|
|
|
|
Some compilers don't like \texttt{CGAL::} qualification in
|
|
namespace \ccc{CGAL}. In other cases, \eg, template friend declarations,%
|
|
\ccIndexSubitem{friend declaration}{function template}
|
|
\ccIndexSubsubitem{template}{function}{friend declarations}
|
|
compilers need to see \texttt{CGAL::} qualification. To resolve this
|
|
dilemma, use \texttt{CGAL\_SCOPE} instead of \texttt{CGAL::} in such cases.
|
|
\index{cgal_scope macro@{\tt CGAL\_SCOPE} macro}
|
|
|
|
\section{Name lookup}
|
|
The process of searching for a definition of a name detected in
|
|
some scope is called name lookup.\ccIndexMainItemDef{name lookup}
|
|
Simply speaking, name lookup looks
|
|
up names in the scope where the name is used,
|
|
and if not found, the lookup proceeds in successively enclosing scope
|
|
until the name is found. It terminates as soon as the name is found, no
|
|
matter whether the name found fits or not.
|
|
If a name is qualified by a namespace name, that namespace is searched
|
|
for the name.
|
|
|
|
\subsection{Argument-dependent name lookup}
|
|
\ccIndexSubitem{name lookup}{argument-dependent}%
|
|
\ccIndexSubitem{name lookup}{unqualified}
|
|
Unqualified name lookup, \ie, lookup when there is no namespace or class
|
|
name and no scope resolution%
|
|
\ccIndexMainItem{scope resolution} operator \verb+::+, proceeds like qualified
|
|
name lookup, but name lookup for a function call is supposed to search also
|
|
the namespaces of the argument types for a matching function name.
|
|
This is sometimes called Koenig-lookup.\footnote{%
|
|
\path+http://www.devresource.hp.com/devresource/Docs/TechPapers/KoenigLookup.html+}\ccIndexMainItem{Koenig lookup}
|
|
\cgal\ checks for Koenig-lookup. If this is not available,
|
|
the flag \ccc{CGAL_CFG_NO_KOENIG_LOOKUP}%
|
|
\index{CGAL_CFG_NO_KOENIG_LOOKUP flag@{\tt CGAL\_CFG\_NO\_KOENIG\_LOOKUP} flag}
|
|
is set. As a workaround,
|
|
you can add matching function(s) with the same name in the using namespace;
|
|
most likely, this will be the global scope.
|
|
Here is an example:
|
|
|
|
\ccIncludeExampleCode{kl.C}
|
|
|
|
While \verb+gcc 2.95+ and the Kai \CC\ compiler don't have problems
|
|
with correctly compiling the program above, the mips compiler on {\sc IRIX}
|
|
does not implement Koenig lookup, so it fails:
|
|
|
|
{\small
|
|
\begin{verbatim}
|
|
bash-2.03$ CC -64 kl.C
|
|
cc-1387 CC: ERROR File = kl.C, Line = 19
|
|
No suitable conversion function from "A::Cls" to "int" exists.
|
|
|
|
foo( c );
|
|
^
|
|
|
|
1 error detected in the compilation of "kl.C".
|
|
\end{verbatim}
|
|
|
|
}
|
|
Workaround for missing Koenig lookup:\ccIndexSubitem{Koenig lookup}{workaround}
|
|
Define
|
|
\begin{verbatim}
|
|
bool
|
|
foo( const A::Cls& cls)
|
|
{ return A::foo( cls); }
|
|
\end{verbatim}
|
|
in global scope, too.
|
|
|
|
\subsection{Point of instantiation of a template}
|
|
Name lookup in a template is slightly more complicated.
|
|
\ccIndexSubitem{name lookup}{template}
|
|
Names that do not depend on template parameters are looked up at the point
|
|
of definition of the template%
|
|
\ccIndexSubitem{template}{point of definition}
|
|
(so they must be known at the point of definition).
|
|
Names depending on the template parameters are looked up at
|
|
the point of instantiation%
|
|
\ccIndexSubitem{template}{point of instantiation} of the template.
|
|
The name is searched for in the
|
|
scope of the point of instantiation and the scope of the
|
|
point of definition. Here is a small example:
|
|
|
|
\ccIncludeExampleCode{poi.C}
|
|
|
|
There is a ambiguity, because both the scope enclosing the point of
|
|
instantiation and the scope enclosing the point of definition contain
|
|
a \ccc{mix} function. The mips compiler on {\sc IRIX} and the Kai \CC\
|
|
compiler complain about this ambiguity:
|
|
|
|
{\small
|
|
\begin{verbatim}
|
|
bash-2.03$ CC -64 poi.C
|
|
cc-1282 CC: ERROR File = poi.C, Line = 11
|
|
More than one instance of overloaded function "mix" matches the argument list.
|
|
|
|
Function symbol function template "B::mix(const T &, const T &)"
|
|
is ambiguous by inheritance.
|
|
Function symbol function template "A::mix(const T &, const T &)"
|
|
is ambiguous by inheritance.
|
|
The argument types are: (const double, const double).
|
|
{ return mix( a1, a2); }
|
|
^
|
|
detected during instantiation of
|
|
"const double &A::use(const double &, const double &)"
|
|
|
|
1 error detected in the compilation of "poi.C".
|
|
\end{verbatim}
|
|
|
|
\bigskip
|
|
\begin{verbatim}
|
|
bash-2.03$ /opt/kaic++/KCC_BASE/bin/KCC poi.C
|
|
Recompiling poi.o
|
|
"poi.C", line 11: error: more than one instance of overloaded function "mix"
|
|
matches the argument list:
|
|
function template "B::mix(const T &, const T &)"
|
|
function template "A::mix(const T &, const T &)"
|
|
argument types are: (const double, const double)
|
|
{ return mix( a1, a2); }
|
|
^
|
|
detected during instantiation of
|
|
"const T &A::use(const T &, const T &) [with T=double]"
|
|
|
|
1 error detected in the compilation of "poi.C".
|
|
\end{verbatim}
|
|
|
|
}
|
|
There wouldn't be any problems, if \verb+B::use_use()+ would be a template
|
|
function as well, because this would move the point of instantiation
|
|
into global scope.
|
|
|
|
By the way, \verb+gcc 2.95+ uses the function defined at the
|
|
point of definition.
|
|
|
|
\section{Namespace CGAL::NTS}
|
|
What are the conclusions from the previous subsection. If \ccc{A}
|
|
plays the role of \ccc{std} and \ccc{B} the role of \cgal, we can
|
|
conclude that \cgal\ should not define template
|
|
functions that are already defined in namespace \ccc{std}, especially
|
|
\ccc{min} and \ccc{max}.
|
|
Also, letting CGAL be namespace \ccc{A}, we should not define
|
|
templates in \cgal\ that are likely to conflict with templates in
|
|
other namespaces (playing the role of \ccc{B}): Assume that both \cgal\
|
|
and some other namespace define an \ccc{is_zero()} template.
|
|
Then an instantiation of some \cgal\ template using \ccc{is_zero()}
|
|
that takes place inside the other namespace causes trouble.
|
|
For this reason, we have another namespace \ccc{NTS}%
|
|
\ccIndexSubitem{namespace}{\ccFont CGAL::NTS}
|
|
nested in \ccc{CGAL}, which contains potentially conflicting
|
|
template functions.
|
|
|
|
\subsection{Which function calls should be qualified in \cgal\ code?}
|
|
Out current policy is:
|
|
\begin{itemize}
|
|
\item
|
|
\ccc{max} should be used without qualification\ccIndexGlobalFunction{max}
|
|
\item
|
|
\ccc{min} should be used without qualification\ccIndexGlobalFunction{min}
|
|
\item
|
|
For the following functions, templates are provided in nested namespace
|
|
\ccc{NTS}:
|
|
\begin{itemize}
|
|
\item[]\ccc{abs}\ccIndexGlobalFunction{abs}
|
|
\item[]\ccc{compare}\ccIndexGlobalFunction{compare}
|
|
\item[]\ccc{gcd}\ccIndexGlobalFunction{gcd}
|
|
\item[]\ccc{is_negative}\ccIndexGlobalFunction{is_negative}
|
|
\item[]\ccc{is_positive}\ccIndexGlobalFunction{is_positive}
|
|
\item[]\ccc{is_one}\ccIndexGlobalFunction{is_one}
|
|
\item[]\ccc{is_zero}\ccIndexGlobalFunction{is_zero}
|
|
\item[]\ccc{sign}\ccIndexGlobalFunction{sign}
|
|
\item[]\ccc{lexicographical_sign}\ccIndexGlobalFunction{lexicographical_sign}
|
|
\item[]\ccc{square}\ccIndexGlobalFunction{square}
|
|
\end{itemize}
|
|
Calls of the above functions should be qualified using macro
|
|
\ccc{CGAL_NTS},%
|
|
\index{CGAL_NTS macro@{\tt CGAL\_NTS} macro}
|
|
which maps to \ccc{CGAL::NTS::}\footnote{The use of
|
|
the macro eases future changes in our policy.}: For example,
|
|
\begin{verbatim}
|
|
if ( CGAL_NTS is_zero(0) ) { /* ... */ }
|
|
\end{verbatim}
|
|
Qualification with \ccc{CGAL} does not work.
|
|
\item
|
|
The following functions can be qualified by \ccc{CGAL_NTS} as well:
|
|
\begin{itemize}
|
|
\item[]\ccc{to_double}\ccIndexGlobalFunction{to_double}
|
|
\item[]\ccc{is_valid}\ccIndexGlobalFunction{is_valid}
|
|
\item[]\ccc{is_finite}\ccIndexGlobalFunction{is_finite}
|
|
\item[]\ccc{sqrt}\ccIndexGlobalFunction{sqrt}\\
|
|
\item[]\ccc{div}\ccIndexGlobalFunction{div}\\
|
|
Whenever the argument of \ccc{sqrt} is a concrete type, \ie, it does
|
|
not depend on a template parameter, you should qualify the call of
|
|
\ccc{sqrt}, for example \verb+CGAL_CLIB_STD::sqrt(2.0)+
|
|
\end{itemize}
|
|
Here, qualification with \ccc{CGAL} works as well.
|
|
\end{itemize}
|
|
Summarizing, you can always qualify functions on number types
|
|
with \ccc{CGAL_NTS} besides \ccc{min} and \ccc{max}.
|
|
|
|
\InternalOnly{
|
|
|
|
\section{Requirements and recommendations}
|
|
|
|
Requirements:
|
|
\begin{itemize}
|
|
\item all names defined by \cgal\ are in namespace \ccc{CGAL} (including
|
|
namespaces nested in namespace \ccc{CGAL}).
|
|
\item qualify calls of \ccc{is_zero}, \ccc{is_one}, \ccc{is_negative},
|
|
\ccc{is_positive}, \ccc{sign}, \ccc{lexicographical_sign}, \ccc{abs},
|
|
\ccc{compare}, \ccc{square} by \texttt{CGAL\_NTS}.
|
|
\ccIndexSubitem{qualification}{\ccFont CGAL_NTS}%
|
|
\item use \texttt{CGAL\_CLIB\_STD} with C-library functions.
|
|
\index{cgal_clib_std macro@{\tt CGAL\_CLIB\_STD} macro}%
|
|
\ccIndexSubitem{qualification}{\ccFont CGAL_CLIB_STD}%
|
|
\end{itemize}
|
|
|
|
Recommendations:
|
|
\begin{itemize}
|
|
\item Don't qualify calls of \ccc{max} and \ccc{min}.
|
|
\item Don't use \ccc{CGAL::} qualification inside namespace \ccc{CGAL},%
|
|
\ccIndexSubitem{qualification}{\ccFont CGAL::}
|
|
unless it is required by a compiler or to resolve a name conflict with a
|
|
local type in a scope enclosed by namespace \ccc{CGAL}.
|
|
\end{itemize}
|
|
|
|
}
|