mirror of https://github.com/CGAL/cgal
504 lines
18 KiB
TeX
504 lines
18 KiB
TeX
% +------------------------------------------------------------------------+
|
|
% | STL User Manual: Circulator_stl.tex
|
|
% +------------------------------------------------------------------------+
|
|
% | Requirements for circulators in analogy to STL iterators.
|
|
% | Adaptors between circulators and iterators.
|
|
% | Proposal for CGAL.
|
|
% |
|
|
% | 27.01.1997 Lutz Kettner
|
|
% | Adapted from the iterator chapter and the circulator
|
|
% | chapter of the CGAL Reference Manual circulator.tex R1.3.
|
|
% |
|
|
% | $Revision$
|
|
% | $Date$
|
|
% +------------------------------------------------------------------------+
|
|
|
|
\cleardoublepage
|
|
\chapter{Circulators}
|
|
\label{sectionCirculatorWarning}
|
|
|
|
Circulators are quite similar to iterators that are described in
|
|
Chapter~\ref{chapterIterators}. Circulators are a generalization of
|
|
pointers that allow a programmer to work with different circular data
|
|
structures like a ring list in a uniform manner. Please note that
|
|
circulators are not part of the \stl, but of \cgal. A summary of the
|
|
requirements for circulators is presented here. Thereafter, a couple
|
|
of adaptors are described that convert between iterators and
|
|
circulators. For the complete description of the requirements, support
|
|
to develop own circulators, and the adaptors please refer to the \cgal\
|
|
Reference Manual: Part 3: Support Library.
|
|
|
|
The specialization on circular data structures gives the reason for
|
|
the slightly different requirements for circulators than for
|
|
iterators. A circular data structure has no natural past-the-end
|
|
value. In consequence, a container supporting circulators will not
|
|
have an {\tt end()}-member function, only a {\tt begin()}-member
|
|
function. The semantic of a range is different for a circulator $c$:
|
|
The range $\left[c, c\right)$ denotes the sequence of all elements in
|
|
the data structure. For iterators, this range would be empty. A
|
|
separate test for an empty sequence has been added to the
|
|
requirements. A comparison $c ==$ {\tt NULL} for a circulator $c$
|
|
tests whether the data structure is empty or not. As for
|
|
\CC, we recommend the use of 0 instead of {\tt NULL}. An example
|
|
function demonstrates a typical use of circulators. It counts the
|
|
number of elements in the range $\left[c, d\right)$:
|
|
|
|
\begin{verbatim}
|
|
template <class Circulator, class Size>
|
|
void count( Circulator c, Circulator d, Size& n) {
|
|
n = 0;
|
|
if ( c != 0) {
|
|
do {
|
|
++n;
|
|
} while (++c != d);
|
|
}
|
|
}
|
|
\end{verbatim}
|
|
|
|
Given a circular data structure $S$, the expression {\tt
|
|
count(}$S${\tt.begin(),} $S${\tt.begin(), counter)} returns the
|
|
number of elements of $S$ in the {\tt counter} parameter.
|
|
|
|
As for iterators, circulators come in different flavors. There are
|
|
{\em forward, bidirectional\/} and {\em random access circulators}.
|
|
They are either {\em mutable} or {\em constant}. The past-the-end
|
|
value is not applicable for circulators.
|
|
|
|
{\bf Reachability:}
|
|
A circulator $d$ is called {\em reachable} from a circulator $c$ if
|
|
and only if there is a finite sequence of applications of
|
|
\ccStyle{operator++} to $c$ that makes $c == d$. If $c$ and $d$ refer
|
|
to the same non-empty data structure, then $d$ is reachable from $c$,
|
|
and $c$ is reachable from $d$. In particular, any circulator $c$
|
|
referring to a non-empty data structure will return to itself after a
|
|
finite sequence of applications of \ccStyle{operator++} to $c$.
|
|
|
|
{\bf Range:}
|
|
Most of the library's algorithmic templates that operate on data
|
|
structures have interfaces that use {\em ranges}. A range is a pair of
|
|
circulators that designate the beginning and end of the computation. A
|
|
range $\left[c, c\right)$ is a {\em full range}; in general, a range
|
|
$\left[c, d\right)$ refers to the elements in the data structure
|
|
starting with the one pointed to by $c$ and up to but not including
|
|
the one pointed to by $d$. Range $\left[c, d\right)$ is valid if and
|
|
only if both refer to the same data structure. The result of the
|
|
application of the algorithms in the library to invalid ranges is
|
|
undefined.
|
|
|
|
{\bf Warning:} Please note that the definition of a range is different
|
|
to that of iterators. An interface of a data structure must declare
|
|
whether it works with iterators, circulators, or both. \stl\ algorithms
|
|
always specify only iterators in their interfaces. A range $\left[c,
|
|
d\right)$ of circulators used in an interface for iterators will
|
|
work as expected as long as $c\; !\!= d$. A range $\left[c, c\right)$ will
|
|
be interpreted as the empty range like for iterators, which is
|
|
different than the full range that it should denote for circulators.
|
|
|
|
Algorithms could be written to support both, iterators and
|
|
circulators, in a single interface. Here, the range $\left[c,
|
|
c\right)$ would be interpreted correctly. For more information how
|
|
to program functions with this behavior, please refer to the \cgal\
|
|
Reference Manual.
|
|
|
|
\medskip
|
|
|
|
As we said in the introduction, we are a little bit sloppy in the
|
|
presentation, in order to make it easier to understand. A class is
|
|
said to be a circulator if it fulfills a set of requirements. In the
|
|
following sections we do not present the requirements, but we state
|
|
properties that are true, if the requirements are fulfilled. The
|
|
difference is best seen by an example: We write that the return value
|
|
of the test for equality returns a \ccStyle{bool}. The requirement is
|
|
only that the return value is convertible to \ccStyle{bool}.
|
|
|
|
|
|
\begin{ccHtmlClassFile}{Circulator.html}{Requirements for Circulators}
|
|
\begin{ccClass}{Circulator}
|
|
|
|
\ccSection{Forward Circulator}
|
|
|
|
\ccDefinition
|
|
|
|
A class \ccClassName\ that satisfies the requirements of a forward circulator
|
|
for the value type \ccStyle{T}, supports the following operations.
|
|
|
|
\ccCreation
|
|
\ccCreationVariable{c}
|
|
%\ccSetThreeColumns{Circulator&}{int n + Circulator d}{}
|
|
%\ccSetThreeColumns{difference_type}{difference_type n += d}{}
|
|
\ccPropagateThreeToTwoColumns
|
|
|
|
\ccConstructor{Circulator();}
|
|
{}
|
|
|
|
\ccConstructor{Circulator(const Circulator& d);}
|
|
{}
|
|
|
|
\ccOperations
|
|
|
|
\ccMethod{bool operator=(const Circulator &d);}
|
|
{Assignment.}
|
|
|
|
\ccMethod{bool operator==(NULL) const;}
|
|
{Test for emptiness.}
|
|
|
|
\ccMethod{bool operator!=(NULL) const;}
|
|
{Test for non-emptiness. The result is the same as \ccStyle{!(c == NULL)}.}
|
|
|
|
\ccMethod{bool operator==(const Circulator &d) const;}
|
|
{Test for equality: Two circulators are equal if they refer to the same item.}
|
|
|
|
\ccMethod{bool operator!=(const Circulator &d) const;}
|
|
{Test for inequality. The result is the same as \ccStyle{!(c == d)}.}
|
|
|
|
\ccMethod{T& operator*();}
|
|
{Returns the value of the circulator.
|
|
If \ccClassName\ is mutable \ccStyle{*c = t} is valid.
|
|
\ccPrecond \ccVar\ is dereferenceable.}
|
|
|
|
\ccMethod{Circulator& operator++();}
|
|
{Prefix increment operation.
|
|
\ccPrecond \ccVar\ is dereferenceable. \ccPostcond \ccVar\ is dereferenceable.}
|
|
|
|
\ccMethod{const Circulator& operator++(int);}
|
|
{Postfix increment operation. The result is the same as that of
|
|
\ccStyle{Circulator tmp = c; ++c; return tmp;}~.}
|
|
|
|
\end{ccClass}
|
|
|
|
|
|
\ccHtmlNoClassLinks
|
|
\ccHtmlNoClassIndex
|
|
\begin{ccClass}{Circulator}
|
|
|
|
\ccSection{Bidirectional Circulator}
|
|
|
|
\ccDefinition
|
|
|
|
A class \ccClassName\ that satisfies the requirements of a bidirectional
|
|
circulator for the value type \ccStyle{T}, supports the following operations
|
|
in addition to the operations supported by a forward circulator.
|
|
|
|
\ccCreationVariable{c}
|
|
\ccOperations
|
|
|
|
\ccMethod{Circulator& operator--();}
|
|
{Prefix decrement operation.
|
|
\ccPrecond \ccVar\ is dereferenceable. \ccPostcond \ccVar\
|
|
is dereferenceable.}
|
|
|
|
\ccMethod{const Circulator& operator--(int);}
|
|
{Postfix decrement operation. The result is the same as that of
|
|
\ccStyle{Circulator tmp = c; --c; return tmp;}~.}
|
|
|
|
\end{ccClass}
|
|
|
|
|
|
\ccHtmlNoClassLinks
|
|
\ccHtmlNoClassIndex
|
|
\begin{ccClass}{Circulator}
|
|
|
|
\ccSection{Random Access Circulator}
|
|
\label{sectionRandomAccessCirculatorRequ}
|
|
|
|
\ccDefinition
|
|
|
|
A class \ccClassName\ that satisfies the requirements of a random access
|
|
Circulator for the value type \ccStyle{T}, supports the following operations
|
|
in addition to the operations supported by a bidirectional Circulator.
|
|
|
|
\ccCreationVariable{c}
|
|
|
|
\ccOperations
|
|
|
|
\ccMethod{Circulator& operator+=(int n);}
|
|
{The result is the same as if the prefix increment operation
|
|
was applied $n$ times, but it is computed in constant time.}
|
|
|
|
\ccMethod{Circulator operator+(int n);}
|
|
{Same as above, but returns a new circulator.}
|
|
|
|
\renewcommand{\ccTagRmEigenClassName}{\ccTrue}
|
|
\ccFunction{Circulator operator+(int n, Circulator c);}
|
|
{Same as above.}
|
|
\renewcommand{\ccTagRmEigenClassName}{\ccFalse}
|
|
|
|
\ccMethod{Circulator& operator-=(int n);}
|
|
{The result is the same as if the prefix decrement operation
|
|
was applied $n$ times, but it is computed in constant time.}
|
|
|
|
\ccMethod{Circulator operator-(int n);}
|
|
{Same as above, but returns a new circulator.}
|
|
|
|
|
|
\ccMethod{T& operator[](int n);}
|
|
{Returns \ccStyle{*(c + n)}.}
|
|
|
|
\ccMethod{int operator-(const Circulator& d) const;}
|
|
{returns the difference between the two circulators within the
|
|
interval $\left[ 1-s , s-1 \right]$ for a sequence size $s$. The
|
|
difference for a fixed circulator \ccVar\ (or $d$) with all other
|
|
circulators $d$ (or \ccVar) is a consistent ordering of the elements
|
|
in the data structure. There has to be a minimal circulator
|
|
$d_{\mbox{\footnotesize min}}$ for which the difference \ccVar $-
|
|
d_{\mbox{\footnotesize min}}$ to all other circulators \ccVar\ is
|
|
non negative.}
|
|
|
|
\ccMethod{Circulator min_circulator() const;}
|
|
{Returns the minimal circulator $c_{\mbox{\footnotesize min}}$ in
|
|
constant time. If $c$ has a singular value, a singular value is
|
|
returned.}
|
|
|
|
There are no comparison operators required.
|
|
\end{ccClass}
|
|
\end{ccHtmlClassFile}
|
|
|
|
% +-----------------------------------------------------+
|
|
\newpage
|
|
\section{Adaptor: Container with Iterators from Circulator}
|
|
\label{sectionContainerFromCirc}
|
|
|
|
Algorithms working on iterators cannot be applied to circulators in
|
|
full generality, only to subranges (see the warning in
|
|
Section~\ref{sectionCirculatorWarning}). The following adaptors
|
|
convert circulators to iterators (with the unavoidable space and time
|
|
drawback) to reestablish this generality.
|
|
|
|
\begin{ccClassTemplate}{Container_from_circulator<C>}
|
|
|
|
\ccDefinition
|
|
|
|
The adaptor \ccClassTemplateName\ is a class that converts any
|
|
circulator type \ccStyle{C} to a kind of container class, i.e.~a class
|
|
that provides an \ccStyle{iterator} and a \ccStyle{const_iterator}
|
|
type and two member functions -- \ccStyle{begin()} and \ccStyle{end()}
|
|
-- that return the appropriate iterators. In analogy to \stl\
|
|
container classes these member functions return a \ccc{const_iterator}
|
|
in the case that the container itself is constant and a mutable
|
|
\ccc{iterator} otherwise.
|
|
|
|
\ccInclude{CGAL/circulator.h}
|
|
|
|
\ccTypes
|
|
|
|
\ccNestedType{Circulator}{the template argument \ccc{C}.}
|
|
|
|
\ccNestedType{iterator}{}
|
|
\ccGlue
|
|
\ccNestedType{const_iterator}{}
|
|
|
|
\ccCreation
|
|
|
|
\ccCreationVariable{container}
|
|
%\ccSetTwoColumns{Circulator}{}
|
|
|
|
\ccConstructor{Container_from_circulator();}{%
|
|
the resulting iterators will have a singular value.}
|
|
|
|
\ccConstructor{Container_from_circulator(const C& c);}{%
|
|
the resulting iterators will have a singular value if the circulator
|
|
\ccStyle{c} is singular.}
|
|
|
|
\ccOperations
|
|
%\ccSetThreeColumns{const_iterator}{container.begin() const;}{}
|
|
|
|
\def\ccTagRmTrailingConst{\ccFalse}
|
|
|
|
\ccMethod{iterator begin();}{the start iterator.}
|
|
\ccGlue
|
|
\ccMethod{const_iterator begin() const;}{the start const iterator.}
|
|
\ccGlue
|
|
\ccMethod{iterator end();}{the past-the-end iterator.}
|
|
\ccGlue
|
|
\ccMethod{const_iterator end() const;}{the past-the-end const iterator.}
|
|
\def\ccTagRmTrailingConst{\ccTrue}
|
|
|
|
The \ccc{iterator} and \ccc{const_iterator} types are of the
|
|
appropriate iterator category. In addition to the operations required
|
|
for their category, they have a member function
|
|
\ccc{current_circulator()} that returns a circulator pointing to the
|
|
same position as the iterator does.
|
|
|
|
\ccExample
|
|
|
|
The generic {\tt reverse()} algorithm from the \stl\ can be used with an
|
|
adaptor if at least a bidirectional circulator {\tt c} is given.
|
|
|
|
\begin{ccExampleCode}
|
|
Circulator c; // c is assumed to be a bidirectional circulator.
|
|
CGAL::Container_from_circulator<Circulator> container(c);
|
|
reverse( container.begin(), container.end());
|
|
\end{ccExampleCode}
|
|
|
|
\ccImplementation
|
|
|
|
The forward and bidirectional iterator adaptors keep track of the
|
|
number of rounds a circulator has done around the ring-like data
|
|
structure. This is a kind of winding number. It is used to distinguish
|
|
between the start position and the end position which will be denoted
|
|
by the same circulator. This winding number is zero for the
|
|
\ccStyle{begin()}-iterator and one for the \ccStyle{end()}-iterator.
|
|
It is incremented whenever a circulator passes the \ccStyle{begin()}
|
|
position. Two iterators are equal if their internally used circulators
|
|
and winding numbers are equal. This is more general than necessary
|
|
since the \ccStyle{end()}-iterator is not supposed to move any more.
|
|
|
|
The random access iterator has to be able to compute the size of the
|
|
data structure. It is needed for the difference of a past-the-end
|
|
iterator and the begin iterator. Therefore, the constructor for the
|
|
random access iterator choose the minimal circulator for the internal
|
|
anchor position. The minimal circulator is part of the random access
|
|
circulator requirements, see
|
|
Section~\ref{sectionRandomAccessCirculatorRequ}.
|
|
|
|
\end{ccClassTemplate}
|
|
|
|
|
|
% +-----------------------------------------------------+
|
|
\newpage
|
|
|
|
\section{Adaptor: Circulator from Iterator}
|
|
\label{sectionCircFromIter}
|
|
|
|
To obtain circulators, one could use a container class like those in
|
|
the Standard Template Library (\stl) or a pair of \ccStyle{begin()}-,
|
|
\ccStyle{end()}-iterators and one of the following adaptors. The adaptor
|
|
for iterator pairs is described here, the adaptor for container classes
|
|
is described in the next section.
|
|
|
|
\begin{ccClassTemplate}{Circulator_from_iterator<I>}
|
|
|
|
\ccDefinition
|
|
|
|
The adaptor \ccClassTemplateName\ converts two iterators of type
|
|
\ccc{I}, a begin and a past-the-end value, to a circulator of equal
|
|
category. The iterator must be at least of the forward iterator
|
|
category. The circulator will be mutable or non-mutable according to
|
|
the iterator. Iterators provide no \ccc{size_type}. This adapter
|
|
assumes \ccc{std::size_t} instead.
|
|
|
|
\ccInclude{CGAL/circulator.h}
|
|
|
|
\ccTypes
|
|
%\ccSetThreeColumns{typedef const T&}{const_reference;}{}
|
|
|
|
\ccUnchecked\ccTypedef{typedef I iterator;}{}
|
|
|
|
In addition all types required for circulators are provided.
|
|
|
|
\ccCreation
|
|
\ccCreationVariable{c}
|
|
|
|
\ccConstructor{Circulator_from_iterator();}{%
|
|
a circulator \ccVar\ with a singular value.}
|
|
|
|
\ccConstructor{Circulator_from_iterator(const I& begin, const I& end);}{%
|
|
a circulator \ccVar\ initialized to refer to the element
|
|
\ccStyle{*begin} in a range {\tt [}\ccStyle{begin}{\tt
|
|
,}\ccStyle{end}{\tt )}.
|
|
The circulator \ccVar\ contains a singular value if \ccStyle{begin==end}.
|
|
}
|
|
|
|
\ccOperations
|
|
|
|
The adaptors conform to the requirements of the different circulator
|
|
categories. An additional member function \ccc{current_iterator()} is
|
|
provided that returns the current iterator that points to the same
|
|
position as the circulator does.
|
|
|
|
\ccExample
|
|
|
|
This program uses two adaptors, iterators to circulators and back to
|
|
iterators. It applies an \stl\ sort algorithm on a \stl\ vector with three
|
|
elements. The resulting vector will be {\tt [2 5 9]} as it will be
|
|
checked by the assertions. The program is part of the \cgal\
|
|
distribution.
|
|
|
|
\ccIncludeVerbatim{Use_of_Stl/circulator_prog1.C}
|
|
|
|
Another example usage for this adaptor are random access circulators
|
|
over the built-in C arrays. Given an array of type {\tt T*} with a
|
|
begin pointer {\tt b} and a past-the-end pointer {\tt e} the adaptor
|
|
\ccStyle{Circulator_from_iterator< T*> c( b,e)} is a random circulator
|
|
\ccStyle{c} over this array.
|
|
|
|
\end{ccClassTemplate}
|
|
|
|
% +-----------------------------------------------------+
|
|
\newpage
|
|
\section{Adaptor: Circulator from Container}
|
|
\label{sectionCircFromContainer}
|
|
|
|
To obtain circulators, one could use a container class like those in the
|
|
Standard Template Library (\stl) or a pair of \ccStyle{begin()}-,
|
|
\ccStyle{end()}-iterators and one of the provided adaptors here.
|
|
The adaptor for iterator pairs is described in the previous section,
|
|
the adaptor for container classes is described here.
|
|
|
|
\begin{ccClassTemplate}{Circulator_from_container<C>}
|
|
|
|
\ccHtmlCrossLink{Const_circulator_from_container}
|
|
\ccHtmlCrossLink{Const_circulator_from_container<C>}
|
|
\ccIndexMainItemDef[C]{Const_circulator_from_container<C>}
|
|
|
|
\ccDefinition
|
|
|
|
The adaptor \ccClassTemplateName\ provides a circulator for an \stl\
|
|
container $C$ of equal category as the iterator provided by the container.
|
|
The iterator must be at least of the forward iterator
|
|
category. The corresponding non-mutable circulator is called
|
|
\ccc{Const_circulator_from_container<C>}.
|
|
|
|
The container type \ccc{C} is supposed to conform to the \stl\
|
|
requirements for container (i.e.~to have a \ccStyle{begin()} and an
|
|
\ccStyle{end()} iterator as well as the local types
|
|
\ccStyle{reference}, \ccStyle{const_reference}, \ccStyle{value_type},
|
|
\ccStyle{size_type}, and \ccStyle{difference_type}).
|
|
|
|
\ccInclude{CGAL/circulator.h}
|
|
|
|
\ccTypes
|
|
%\ccSetThreeColumns{typedef container::const_reference}{const_reference;}{}
|
|
|
|
All types required for circulators are provided.
|
|
|
|
\ccCreation
|
|
\ccCreationVariable{c}
|
|
|
|
\ccConstructor{Circulator_from_container();}{%
|
|
a circulator \ccVar\ with a singular value.}
|
|
|
|
\ccConstructor{Circulator_from_container(C* container);}{%
|
|
a circulator \ccVar\ initialized to refer to the first element in
|
|
\ccStyle{container}, i.e. \ccStyle{container.begin()}.
|
|
The circulator \ccVar\ contains a singular value if the
|
|
\ccStyle{container} is empty.
|
|
}
|
|
|
|
\ccConstructor{Circulator_from_container(C* container, C::iterator i);}{%
|
|
a circulator \ccVar\ initialized to refer to the element \ccStyle{*i} in
|
|
\ccStyle{container}. \ccPrecond \ccStyle{*i} is dereferenceable and refers
|
|
to \ccStyle{container}.
|
|
}
|
|
|
|
\ccOperations
|
|
|
|
The adaptors conform to the requirements of the different circulator
|
|
categories. An additional member function \ccc{current_iterator()} is
|
|
provided that returns the current iterator that points to the same
|
|
position as the circulator does.
|
|
|
|
\ccExample
|
|
|
|
This program uses two adaptors, container to circulators and back to
|
|
iterators. It applies an \stl\ sort algorithm on a \stl\ vector with three
|
|
elements. The resulting vector will be {\tt [2 5 9]} as it will be
|
|
checked by the assertions. The program is part of the \cgal\
|
|
distribution.
|
|
|
|
\ccIncludeVerbatim{Use_of_Stl/circulator_prog2.C}
|
|
|
|
\end{ccClassTemplate}
|
|
|
|
% EOF
|