Initial revision

This commit is contained in:
Mariette Yvinec 1999-09-06 12:31:16 +00:00
parent ca20f09a33
commit bcfbe32c19
62 changed files with 19209 additions and 0 deletions

View File

@ -0,0 +1,163 @@
Circulator Package: Release changes:
---------------------------------------------------------------------
3.4 (02 Sep 1999)
Unnecessary typenames removed from iterator_test.any. Mariette
Yvinec (INRIA) takes over the maintenance of this package with
this release.
3.3 (02 Sep 1999)
One more patch for MSC_VCC.
3.2 (01 Sep 1999)
Changed to work with MSC_VCC.
3.1 (12 Aug 1999)
Fully reworked version. The package relies now on template parameter
defaults and std::iterator_traits. For compilers yet not supporting
std::iterator_traits, the old circulator.h file of CGAL R2.0 is
distributed for compatibility reasons under the name
circulator_compat.h
The use of std::iterator_traits allowed me to simplify many parts of
this package. An adapter class was provided for each iterator/circulator
category. This is now unified to one adapter for all categories,
deriving its actual category with the std::iterator_traits.
Furthermore, many internal implementations have been simplified.
Important, the package is nevertheless backwards compatible.
The documentation is new. It is separated into a user manual part and
and a reference part, but for the transition period both parts stay
in one chapter. The manual needs the cc_manual tools R3.2 (not yet
released) for formatting.
2.6 (22 May 1999)
Typos before CGAL R2.0 fixed.
2.5 (29 Apr 1999)
circulator_bases.h include cstddef now.
2.4 (07 Apr 1999)
Fixes std:: prefix for base classes to CGAL_STD:: in
circulator_base.h. std:: namespace added for sort().
2.3 (26 Mar 1999)
A single missing std:: for a vector fixed.
2.2 (25 Mar 1999)
A few std:: fixed, derivation from std::forward_iterator etc.
removed and some CGAL_TEMPLATE_NULL introduced for the traits
classes.
2.1 (06 Mar 1999)
Standard headers, std namespace and CGAL namespace.
1.15 (07 Oct 1998)
Bug with respect to value_type friend function and value_type type
fixed. Warnings about CGAL_NULL_TYPE with egcs fixed.
1.14 (03 Jun 1998)
A few changes in the doc. Chapter entry in header.
1.13 (09 Apr 1998)
Spell checker.
1.12 (18 Mar 1998)
A few typename's in the examples removed. Run's with SGI CC-n32.
Problems with operator+ and SGI CC-64 fixed.
1.11 (18 Feb 1998)
A few typename's in inappropriate places removed. Run's with SGI CC-n32.
1.10 (05 Feb 1998)
Reorganized TeX files for the manual and minor changes in the manual.
1.9 (30 Jan 1998)
New cgal_test script. CGAL_circulator_distance has now difference_type
as return type. New function CGAL_iterator_distance working on both,
iterators and circulators. New header file CGAL/circulator_bases.h
that includes only circulator tags and base classes.
1.8 (06 Jan 1998)
A missing typename inserted for egcs.
1.7 (19 Dec 1997)
Tested with egcs. New subsections with \ccSeeAlso.
1.6 (12 Dec 1997)
The container-from-circulator adaptor classes cannot be used for
non-mutable circulators if the C++ compiler has the
CGAL_CFG_NO_LAZY_INSTANTIATION bug. However, the g++ works fine,
only some warnings about const to non-const conversions.
The related tests for the container-from-circulator adaptors are
now guarded with the CGAL_CFG_NO_LAZY_INSTANTIATION flag.
All scope expressions with the typename keyword where necessary
(not tested yet). Include file protection as provided with the script.
Circulators work now with iterator traits! Tested with SGI CC 7.2.
1.5 (11 Dec 1997)
Circulator functions matches now appropriately to the circulator tags
instead of the iterator tags as previously. Bug reported by Wieger
while testing with Borland. The problem with the non-const iterator
adaptor in the container_from_circulator adaptor classes cannot
be fixed. The g++ is known to warn about conversion from const
to non-const references even though the class is actually not used.
SunPro and SGI C++ works fine. The Borland now reports error messages.
1.4 (09 Dec 1997)
Includes now the TeX documentation for the support library and the
stl_extension manual. Includes new package field in the header.
The dependency on Gnu and SunPro C++ has been reduced.
The adaptors for circulators for a struct, class or array which
uses the member function pointer as a template argument (could be
recognized as those classes with an _mptr suffix) have been removed.
They were even no longer documented in R1.3.
1.3 (25 Nov 1997)
Compliant to recent organisational conventions that the examples
directory gets tested and that there is a new demo directory.
Changes compared to CGAL 0.9:
New features are: strong support of size_type for circulators.
Base classes have additional template argument for that.
Support of local types for pointer and const_pointer.
All circulators and iterators provide operator->() if supported
by the compiler. The handling of the iterator category has been
changed such that the tags for circulators (which are derived
from the iterator tags) are been used. A new function
CBP_circulator_size computes the size of the range of two
circulators (i.e. the positive distance between both).

View File

@ -0,0 +1 @@
Circulator support and adaptors.

View File

@ -0,0 +1,87 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Assert_circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{Assert_circulator}
\ccHtmlCrossLink{Assert_iterator}
\ccHtmlCrossLink{Assert_circulator_or_iterator}
\ccHtmlCrossLink{Assert_input_category}
\ccHtmlCrossLink{Assert_output_category}
\ccHtmlCrossLink{Assert_forward_category}
\ccHtmlCrossLink{Assert_bidirectional_category}
\ccHtmlCrossLink{Assert_random_access_category}
\ccHtmlIndexC[function]{Assert_iterator}
\ccHtmlIndexC[function]{Assert_circulator_or_iterator}
\ccHtmlIndexC[function]{Assert_input_category}
\ccHtmlIndexC[function]{Assert_output_category}
\ccHtmlIndexC[function]{Assert_forward_category}
\ccHtmlIndexC[function]{Assert_bidirectional_category}
\ccHtmlIndexC[function]{Assert_random_access_category}
\ccDefinition
The following assertions check at compile time if their argument
is of the kind as stated in the assertions name, i.e.~a circulator, an
iterator, or of a particular category, applicable for an iterator or a
circulator. Note that neither input nor output circulators exists.
\ccInclude{CGAL/circulator.h}
\def\ccTagTemplateInline{\ccTrue}
\ccSetThreeColumns{template <class IC> void}{X}{}
\ccGlobalFunction{template <class C>
void Assert_circulator( const C &c);}
\ccGlue
\ccGlobalFunction{template <class I>
void Assert_iterator( const I &i);}
\ccGlue
\ccGlobalFunction{template< class IC>
void Assert_circulator_or_iterator(const IC& i);}
\ccGlobalFunction{template <class I>
void Assert_input_category( const I &i);}
\ccGlue
\ccGlobalFunction{template <class I>
void Assert_output_category( const I &i);}
\ccGlue
\ccGlobalFunction{template <class IC>
void Assert_forward_category( const IC &ic);}
\ccGlue
\ccGlobalFunction{template <class IC>
void Assert_bidirectional_category( const IC &ic);}
\ccGlue
\ccGlobalFunction{template <class IC>
void Assert_random_access_category( const IC &ic);}
\def\ccTagTemplateInline{\ccFalse}
\ccSeeAlso
\ccc{Circulator_tag},
\ccc{Circulator_traits},
\ccc{query_circulator_or_iterator},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,244 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefConcept}{Circulator}
\ccDefinition
\ccHtmlCrossLink{Forward_circulator}
\ccHtmlCrossLink{Bidirectional_circulator}
\ccHtmlCrossLink{Random_access_circulator}
\ccHtmlIndexC[concept]{Forward_circulator}
\ccHtmlIndexC[concept]{Bidirectional_circulator}
\ccHtmlIndexC[concept]{Random_access_circulator}
Note: This specification is a revised version based on the \CC\
Standard~\cite{c-isplc-98}, which is available now. In particular,
iterator traits are now assumed and required.
Iterators in the \stl\ were tailored for linear sequences. The
specialization for circular data structures leads to slightly
different requirements which we will summarize in the {\em
circulators\/} concept. The main difference is that 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. The semantic of a circulator range differs from the semantic
of an iterator range: For a circulator $c$ the range $\left[c,
c\right)$ denotes the sequence of all elements in the data
structure. For iterators, this range defines the empty sequence. A
separate test for an empty sequence has been added to the circulator
requirements: A comparison $c ==$ {\tt NULL} for a circulator $c$ is
true for an empty sequence. As for \CC, we recommend the use of 0
instead of {\tt NULL}.
Similar to \stl\ iterators, we distinguish between forward,
bidirectional, and random access circulators\footnote{Input
circulators are a contradiction, since any circulator is supposed to
return once to itself. Output circulators are not supported since
they would be indistinguishable from output iterators.}. Most
requirements for circulators are equal to those for iterators. We
present the changes, please refer to \cite[chapter 18]{ms-strg-96} or
\cite{c-isplc-98} for the iterator requirements.
{\bf Past-the-end value:} There is no past-the-end value for circulators.
{\bf Singular values:} There are no singular values for
circulators\footnote{Since circulators must be implemented as classes
anyway, there is no need to allow singular values for them. An
un-initalized circulator does not have a singular value, but is
supposed to refer to an empty sequence.}.
{\bf Empty sequence:} The comparison $c ==$ {\tt NULL} (or $c == 0$)
for a circulator $c$ is {\tt true} if $c$ denotes an empty sequence,
and {\tt false} otherwise.
{\bf Dereferenceable values:} A circulator that does not denote an
empty sequence is dereferenceable.
{\bf Reachability:} Each dereferenceable circulator can reach itself
with a finite and non-empty sequence of applications of \ccc{operator++}.
{\bf Ranges:} For any circulator $c$ the range $\left[c, c\right)$ is
a valid range. If the circulator refers to an empty sequence, the range
$\left[c, c\right)$ denotes the empty range. Otherwise the circulator
is dereferenceable and the range $\left[c, c\right)$ denotes the
sequence of all elements in the data structure. {\em Remark:} When a
circulator is used in a place of an iterator, like with an \stl\
algorithm, it will work as expected with the only exception that
the range $\left[c, c\right)$ denotes always the empty range. This is
not a requirement, but a consequence of the requirements
stated here and the fact that the \stl\ requirements for iterator
ranges are based on the {\tt operator++} and the {\tt operator==},
which we use for circulators as well. In principle, we face here the
difference between a {\tt while} loop and a {\tt do-while} loop.
{\bf Types:} For a circulator of type $C$ the following local types
are required:
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt C::value\_type} \> value type the circulator refers to.\\
{\tt C::reference} \> reference type used for the return type
of {\tt C::operator*()}.\\
{\tt C::pointer} \> pointer type used for the return type of
{\tt C::operator->()}.\\
{\tt C::size\_type} \> unsigned integral type that can hold
the size of a sequence\\
{\tt C::difference\_type} \> signed integral type that can hold
the distance between two circulators.\\
{\tt C::iterator\_category} \> circulator category.
\end{tabbing}
\subsection*{Forward Circulators}
In the following, we assume that {\tt a} and {\tt b} are circulators
of type {\tt C}, {\tt r} is of type {\tt C\&} (is assignable), and
{\tt T} denotes the the value type of {\tt C}. Let {\tt D} be the
distance type of {\tt C}. As for \CC, we recommend the use of 0
instead of {\tt NULL}.
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt C()} \> a circulator equal to \ccc{NULL} denoting an
empty sequence.\\
{\tt a == NULL} \> Returns {\tt true} if {\tt a} denotes an empty
sequence, {\tt false} otherwise\footnote{For
simplicity, {\tt NULL == a} is not required.}. The\\
\> behavior for comparisons with pointer-like
values different than {\tt NULL} \\
\> is undefined%
\footnote{A runtime assertion is
recommended.}.\\
{\tt a != NULL} \> Returns {\tt !(a == NULL)}. \\
{\tt ++r} \> Like for forward iterators, but a dereferenceable
circulator {\tt r} will always\\
\> be dereferenceable after {\tt ++r} (no
past-the-end value). {\em Precondition:} {\tt
r} \\
\> does not denote an empty sequence.\\
{\tt r++} \> Same as for {\tt ++r}.\\
{\tt C::iterator\_category} \> circulator category {\tt
CBP\_Forward\_circulator\_tag}.
\end{tabbing}
\subsection*{Bidirectional Circulators}
The same requirements as for the forward circulators hold for
bidirectional iterators with the following change of the iterator
category:
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt C::iterator\_category} \> circulator category {\tt
CBP\_Bidirectional\_circulator\_tag}.
\end{tabbing}
\subsection*{Random Access Circulators}
\label{sectionMinCircleRequ}
The same requirements as for the bidirectional circulators hold for
random access iterators with the following changes and extensions.
The idea of a random access extends naturally to circulators using
equivalence classes modulus the length of the sequence. With this in
mind, the additional requirements for random access iterators hold
also for random access circulators. The only exception is that the
random access iterator is required to provide a total order on the
sequence, which a circulator cannot provide\footnote{One might define
an order by splitting the circle at a fixed point, e.g.~the start
circulator provided from the data structure. This is what the
adaptor to iterators will do. Nonetheless, we do not require this
for circulators.}.
The difference of two circulators is not unique as for iterators. A
reasonable requirement demands that the result is in a certain range
$[1-\mbox{{\it size, size}}-1]$, where {\it size} is the size of the
sequence, and that whenever a circulator {\tt a} is fixed that
the differences with all other circulators of the sequence form a
consistent ordering.
For the adaptor to iterators a minimal circulator
$d_{\mbox{\footnotesize min}}$ is required for which the difference $c
- d_{\mbox{\footnotesize min}}$ to all other circulators $c$ is non
negative.
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt b - a} \> limited range and consistent ordering
as explained above.\\
{\tt a.min\_circulator()} \> returns the minimal circulator from the
range $[a,a)$.\\
{\tt C::iterator\_category} \> circulator category {\tt
CBP\_Random\_access\_circulator\_tag}.
\end{tabbing}
\subsection*{Const Circulators}
As with iterators, we distinguish between circulators and const
circulators. The expression {\tt *a = t} with {\tt t} of type {\tt T}
is valid for mutable circulators. It is invalid for const circulators.
\subsection*{Circulators in Container Classes}
For a container {\tt x} of type {\tt X} that supports circulators
{\tt c} the following naming convention is recommended:
\begin{tabbing}
\ccTexHtml{{\tt X::Const\_circulator}\ \ \ \ \= \kill}{}
{\tt X::Circulator} \> the type of the mutable circulator.\\
{\tt X::Const\_circulator} \> the type of the const circulator.\\
{\tt c = x.begin()} \> the start circulator of the sequence.
It is of type {\tt X::Circulator} for a \\
\> mutable container or {\tt X::Const\_circulator} for
a const container. There \\
\> must not be an {\tt end()} member function.
\end{tabbing}
If a container will support iterators and circulators, the member
function {\tt circulator\_begin()} is proposed. However, the support
of iterators and circulators simultaneously is not recommended, since
it would lead to fat interfaces. The natural choice should be
supported, the other concept will be available through adaptors.
\subsection*{Example}
A generic {\tt contains} function accepts a range of circulators and a
value. It returns \ccc{true} if the value is contained in the sequence
of items denoted by the range of circulators. As usual for circular
structures, a {\tt do}-{\tt while} loop is preferable, such that for
the specific input, {\tt c == d}, all elements in the sequence are
reached. Note that the example simplifies if the sequence is known to
be non-empty, which is for example the common case in polyhedral
surfaces where vertices and facets have at least one incident edge.
\begin{ccExampleCode}
template <class Circulator, class T>
bool contains( Circulator c, Circulator d, const T& value) {
if (c != 0) {
do {
if (*c == value)
return true;
} while (++c != d);
}
return false;
}
\end{ccExampleCode}
\end{ccRefConcept}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,88 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Forward_circulator_from_container.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_from_container<C>}
\label{pageCircFromContainerRef}
\ccHtmlCrossLink{Const_circulator_from_container}
\ccHtmlCrossLink{Const_circulator_from_container<C>}
\ccHtmlIndexC[class]{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 adaptor conforms to the requirements of the corresponding
circulator category. An additional member function
\ccc{current_iterator()} returns the current iterator pointing to
the same position as the circulator does.
\ccSeeAlso
\ccc{Container_from_circulator},
\ccc{Circulator_from_iterator},
\ccc{Circulator}.
\ccExample
The following program composes two adaptor -- from a container to a
circulator and back to an iterator. It applies an \stl\ sort algorithm
on a \stl\ vector with three elements. The resulting vector will be
{\tt [2 5 9]} as it is checked by the assertions. The program is
part of the \cgal\ distribution.
\ccIncludeExampleCode{examples/Circulator/circulator_prog2.C}
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,90 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Forward_circulator_from_iterator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_from_iterator<I>}
\label{pageCircFromIterRef}
\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, const I& cur = begin);}{%
a circulator \ccVar\ initialized to refer to the element
\ccStyle{*cur} in a range {\tt [}\ccStyle{begin}{\tt
,}\ccStyle{end}{\tt )}.
The circulator \ccVar\ contains a singular value if \ccStyle{begin==end}.
}
\ccConstructor{Circulator_from_iterator(
const Circulator_from_iterator<I,T,Size,Dist>& d,
const I& cur);}{%
a copy of circulator $d$ referring to the element \ccc{*cur}.
The circulator \ccVar\ contains a singular value if $d$ does so.
}
\ccOperations
The adaptor conforms to the requirements of the respective circulator
category. An additional member function \ccc{current_iterator()}
returns the current iterator pointing to the same position as the
circulator does.
\ccSeeAlso
\ccc{Container_from_circulator},
\ccc{Circulator_from_container},
\ccc{Circulator}.
\ccExample
The following program composes two adaptors -- from an iterator to a
circulator and back to an iterator. It applies an \stl\ sort algorithm
on a \stl\ vector containing three elements. The resulting vector will
be {\tt [2 5 9]} as it is checked by the assertions. The program is
part of the \cgal\ distribution.
\ccIncludeExampleCode{examples/Circulator/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{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,159 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Circulator_tag
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_tag}
\ccHtmlCrossLink{Iterator_tag}
\ccHtmlIndexC[class]{Iterator_tag}
\ccHtmlCrossLink{Forward_circulator_tag}
\ccHtmlIndexC[class]{Forward_circulator_tag}
\ccHtmlCrossLink{Bidirectional_circulator_tag}
\ccHtmlIndexC[class]{Bidirectional_circulator_tag}
\ccHtmlCrossLink{Random_access_circulator_tag}
\ccHtmlIndexC[class]{Random_access_circulator_tag}
\ccHtmlCrossLink{Circulator_base}
\ccHtmlCrossLink{Circulator_base<Category, T>}
\ccHtmlIndexC[class]{Circulator_base<Category, T>}
\ccHtmlCrossLink{Forward_circulator_base}
\ccHtmlCrossLink{Forward_circulator_base<T,Dist,Size>}
\ccHtmlIndexC[class]{Forward_circulator_base<T,Dist,Size>}
\ccHtmlCrossLink{Bidirectional_circulator_base}
\ccHtmlCrossLink{Bidirectional_circulator_base<T,Dist,Size>}
\ccHtmlIndexC[class]{Bidirectional_circulator_base<T,Dist,Size>}
\ccHtmlCrossLink{Random_access_circulator_base}
\ccHtmlCrossLink{Random_access_circulator_base<T,Dist,Size>}
\ccHtmlIndexC[class]{Random_access_circulator_base<T,Dist,Size>}
\ccHtmlCrossLink{Forward_circulator_ptrbase}
\ccHtmlCrossLink{Forward_circulator_ptrbase<T,Dist,Size>}
\ccHtmlIndexC[class]{Forward_circulator_ptrbase<T,Dist,Size>}
\ccHtmlCrossLink{Bidirectional_circulator_ptrbase}
\ccHtmlCrossLink{Bidirectional_circulator_ptrbase<T,Dist,Size>}
\ccHtmlIndexC[class]{Bidirectional_circulator_ptrbase<T,Dist,Size>}
\ccHtmlCrossLink{Random_access_circulator_ptrbase}
\ccHtmlCrossLink{Random_access_circulator_ptrbase<T,Dist,Size>}
\ccHtmlIndexC[class]{Random_access_circulator_ptrbase<T,Dist,Size>}
\ccDefinition
Iterators and circulators as well as different categories of
circulators can be distinguished with the use of discriminating
functions and the following circulator tags. A couple of base classes
simplify the task of writing own circulators. They declare the
appropriate tags and the local types needed for circulators.
To use the tags or base classes only it is sufficient to include:
\ccInclude{CGAL/circulator_bases.h}\\
\ccInclude{CGAL/circulator.h}
\ccSetOneOfTwoColumns{8cm}
\ccSetTwoOfThreeColumns{3.4cm}{4cm}
\ccHeading{Compile Time Tags}
\ccStruct{struct Circulator_tag {};}{any circulator.}
\ccGlue
\ccStruct{struct Iterator_tag {};}{any iterator.}
\ccStruct{struct Forward_circulator_tag {};}{
derived from \ccc{forward_iterator_tag}.}
\ccGlue
\ccStruct{struct Bidirectional_circulator_tag {};}{
derived from \ccc{bidirectional_iterator_tag}.}
\ccGlue
\ccStruct{struct Random_access_circulator_tag {};}{
derived from \ccc{random_access_iterator_tag}.}
\ccHeading{Base Classes}
\begin{ccTexOnly}
\def\dummySkipASD{\\\hspace*{18mm}}
\ccStruct{template < class Category,
class T,
class Dist = std::ptrdiff_t,
class Size = std::size_t,\dummySkipASD
class Ptr = T*,
class Ref = T&>
struct Circulator_base {};}{}
\end{ccTexOnly}
\begin{ccHtmlOnly}
\ccStruct{template < class Category,
class T,
class Dist = std::ptrdiff_t,
class Size = std::size_t,
class Ptr = T*,
class Ref = T&>
struct Circulator_base {};}{}
\end{ccHtmlOnly}
\ccRefLabel{CGAL::Circulator_base}
\ccSetTwoColumns{}{random access.}
\def\ccTagTemplateInline{\ccTrue}
\ccStruct{template <class T, class Dist, class Size>
struct Forward_circulator_base {};}{}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
struct Bidirectional_circulator_base {};}{}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
struct Random_access_circulator_base {};}{}
\def\ccTagTemplateInline{\ccFalse}
\ccSeeAlso
\ccc{query_circulator_or_iterator},
\ccc{Circulator_traits},
\ccc{Assert_circulator},\\
\ccc{CGAL_For_all},
\ccc{is_empty_range},
\ccc{Circulator}.
\ccExample
The above declarations can be used to distinguish between iterators
and circulators and between different circulator categories. The
assertions can be used to protect a templatized algorithm against
instantiations that do not fulfill the requirements. The following
example program illustrates both.
\ccIncludeExampleCode{examples/Circulator/circulator_prog3.C}
\ccImplementation
Since not all current compilers can eliminate the space needed for the
compile time tags even when deriving from them, we implement a variant
for each base class that contains a protected \ccc{void*} data member
called \ccc{_ptr}. Here, the allocated space in the derived
classes can be reused.
\ccSetOneOfTwoColumns{8.4cm}
\ccStruct{template <class T, class Dist, class Size>
class Forward_circulator_ptrbase {};}{%
forward circulator.}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
class Bidirectional_circulator_ptrbase {};}{%
bidirectional circulator.}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
class Random_access_circulator_ptrbase {};}{%
random access circulator.}
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,73 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Circulator_traits
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_traits<C>}
\ccDefinition
The circulator traits class distinguishes between circulators and
iterators. It defines a local type \ccc{category} that is identical to the
type \ccc{Circulator_tag} if the iterator category of the argument
\ccc{C} is a circulator category. Otherwise it is identical to the type
\ccc{Iterator_tag}.
The local type \ccc{iterator_category} gives the corresponding
iterator category for circulators, i.e.~one of
\ccc{forward_iterator_tag}, \ccc{bidirectional_iterator_tag}, or
\ccc{random_access_iterator_tag}.
The local type \ccc{circulator_category} gives the corresponding
circulator category for iterators, i.e.~one of
\ccc{Forward_circulator_tag}, \ccc{Bidirectional_circulator_tag}, or
\ccc{Random_access_circulator_tag}.
\ccInclude{CGAL/circulator.h}
\ccTypes
\ccTwo{Circulator_traits<C>:: \ \ circulator_category}{}
\ccNestedType{category}{either \ccc{Iterator_tag} or
\ccc{Circulator_tag}.}
\ccNestedType{iterator_category}{
corresponding iterator category for circulators.}
\ccNestedType{circulator_category}{
corresponding circulator category for iterator}
\ccExample
A generic function \ccc{bar} that distinguishes between a call with a
circulator range and a call with an iterator range:
\begin{ccExampleCode}
template <class I>
void bar( I i, I j, CGAL::Iterator_tag) {
CGAL::Assert_iterator(i);
// This function is called for iterator ranges [i,j).
}
template <class C>
void bar( C c, C d, CGAL::Circulator_tag) {
CGAL::Assert_circulator(c);
// This function is called for circulator ranges [c,d).
}
template <class IC>
void bar( IC i, IC j) { // calls the correct function
return bar( i, j, typename CGAL::Circulator_traits<IC>::category());
}
\end{ccExampleCode}
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,131 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Forward_container_from_circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{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. By analogy to \stl\
container classes these member functions return a const iterator in
the case that the container itself is constant and a mutable iterator
otherwise.
\ccInclude{CGAL/circulator.h}
\ccTypes
\ccTypedef{typedef C Circulator;}{}
\ccGlue
\ccNestedType{iterator}{}
\ccGlue
\ccNestedType{const_iterator}{}
\ccGlue
\ccNestedType{value_type}{}
\ccGlue
\ccNestedType{reference}{}
\ccGlue
\ccNestedType{const_reference}{}
\ccGlue
\ccNestedType{pointer}{}
\ccGlue
\ccNestedType{const_pointer}{}
\ccGlue
\ccNestedType{size_type}{}
\ccGlue
\ccNestedType{difference_type}{}
\ccCreation
\ccCreationVariable{container}
\ccSetTwoColumns{Circulator}{}
\ccConstructor{Container_from_circulator();}{%
any iterator of \ccc{container} will have a singular value.}
\ccConstructor{Container_from_circulator(const C& c);}{%
any iterator of \ccc{container} 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.
\ccSeeAlso
\ccc{Circulator_from_iterator},
\ccc{Circulator_from_container},
\ccc{Circulator}.
\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 iterator adaptor keeps track of the number of rounds a circulator
has done around the ring-like data structure (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 internally.
This winding number is zero for the \ccStyle{begin()}-iterator and one
for the \ccStyle{end()}-iterator. It is incremented whenever the
internal 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, which is
here still possible in a defined manner. However, for random access
iterators it is not supported.
The random access iterator has to be able to compute the size of the
data structure in constant time. This is for example needed if the
difference of the past-the-end iterator and the begin iterator is
taken, which is exactly the the size of the data structure.
Therefore, if the circulator is of the random-access category, the
adapter chooses the minimal circulator for the internal anchor
position. The minimal circulator is part of the random access
circulator requirements, see
Page~\pageref{sectionMinCircleRequ}. For the random
access iterator the adaptor implements a total ordering relation that
is currently not required for random access circulators.
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,68 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: For_all.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefMacro}{CGAL_For_all}
\ccHtmlCrossLink{CGAL_For_all_backwards}
\ccHtmlIndexC[macro]{CGAL_For_all_backwards}
\ccDefinition
In order to write algorithms that work with iterator ranges as well as
with circulator ranges we have to consider the difference of
representing an empty range. For iterators this is the range $[i,i)$,
while for circulators it would be \ccc{c == NULL}, the empty sequence test.
The function \ccc{is_empty_range} provides the necessary generic test
which accepts an iterator range or a circulator range and says whether
the range is empty or not.
\ccInclude{CGAL/circulator.h}
A macro \ccc{CGAL_For_all( i, j)} simplifies the writing of such simple
loops as the one in the example of the function \ccc{is_empty_range}.
\ccc{i} and \ccc{j} can be either iterators or circulators. The macro
loops through the range [\ccc{i, j}). It increments \ccc{i} until it
reaches \ccc{j}. The implementation looks like:
\ccc{CGAL_For_all(i,j)} \ \ \ccTexHtml{$\equiv$}{:=} \ \
\begin{minipage}[t]{0.74\textwidth}
\begin{verbatim}
for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range(i,j);
_circ_loop_flag;
_circ_loop_flag = ((++i) != (j))
)
\end{verbatim}
\end{minipage}%
Note that the macro behaves like a \ccc{for}-loop. It can be used with
a single statement or with a statement block. For bidirectional
iterators or circulators exist a backwards loop macro
\ccc{CGAL_For_all_backwards( i, j)} that decrements \ccc{j} until
it reaches \ccc{i}.
\ccSeeAlso
\ccc{iterator_distance},
\ccc{is_empty_range},
\ccc{Circulator_tag},
\ccc{Circulator_traits},\\
\ccc{Assert_circulator_or_iterator},
\ccc{Circulator}.
\end{ccRefMacro}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,41 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: circulator_distance
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{circulator_distance}
\ccDefinition
\ccSetThreeColumns{template <class C> sieze_t}{XXX}{}
The distance of a circulator $c$ to a circulator $d$ is the number of
elements in the range $\left[c, d\right)$. It is defined to be zero
for a singular circulator and it returns the size of the data
structure when applied to a range of the form $\left[c, c\right)$.
\ccInclude{CGAL/circulator.h}
\ccGlobalFunction{template <class C> C::difference_type
circulator_distance(C c, C d);}
\ccSeeAlso
\ccc{circulator_size},
\ccc{iterator_distance},
\ccc{is_empty_range},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,44 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: circulator_size
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{circulator_size}
\ccDefinition
\ccSetThreeColumns{template <class C> sieze_t}{XXX}{}
The size of a circulator is the size of the data structure it refers
to. It is zero for a circulator with singular value. The size can be
computed in linear time for forward and bidirectional circulators, and
in constant time for random access circulators using the minimal
circulator. The function \ccStyle{circulator_size(c)}
returns the circulator size. It uses the
\ccStyle{c.min_circulator()} function if $c$ is a random
access circulator.
\ccInclude{CGAL/circulator.h}
\ccGlobalFunction{template <class C> C::size_type circulator_size(C c);}
\ccSeeAlso
\ccc{circulator_distance},
\ccc{iterator_distance},
\ccc{is_empty_range},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,92 @@
% +------------------------------------------------------------------------+
% | CBP Reference Manual: intro.tex
% +------------------------------------------------------------------------+
% | Model for a new style of manuals in CBP
% |
% | 14.05.1998 Lutz Kettner
% +------------------------------------------------------------------------+
\section{Reference Pages for Circulator}
\section*{Summary}
The concept of iterators in \stl\ is tailored for linear sequences.
In contrast, circular sequences occur naturally in many combinatorial
and geometric structures. Examples are polyhedral surfaces and planar
maps, where the edges emanating from a vertex or the edges around a
facet form a circular sequence.
We provide several functions, classes and macros to assist working
with circulators: distance computation, adaptor classes converting
between circulators and iterators, base classes to ease implementing
circulators, and support for generic algorithms that work with
circulators as well as with iterators.
\subsection*{Concepts}
\ccRefIdfierPage{Circulator}\\
\ccc{Forward_circulator}\\
\ccc{Bidirectional_circulator}\\
\ccc{Random_access_circulator}
\subsection*{Classes}
\ccRefIdfierPage{CGAL::Container_from_circulator<C>}\\
\ccRefIdfierPage{CGAL::Circulator_from_iterator<I>}\\
\ccRefIdfierPage{CGAL::Circulator_from_container<C>}\\
\ccc{CGAL::Const_circulator_from_container<C>}
\ccRefIdfierPage{CGAL::Circulator_tag}\\
\ccc{CGAL::Iterator_tag}\\
\ccc{CGAL::Forward_circulator_tag}\\
\ccc{CGAL::Bidirectional_circulator_tag}\\
\ccc{CGAL::Random_access_circulator_tag}
\ccRefIdfierPage{CGAL::Circulator_base}\\
\ccc{CGAL::Forward_circulator_base}\\
\ccc{CGAL::Bidirectional_circulator_base}\\
\ccc{CGAL::Random_access_circulator_base}
\ccRefIdfierPage{CGAL::Circulator_traits<C>}
\subsection*{Functions}
\ccThree{random_access_iterator_tag}{}{page 999.}
\ccFunction{size_type CGAL::circulator_size ( C c);}
{\hfill \ccRefPage{CGAL::circulator_size}}\ccGlue
\ccFunction{difference_type CGAL::circulator_distance ( C c, C d);}
{\hfill \ccRefPage{CGAL::circulator_distance}}\ccGlue
\ccFunction{difference_type CGAL::iterator_distance ( IC ic1, IC ic2);}
{\hfill \ccRefPage{CGAL::iterator_distance}}\ccGlue
\ccFunction{bool CGAL::is_empty_range ( IC i, IC j);}
{\hfill \ccRefPage{CGAL::is_empty_range}}
\ccFunction{CGAL::Circulator_tag CGAL::query_circulator_or_iterator ( C c);}
{\hfill \ccRefPage{CGAL::query_circulator_or_iterator}}\ccGlue
\ccFunction{CGAL::Iterator_tag CGAL::query_circulator_or_iterator ( I i);}
{}
\ccFunction{void CGAL::Assert_circulator ( C c);}
{\hfill \ccRefPage{CGAL::Assert_circulator}}\ccGlue
\ccFunction{void CGAL::Assert_iterator ( I i);}
{}\ccGlue
\ccFunction{void CGAL::Assert_input_category ( I i);}
{}\ccGlue
\ccFunction{void CGAL::Assert_output_category ( I i);}
{}\ccGlue
\ccFunction{void CGAL::Assert_forward_category ( IC ic);}
{}\ccGlue
\ccFunction{void CGAL::Assert_bidirectional_category ( IC ic);}
{}\ccGlue
\ccFunction{void CGAL::Assert_random_access_category ( IC ic);}
{}\ccGlue
\ccFunction{void CGAL::Assert_circulator_or_iterator ( IC i);}
{}
\subsection*{Macros}
\ccc{CGAL_For_all(i,j)}\hfill \ccRefPage{CGAL_For_all}\\
\ccc{CGAL_For_all_backwards(i,j)}
%% EOF %%

View File

@ -0,0 +1,69 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: is_empty_range.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{is_empty_range}
\ccDefinition
In order to write algorithms that work with iterator ranges as well as
with circulator ranges we have to consider the difference of
representing an empty range. For iterators this is the range $[i,i)$,
while for circulators it would be \ccc{c == NULL}, the empty sequence test.
The function \ccc{is_empty_range} provides the necessary generic test
which accepts an iterator range or a circulator range and says whether
the range is empty or not.
\ccInclude{CGAL/circulator.h}
\ccSetThreeColumns{bool}{is_empty_range( IC i, IC j);}{}
\ccFunction{template< class IC>
bool is_empty_range( const IC& i, const IC& j);}{%
is \ccc{true} if the range [\ccc{i, j}) is empty,
\ccc{false} otherwise.
\ccPrecond \ccc{IC} is either a circulator or an iterator
type. The range [\ccc{i, j}) is valid.
}
\ccExample
The following function \ccc{process_all} accepts a range $\left[i,
j\right)$ of an iterator or circulator \ccc{IC} and process each
element in this range:
\begin{verbatim}
template <class IC>
void process_all( IC i, IC j) {
if (! CGAL::is_empty_range( i, j)) {
do {
process(*i);
} while (++i != j);
}
}
\end{verbatim}
\ccSeeAlso
\ccc{iterator_distance},
\ccc{CGAL_For_all},
\ccc{Circulator_tag},
\ccc{Circulator_traits},\\
\ccc{Assert_circulator_or_iterator},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,44 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: iterator_distance
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{iterator_distance}
\ccDefinition
\ccSetThreeColumns{iterator_traits<IC>::difference_type;}{XXX}{}
The following function returns the distance between either two
iterators or two circulators. The return type is {\tt ptrdiff\_t} for
compilers not supporting iterator traits yet.
\ccInclude{CGAL/circulator.h}
\ccGlobalFunction{template <class IC> iterator_traits<IC>::difference_type
iterator_distance(IC ic1, IC ic2);}
\ccSeeAlso
\ccc{circulator_size},
\ccc{circulator_distance},
\ccc{is_empty_range},
\ccc{Circulator_tag},\\
\ccc{Assert_circulator_or_iterator},
\ccc{CGAL_For_all},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,46 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: query_circulator_or_iterator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{query_circulator_or_iterator}
\ccDefinition
The following function distinguishes between circulators and
iterators. It is based on iterator traits~\cite{c-isplc-98,m-tnutt-95}
and \ccc{Circulator_traits}.
\ccInclude{CGAL/circulator.h}
\ccSetThreeColumns{Circulator_tag}{distance_type( C c);}{}
\ccFunction{template <class I>
Iterator_tag query_circulator_or_iterator( const I& i);}{
if the iterator category of \ccc{I} belongs to an iterator.}
\ccFunction{template <class C>
Circulator_tag query_circulator_or_iterator( const C& c);}{
if the iterator category of \ccc{C} belongs to a circulator.}
\ccSeeAlso
\ccc{Circulator_tag},
\ccc{Circulator_traits},
\ccc{Assert_circulator},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,391 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
\RCSdef{\circRev}{$Revision$}
\RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
\gdef\lciIfHtmlClassLinks{\lcFalse}
\gdef\lciIfHtmlRefLinks{\lcFalse}
\gdef\lciIfHtmlLinks{\lcFalse}
\chapter{Circulators}
\label{chapterCirculators}
\ccChapterRelease{\circRev. \ \circDate}\\
\ccChapterAuthor{Lutz Kettner}
An introduction to the concept of circulators is given here. A couple
of adaptors are presented that convert between iterators and
circulators. Some useful functions for circulators follow. This
chapter concludes with a discussion of the design decisions taken. For
the full description of the circulator requirements, the provided base
classes, the circulator tags, and the support for generic algorithms
that work for iterators as well as for circulators please refer to the
reference pages. Note that circulators are not part of \stl, but of \cgal.
% +-----------------------------------------------------+
\section{Introduction}
\label{sectionIntroduction}
\label{sectionCirculatorWarning}
The concept of iterators in \stl\ is tailored for linear
sequences~\cite{c-isplc-98,ms-strg-96}. In contrast, circular
sequences occur naturally in many combinatorial and geometric
structures. Examples are polyhedral surfaces and planar maps, where
the edges emanating from a vertex or the edges around a facet form a
circular sequence.
Since circular sequences cannot provide efficient iterators, we have
introduced the new concept of {\em circulators}. They share most of
the requirements with iterators, while the main difference is the lack
of a past-the-end position in the sequence. Appropriate adaptors are
provided between iterators and circulators to integrate circulators
smoothly into the framework of \stl. An example of a generic {\tt
contains} function illustrates the use of circulators. As usual for
circular structures, a {\tt do}-{\tt while} loop is preferable, such
that for the specific input, {\tt c == d}, all elements in the
sequence are reached.
\begin{ccExampleCode}
template <class Circulator, class T>
bool contains( Circulator c, Circulator d, const T& value) {
if (c != 0) {
do {
if (*c == value)
return true;
} while (++c != d);
}
return false;
}
\end{ccExampleCode}
\noindent
Three circulator categories are defined: forward, bidirectional and
random-access circulators. Given a circulator {\tt c}, the operation
{\tt *c} denotes the item the circulator refers to. The operation {\tt
++c} advances the circulator by one item and {\tt --c} steps a
bidirectional circulator one item backwards. For random-access
circulators {\tt c+n} advances the circulator {\tt n} steps. Two
circulators can be compared for equality.
Circulators have a different notion of reachability and ranges than
iterators. A circulator {\tt d} is called {\em reachable\/} from a
circulator {\tt c} if {\tt c} can be made equal to {\tt d} with
finitely many applications of the operator {\tt ++}. Due to the
circularity of the sequence this is always true if both circulators
refer to items of the same sequence. In particular, {\tt c} is always
reachable from {\tt c}. Given two circulators {\tt c} and {\tt d}, the
range {\tt [c,d)} denotes all circulators obtained by starting with
{\tt c} and advancing {\tt c} until {\tt d} is reached, but does not
include {\tt d}, for {\tt d} $\neq$ {\tt c}. So far it is the same
range definition as for iterators. The difference lies in the use of
{\tt [c,c)} to denote all items in the circular sequence, whereas for
an iterator {\tt i} the range {\tt [i,i)} denotes the empty range. As
long as {\tt c != d} the range {\tt[c,d)} behaves like an iterator
range and could be used in \stl\ algorithms. For circulators however,
an additional test {\tt c == NULL} is required that returns true if
and only if the circular sequence is empty. In this case the
circulator {\tt c} is said to have a {\em singular value}. As for
\CC, we recommend the use of 0 instead of {\tt NULL}.
Besides the conceptual cleanness, the main reason for inventing a new
concept with a similar intent as iterators is efficiency. An iterator
is supposed to be a light-weight object -- merely a pointer and a
single indirection to advance the iterator. Although iterators could
be written for circular sequences, we do not know of an efficient
solution. The missing past-the-end situation in circular sequences can
be solved with an arbitrary sentinel in the cyclic order, but this
would destroy the natural symmetry in the structure (which is in
itself a bad idea) and additional bookkeeping in the items and
checking in the iterator advance method reduces efficiency. Another
solution may use more bookkeeping in the iterator, e.g.~with a start
item, a current item, and a kind of winding-number that is zero for
the {\tt begin()}-iterator and one for the past-the-end
situation\footnote{This is currently implemented as the
adaptor class which provides a pair of iterators for a given
circulator.}. Though we have introduced the concept of circulators
that allows light-weight implementations and the \cgal\ support
library provides adaptor classes that convert between iterators and
circulators (with the corresponding penalty in efficiency), so as to
integrate this new concept into the framework of \stl.
A serious design problem is the slight change of the semantic for
circulator ranges as compared to iterator ranges. Since this semantic
is defined by the intuitive operators {\tt ++} and {\tt ==}, which we
would like to keep for circulators as well, circulator ranges can be
used in \stl\ algorithms. This is in itself a useful feature, if there
would not be the definition of a full range $\left[c, c\right)$ that
an \stl\ algorithm will treat as an empty range. However, the
likelihood of a mistake may be overestimated, since for a container
{\tt C} supporting circulators there is no {\tt end()} member
function, and an expression such as {\tt std::sort( C.begin(),
C.end())} will fail. It is easy to distinguish iterators and
circulators at compile time, which allows for generic algorithms
supporting both as arguments. It is also possible to protect
algorithms against inappropriate arguments using the same technique,
see the reference pages for circulators, specifically the
\ccc{Assert_iterator} and \ccc{is_empty_range} functions.
{\bf Warning:} Please note that the definition of a range is different
from 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.
% +---------------------------------------------+
\begin{ccHtmlClassFile}{Circulator.html}{Requirements for Circulators}
\ccHtmlNoClassLinks
\begin{ccClass}{Circulator}
\section{Forward Circulator}
A class \ccClassName\ that satisfies the requirements of a forward
circulator with the value type \ccStyle{T}, supports the following
operations. See the reference pages for the full set of requirements.
Note that the stated return values are not required, only a return
value that is convertible to the stated type is required. As for \CC,
we recommend the use of 0 instead of {\tt NULL}.
\ccTypes
\ccSetTwoColumns{Circulator:: iterator_category}{}
\ccNestedType{value_type}{the value type \ccStyle{T}.}
\ccGlue
\ccNestedType{reference}{either reference or const reference to \ccStyle{T}.}
\ccGlue
\ccNestedType{pointer}{either pointer or const pointer to \ccStyle{T}.}
\ccGlue
\ccNestedType{size_type}{unsigned integral type that can hold the size
of the sequence.}
\ccGlue
\ccNestedType{difference_type}{signed integral type that can hold the
distance between two circulators.}
\ccGlue
\ccNestedType{iterator_category}{circulator category
\ccc{Forward_circulator_tag}.}
\ccCreation
\ccCreationVariable{c}
%\ccSetThreeColumns{Circulator&}{int n + Circulator d}{}
\ccSetThreeColumns{difference_type}{difference_type n += d}{}
\ccPropagateThreeToTwoColumns
\ccConstructor{Circulator();}{a circulator equal to \ccc{NULL} denoting
an empty sequence.}
\ccGlue
\ccConstructor{Circulator(const Circulator& d);}{a circulator equal to $d$.}
\ccOperations
\ccMethod{Circulator& operator=(const Circulator &d);}
{Assignment.}
\ccGlue
\ccMethod{bool operator==(NULL) const;}
{Test for emptiness.}
\ccGlue
\ccMethod{bool operator!=(NULL) const;}
{Test for non-emptiness, i.e.~ \ccStyle{!(c == NULL)}.}
\ccGlue
\ccMethod{bool operator==(const Circulator &d) const;}
{$c$ is equal to $d$ if they refer to the same item.}
\ccGlue
\ccMethod{bool operator!=(const Circulator &d) const;}
{Test for inequality, i.e.~\ccStyle{!(c == d)}.}
\ccMethod{reference operator*();}
{Returns the value of the circulator.
If \ccClassName\ is mutable \ccStyle{*c = t} is valid.
\ccPrecond \ccVar\ is dereferenceable.}
\ccMethod{pointer operator->();}
{Returns a pointer to the value of the circulator.
\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}
\section{Bidirectional Circulator}
A class \ccClassName\ that satisfies the requirements of a bidirectional
circulator with the value type \ccStyle{T}, supports the following operations
in addition to the operations supported by a forward circulator.
\ccTypes
\ccSetTwoColumns{Circulator:: iterator_category}{}
\ccNestedType{iterator_category}{circulator category
\ccc{Bidirectional_circulator_tag}.}
\ccSetThreeColumns{difference_type}{difference_type n += d}{}
\ccPropagateThreeToTwoColumns
\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}
\section{Random Access Circulator}
\label{sectionRandomAccessCirculatorRequ}
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. In contrast to random access iterators, for
random access circulators are no comparison operators available.
\ccTypes
\ccSetTwoColumns{Circulator:: iterator_category}{}
\ccNestedType{iterator_category}{circulator category
\ccc{Random_access_circulator_tag}.}
\ccSetThreeColumns{difference_type}{difference_type n += d}{}
\ccPropagateThreeToTwoColumns
\ccCreationVariable{c}
\ccOperations
\ccMethod{Circulator& operator+=(difference_type 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+(difference_type n);}
{Same as above, but returns a new circulator.}
\def\ccTagRmEigenClassName{\ccTrue}
\ccFunction{Circulator operator+(difference_type n, Circulator c);}
{Same as above.}
\def\ccTagRmEigenClassName{\ccFalse}
\ccMethod{Circulator& operator-=(difference_type 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-(difference_type n);}
{Same as above, but returns a new circulator.}
\ccMethod{reference operator[](difference_type n);}
{Returns \ccStyle{*(c + n)}.}
\ccMethod{difference_type operator-(const Circulator& d) const;}
{returns the difference between the two circulators. The value will be
in the interval $\left[ 1-s , s-1 \right]$ if $s$ is the size of the
total sequence. 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.}
\end{ccClass}
\end{ccHtmlClassFile}
% +-----------------------------------------------------+
\section{Adaptors Between Iterators and Circulators}
\label{sectionCirculatorAdaptor}
Algorithms working on iterator ranges can not be applied to circulator
ranges in full generality, only to subranges (see the warning in
Section~\ref{sectionCirculatorWarning}). The following adaptors
convert circulators to iterators and vice versa (with the unavoidable
space and time penalty) to reestablish this generality.
\ccInclude{CGAL/circulator.h}
\begin{tabbing}
\ccc{Container_from_circulator}\ \ \ \=
container-like class with iterators build from a circulator\\
\ccc{Circulator_from_iterator} \>
circulator over a range of two iterators\\
\ccc{Circulator_from_container} \>
circulator for a container
\end{tabbing}
The following example applies the generic {\tt std::reverse()} algorithm
from \stl\ to a sequence given by a bidirectional circulator {\tt c}.
It uses the \ccc{Container_from_circulator} adaptor.
\begin{ccExampleCode}
Circulator c; // c must be at least bidirectional.
CGAL::Container_from_circulator<Circulator> container(c);
std::reverse( container.begin(), container.end());
\end{ccExampleCode}
Another example defines a circulator \ccc{c} for a vector of
\ccc{int}'s. However, since there are no elements in the vector, the
circulator denotes an empty sequence. Would have been elements in the
vector, the circulator would implement a random access modulus the
size of the sequence.
\begin{ccExampleCode}
std::vector<int> v;
typedef CGAL::Circulator_from_iterator<
std::vector<int>::iterator > Circulator;
Circulator c( v.begin(), v.end());
\end{ccExampleCode}
% +-----------------------------------------------------+
\section{Functions on Circulators}
\label{sectionCirculatorFunctions}
A few functions deal with circulators and circulator ranges. The type
\ccc{C} denotes a circulator. The type \ccc{IC} denotes either a circulator
or an iterator. More on algorithms that work with circulators as well with
iterators can be found in the reference pages.
\ccInclude{CGAL/circulator.h}
\begin{tabbing}
\ccTexHtml{\ccc{Forward_container_from_circulator}\ \ \ \= \kill}{}
\ccc{circulator_size(C c)} \>
size of the sequence reachable by \ccc{c}\\
\ccc{circulator_distance(C c, C d)} \>
number of elements in the range $\left[c, d\right)$ \\
\ccc{iterator_distance(IC ic1, IC ic2)} \>
number of elements in the range $\left[\ccc{ic2}, \ccc{ic1}\right)$ \\
\ccc{is_empty_range( IC ic1, IC ic2)} \>
test the range $\left[\ccc{ic2}, \ccc{ic1}\right)$ for emptiness
\end{tabbing}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,28 @@
// circulator_prog1.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <vector>
#include <algorithm>
#include <CGAL/circulator.h>
typedef std::vector<int>::iterator I;
typedef CGAL::Circulator_from_iterator<I> Circulator;
typedef CGAL::Container_from_circulator<Circulator> Container;
typedef Container::iterator Iterator;
int main() {
std::vector<int> v;
v.push_back(5);
v.push_back(2);
v.push_back(9);
Circulator c( v.begin(), v.end());
Container container( c);
std::sort( container.begin(), container.end());
Iterator i = container.begin();
assert( *i == 2);
i++; assert( *i == 5);
i++; assert( *i == 9);
i++; assert( i == container.end());
return 0;
}

View File

@ -0,0 +1,27 @@
// circulator_prog2.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <vector>
#include <algorithm>
#include <CGAL/circulator.h>
typedef CGAL::Circulator_from_container< std::vector<int> > Circulator;
typedef CGAL::Container_from_circulator<Circulator> Container;
typedef Container::iterator Iterator;
int main() {
std::vector<int> v;
v.push_back(5);
v.push_back(2);
v.push_back(9);
Circulator c( &v);
Container container( c);
std::sort( container.begin(), container.end());
Iterator i = container.begin();
assert( *i == 2);
i++; assert( *i == 5);
i++; assert( *i == 9);
i++; assert( i == container.end());
return 0;
}

View File

@ -0,0 +1,45 @@
// circulator_prog3.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <list>
#include <CGAL/circulator.h>
template <class C> inline int foo( C c, std::forward_iterator_tag) {
CGAL::Assert_circulator( c);
CGAL::Assert_forward_category( c);
return 1;
}
template <class C> inline int foo( C c, std::random_access_iterator_tag) {
CGAL::Assert_circulator( c);
CGAL::Assert_random_access_category( c);
return 2;
}
template <class I> inline int foo( I i, CGAL::Iterator_tag) {
CGAL::Assert_iterator( i);
return 3;
}
template <class C> inline int foo( C c, CGAL::Circulator_tag) {
CGAL::Assert_circulator( c);
typedef std::iterator_traits<C> Traits;
typedef typename Traits::iterator_category iterator_category;
return foo( c, iterator_category());
}
template <class IC> inline int foo( IC ic) {
typedef CGAL::Circulator_traits<IC> Traits;
typedef typename Traits::category category;
return foo( ic, category());
}
int main() {
typedef CGAL::Forward_circulator_base<int> F;
typedef CGAL::Random_access_circulator_base<int> R;
F f = F();
R r = R();
std::list<int> l;
assert( foo( f) == 1);
assert( foo( r) == 2);
assert( foo( l.begin()) == 3);
return 0;
}

View File

@ -0,0 +1,39 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: main.tex
% +------------------------------------------------------------------------+
% | Circulator for CGAL
% |
% | 05.02.1998 Lutz Kettner
% +------------------------------------------------------------------------+
\input{circulator}
%% EOF %%
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: main.tex
% +------------------------------------------------------------------------+
% | Automatically generated driver file for the reference manual chapter
% | of this package. Do not edit manually, you may loose your changes.
% +------------------------------------------------------------------------+
\input{Circulator_ref/intro.tex}
\begin{ccHtmlOnly}
<HR><H2>Reference Pages</H2>
\end{ccHtmlOnly}
\input{Circulator_ref/Assert_circulator.tex}
\input{Circulator_ref/circulator_distance.tex}
\input{Circulator_ref/circulator_size.tex}
\input{Circulator_ref/Circulator.tex}
\input{Circulator_ref/Circulator_from_container.tex}
\input{Circulator_ref/Circulator_from_iterator.tex}
\input{Circulator_ref/Circulator_tag.tex}
\input{Circulator_ref/Circulator_traits.tex}
\input{Circulator_ref/Container_from_circulator.tex}
\input{Circulator_ref/For_all.tex}
\input{Circulator_ref/is_empty_range.tex}
\input{Circulator_ref/iterator_distance.tex}
\input{Circulator_ref/query_circulator_or_iterator.tex}
%% EOF

View File

@ -0,0 +1,54 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: wrapper.tex
% +------------------------------------------------------------------------+
% | Main TeX file for testing CGAL packages.
% +------------------------------------------------------------------------+
\documentclass{book}
\usepackage{alltt}
\usepackage{cprog}
\usepackage{cc_manual}
\usepackage{latex_converter}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{path}
\usepackage{ipe}
% page dimensions
% ---------------
\textwidth 15.6cm
\textheight 23 cm
\topmargin -14mm
\evensidemargin 3mm
\oddsidemargin 3mm
\marginparsep12mm
\marginparwidth13mm
\sloppy
\begin{document}
\def\ccTagChapterAuthor{\ccTrue}
\def\ccTagChapterRelease{\ccTrue}
% default column layout
% ---------------------
\newcommand{\cgalColumnLayout}{%
\ccSetThreeColumns{CGAL_Oriented_side}{}{\hspace*{8.5cm}}%
\ccPropagateThreeToTwoColumns
}
\cgalColumnLayout
\renewcommand{\ccRefPageBegin}{\ccParDims\cgalColumnLayout}
\ccDefGlobalScope{CGAL::}
\include{main}
\bibliographystyle{alpha}
\bibliography{geom,cgal}
\end{document}
%% EOF %%

View File

@ -0,0 +1,51 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: wrapper.tex
% +------------------------------------------------------------------------+
% | Main TeX file for testing CGAL packages.
% +------------------------------------------------------------------------+
\documentclass{book}
\usepackage{alltt}
\usepackage{cprog}
\usepackage{cc_manual}
\usepackage{latex_converter}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{path}
\usepackage{ipe}
% page dimensions
% ---------------
\textwidth 15.6cm
\textheight 23 cm
\topmargin -14mm
\evensidemargin 3mm
\oddsidemargin 3mm
\marginparsep12mm
\marginparwidth13mm
\sloppy
\begin{document}
% default column layout
% ---------------------
\newcommand{\cgalColumnLayout}{%
\ccSetThreeColumns{CGAL_Oriented_side}{}{\hspace*{8.5cm}}%
\ccPropagateThreeToTwoColumns
}
\cgalColumnLayout
\renewcommand{\ccRefPageBegin}{\ccParDims\cgalColumnLayout}
\ccDefGlobalScope{CGAL::}
\include{main}
\bibliographystyle{alpha}
\bibliography{geom,cgal}
\end{document}
%% EOF %%

View File

@ -0,0 +1,87 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Assert_circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{Assert_circulator}
\ccHtmlCrossLink{Assert_iterator}
\ccHtmlCrossLink{Assert_circulator_or_iterator}
\ccHtmlCrossLink{Assert_input_category}
\ccHtmlCrossLink{Assert_output_category}
\ccHtmlCrossLink{Assert_forward_category}
\ccHtmlCrossLink{Assert_bidirectional_category}
\ccHtmlCrossLink{Assert_random_access_category}
\ccHtmlIndexC[function]{Assert_iterator}
\ccHtmlIndexC[function]{Assert_circulator_or_iterator}
\ccHtmlIndexC[function]{Assert_input_category}
\ccHtmlIndexC[function]{Assert_output_category}
\ccHtmlIndexC[function]{Assert_forward_category}
\ccHtmlIndexC[function]{Assert_bidirectional_category}
\ccHtmlIndexC[function]{Assert_random_access_category}
\ccDefinition
The following assertions check at compile time if their argument
is of the kind as stated in the assertions name, i.e.~a circulator, an
iterator, or of a particular category, applicable for an iterator or a
circulator. Note that neither input nor output circulators exists.
\ccInclude{CGAL/circulator.h}
\def\ccTagTemplateInline{\ccTrue}
\ccSetThreeColumns{template <class IC> void}{X}{}
\ccGlobalFunction{template <class C>
void Assert_circulator( const C &c);}
\ccGlue
\ccGlobalFunction{template <class I>
void Assert_iterator( const I &i);}
\ccGlue
\ccGlobalFunction{template< class IC>
void Assert_circulator_or_iterator(const IC& i);}
\ccGlobalFunction{template <class I>
void Assert_input_category( const I &i);}
\ccGlue
\ccGlobalFunction{template <class I>
void Assert_output_category( const I &i);}
\ccGlue
\ccGlobalFunction{template <class IC>
void Assert_forward_category( const IC &ic);}
\ccGlue
\ccGlobalFunction{template <class IC>
void Assert_bidirectional_category( const IC &ic);}
\ccGlue
\ccGlobalFunction{template <class IC>
void Assert_random_access_category( const IC &ic);}
\def\ccTagTemplateInline{\ccFalse}
\ccSeeAlso
\ccc{Circulator_tag},
\ccc{Circulator_traits},
\ccc{query_circulator_or_iterator},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,244 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefConcept}{Circulator}
\ccDefinition
\ccHtmlCrossLink{Forward_circulator}
\ccHtmlCrossLink{Bidirectional_circulator}
\ccHtmlCrossLink{Random_access_circulator}
\ccHtmlIndexC[concept]{Forward_circulator}
\ccHtmlIndexC[concept]{Bidirectional_circulator}
\ccHtmlIndexC[concept]{Random_access_circulator}
Note: This specification is a revised version based on the \CC\
Standard~\cite{c-isplc-98}, which is available now. In particular,
iterator traits are now assumed and required.
Iterators in the \stl\ were tailored for linear sequences. The
specialization for circular data structures leads to slightly
different requirements which we will summarize in the {\em
circulators\/} concept. The main difference is that 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. The semantic of a circulator range differs from the semantic
of an iterator range: For a circulator $c$ the range $\left[c,
c\right)$ denotes the sequence of all elements in the data
structure. For iterators, this range defines the empty sequence. A
separate test for an empty sequence has been added to the circulator
requirements: A comparison $c ==$ {\tt NULL} for a circulator $c$ is
true for an empty sequence. As for \CC, we recommend the use of 0
instead of {\tt NULL}.
Similar to \stl\ iterators, we distinguish between forward,
bidirectional, and random access circulators\footnote{Input
circulators are a contradiction, since any circulator is supposed to
return once to itself. Output circulators are not supported since
they would be indistinguishable from output iterators.}. Most
requirements for circulators are equal to those for iterators. We
present the changes, please refer to \cite[chapter 18]{ms-strg-96} or
\cite{c-isplc-98} for the iterator requirements.
{\bf Past-the-end value:} There is no past-the-end value for circulators.
{\bf Singular values:} There are no singular values for
circulators\footnote{Since circulators must be implemented as classes
anyway, there is no need to allow singular values for them. An
un-initalized circulator does not have a singular value, but is
supposed to refer to an empty sequence.}.
{\bf Empty sequence:} The comparison $c ==$ {\tt NULL} (or $c == 0$)
for a circulator $c$ is {\tt true} if $c$ denotes an empty sequence,
and {\tt false} otherwise.
{\bf Dereferenceable values:} A circulator that does not denote an
empty sequence is dereferenceable.
{\bf Reachability:} Each dereferenceable circulator can reach itself
with a finite and non-empty sequence of applications of \ccc{operator++}.
{\bf Ranges:} For any circulator $c$ the range $\left[c, c\right)$ is
a valid range. If the circulator refers to an empty sequence, the range
$\left[c, c\right)$ denotes the empty range. Otherwise the circulator
is dereferenceable and the range $\left[c, c\right)$ denotes the
sequence of all elements in the data structure. {\em Remark:} When a
circulator is used in a place of an iterator, like with an \stl\
algorithm, it will work as expected with the only exception that
the range $\left[c, c\right)$ denotes always the empty range. This is
not a requirement, but a consequence of the requirements
stated here and the fact that the \stl\ requirements for iterator
ranges are based on the {\tt operator++} and the {\tt operator==},
which we use for circulators as well. In principle, we face here the
difference between a {\tt while} loop and a {\tt do-while} loop.
{\bf Types:} For a circulator of type $C$ the following local types
are required:
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt C::value\_type} \> value type the circulator refers to.\\
{\tt C::reference} \> reference type used for the return type
of {\tt C::operator*()}.\\
{\tt C::pointer} \> pointer type used for the return type of
{\tt C::operator->()}.\\
{\tt C::size\_type} \> unsigned integral type that can hold
the size of a sequence\\
{\tt C::difference\_type} \> signed integral type that can hold
the distance between two circulators.\\
{\tt C::iterator\_category} \> circulator category.
\end{tabbing}
\subsection*{Forward Circulators}
In the following, we assume that {\tt a} and {\tt b} are circulators
of type {\tt C}, {\tt r} is of type {\tt C\&} (is assignable), and
{\tt T} denotes the the value type of {\tt C}. Let {\tt D} be the
distance type of {\tt C}. As for \CC, we recommend the use of 0
instead of {\tt NULL}.
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt C()} \> a circulator equal to \ccc{NULL} denoting an
empty sequence.\\
{\tt a == NULL} \> Returns {\tt true} if {\tt a} denotes an empty
sequence, {\tt false} otherwise\footnote{For
simplicity, {\tt NULL == a} is not required.}. The\\
\> behavior for comparisons with pointer-like
values different than {\tt NULL} \\
\> is undefined%
\footnote{A runtime assertion is
recommended.}.\\
{\tt a != NULL} \> Returns {\tt !(a == NULL)}. \\
{\tt ++r} \> Like for forward iterators, but a dereferenceable
circulator {\tt r} will always\\
\> be dereferenceable after {\tt ++r} (no
past-the-end value). {\em Precondition:} {\tt
r} \\
\> does not denote an empty sequence.\\
{\tt r++} \> Same as for {\tt ++r}.\\
{\tt C::iterator\_category} \> circulator category {\tt
CBP\_Forward\_circulator\_tag}.
\end{tabbing}
\subsection*{Bidirectional Circulators}
The same requirements as for the forward circulators hold for
bidirectional iterators with the following change of the iterator
category:
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt C::iterator\_category} \> circulator category {\tt
CBP\_Bidirectional\_circulator\_tag}.
\end{tabbing}
\subsection*{Random Access Circulators}
\label{sectionMinCircleRequ}
The same requirements as for the bidirectional circulators hold for
random access iterators with the following changes and extensions.
The idea of a random access extends naturally to circulators using
equivalence classes modulus the length of the sequence. With this in
mind, the additional requirements for random access iterators hold
also for random access circulators. The only exception is that the
random access iterator is required to provide a total order on the
sequence, which a circulator cannot provide\footnote{One might define
an order by splitting the circle at a fixed point, e.g.~the start
circulator provided from the data structure. This is what the
adaptor to iterators will do. Nonetheless, we do not require this
for circulators.}.
The difference of two circulators is not unique as for iterators. A
reasonable requirement demands that the result is in a certain range
$[1-\mbox{{\it size, size}}-1]$, where {\it size} is the size of the
sequence, and that whenever a circulator {\tt a} is fixed that
the differences with all other circulators of the sequence form a
consistent ordering.
For the adaptor to iterators a minimal circulator
$d_{\mbox{\footnotesize min}}$ is required for which the difference $c
- d_{\mbox{\footnotesize min}}$ to all other circulators $c$ is non
negative.
\begin{tabbing}
\ccTexHtml{{\tt C::iterator\_category}\ \ \ \ \ \= \kill}{}
{\tt b - a} \> limited range and consistent ordering
as explained above.\\
{\tt a.min\_circulator()} \> returns the minimal circulator from the
range $[a,a)$.\\
{\tt C::iterator\_category} \> circulator category {\tt
CBP\_Random\_access\_circulator\_tag}.
\end{tabbing}
\subsection*{Const Circulators}
As with iterators, we distinguish between circulators and const
circulators. The expression {\tt *a = t} with {\tt t} of type {\tt T}
is valid for mutable circulators. It is invalid for const circulators.
\subsection*{Circulators in Container Classes}
For a container {\tt x} of type {\tt X} that supports circulators
{\tt c} the following naming convention is recommended:
\begin{tabbing}
\ccTexHtml{{\tt X::Const\_circulator}\ \ \ \ \= \kill}{}
{\tt X::Circulator} \> the type of the mutable circulator.\\
{\tt X::Const\_circulator} \> the type of the const circulator.\\
{\tt c = x.begin()} \> the start circulator of the sequence.
It is of type {\tt X::Circulator} for a \\
\> mutable container or {\tt X::Const\_circulator} for
a const container. There \\
\> must not be an {\tt end()} member function.
\end{tabbing}
If a container will support iterators and circulators, the member
function {\tt circulator\_begin()} is proposed. However, the support
of iterators and circulators simultaneously is not recommended, since
it would lead to fat interfaces. The natural choice should be
supported, the other concept will be available through adaptors.
\subsection*{Example}
A generic {\tt contains} function accepts a range of circulators and a
value. It returns \ccc{true} if the value is contained in the sequence
of items denoted by the range of circulators. As usual for circular
structures, a {\tt do}-{\tt while} loop is preferable, such that for
the specific input, {\tt c == d}, all elements in the sequence are
reached. Note that the example simplifies if the sequence is known to
be non-empty, which is for example the common case in polyhedral
surfaces where vertices and facets have at least one incident edge.
\begin{ccExampleCode}
template <class Circulator, class T>
bool contains( Circulator c, Circulator d, const T& value) {
if (c != 0) {
do {
if (*c == value)
return true;
} while (++c != d);
}
return false;
}
\end{ccExampleCode}
\end{ccRefConcept}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,88 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Forward_circulator_from_container.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_from_container<C>}
\label{pageCircFromContainerRef}
\ccHtmlCrossLink{Const_circulator_from_container}
\ccHtmlCrossLink{Const_circulator_from_container<C>}
\ccHtmlIndexC[class]{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 adaptor conforms to the requirements of the corresponding
circulator category. An additional member function
\ccc{current_iterator()} returns the current iterator pointing to
the same position as the circulator does.
\ccSeeAlso
\ccc{Container_from_circulator},
\ccc{Circulator_from_iterator},
\ccc{Circulator}.
\ccExample
The following program composes two adaptor -- from a container to a
circulator and back to an iterator. It applies an \stl\ sort algorithm
on a \stl\ vector with three elements. The resulting vector will be
{\tt [2 5 9]} as it is checked by the assertions. The program is
part of the \cgal\ distribution.
\ccIncludeExampleCode{examples/Circulator/circulator_prog2.C}
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,90 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Forward_circulator_from_iterator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_from_iterator<I>}
\label{pageCircFromIterRef}
\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, const I& cur = begin);}{%
a circulator \ccVar\ initialized to refer to the element
\ccStyle{*cur} in a range {\tt [}\ccStyle{begin}{\tt
,}\ccStyle{end}{\tt )}.
The circulator \ccVar\ contains a singular value if \ccStyle{begin==end}.
}
\ccConstructor{Circulator_from_iterator(
const Circulator_from_iterator<I,T,Size,Dist>& d,
const I& cur);}{%
a copy of circulator $d$ referring to the element \ccc{*cur}.
The circulator \ccVar\ contains a singular value if $d$ does so.
}
\ccOperations
The adaptor conforms to the requirements of the respective circulator
category. An additional member function \ccc{current_iterator()}
returns the current iterator pointing to the same position as the
circulator does.
\ccSeeAlso
\ccc{Container_from_circulator},
\ccc{Circulator_from_container},
\ccc{Circulator}.
\ccExample
The following program composes two adaptors -- from an iterator to a
circulator and back to an iterator. It applies an \stl\ sort algorithm
on a \stl\ vector containing three elements. The resulting vector will
be {\tt [2 5 9]} as it is checked by the assertions. The program is
part of the \cgal\ distribution.
\ccIncludeExampleCode{examples/Circulator/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{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,159 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Circulator_tag
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_tag}
\ccHtmlCrossLink{Iterator_tag}
\ccHtmlIndexC[class]{Iterator_tag}
\ccHtmlCrossLink{Forward_circulator_tag}
\ccHtmlIndexC[class]{Forward_circulator_tag}
\ccHtmlCrossLink{Bidirectional_circulator_tag}
\ccHtmlIndexC[class]{Bidirectional_circulator_tag}
\ccHtmlCrossLink{Random_access_circulator_tag}
\ccHtmlIndexC[class]{Random_access_circulator_tag}
\ccHtmlCrossLink{Circulator_base}
\ccHtmlCrossLink{Circulator_base<Category, T>}
\ccHtmlIndexC[class]{Circulator_base<Category, T>}
\ccHtmlCrossLink{Forward_circulator_base}
\ccHtmlCrossLink{Forward_circulator_base<T,Dist,Size>}
\ccHtmlIndexC[class]{Forward_circulator_base<T,Dist,Size>}
\ccHtmlCrossLink{Bidirectional_circulator_base}
\ccHtmlCrossLink{Bidirectional_circulator_base<T,Dist,Size>}
\ccHtmlIndexC[class]{Bidirectional_circulator_base<T,Dist,Size>}
\ccHtmlCrossLink{Random_access_circulator_base}
\ccHtmlCrossLink{Random_access_circulator_base<T,Dist,Size>}
\ccHtmlIndexC[class]{Random_access_circulator_base<T,Dist,Size>}
\ccHtmlCrossLink{Forward_circulator_ptrbase}
\ccHtmlCrossLink{Forward_circulator_ptrbase<T,Dist,Size>}
\ccHtmlIndexC[class]{Forward_circulator_ptrbase<T,Dist,Size>}
\ccHtmlCrossLink{Bidirectional_circulator_ptrbase}
\ccHtmlCrossLink{Bidirectional_circulator_ptrbase<T,Dist,Size>}
\ccHtmlIndexC[class]{Bidirectional_circulator_ptrbase<T,Dist,Size>}
\ccHtmlCrossLink{Random_access_circulator_ptrbase}
\ccHtmlCrossLink{Random_access_circulator_ptrbase<T,Dist,Size>}
\ccHtmlIndexC[class]{Random_access_circulator_ptrbase<T,Dist,Size>}
\ccDefinition
Iterators and circulators as well as different categories of
circulators can be distinguished with the use of discriminating
functions and the following circulator tags. A couple of base classes
simplify the task of writing own circulators. They declare the
appropriate tags and the local types needed for circulators.
To use the tags or base classes only it is sufficient to include:
\ccInclude{CGAL/circulator_bases.h}\\
\ccInclude{CGAL/circulator.h}
\ccSetOneOfTwoColumns{8cm}
\ccSetTwoOfThreeColumns{3.4cm}{4cm}
\ccHeading{Compile Time Tags}
\ccStruct{struct Circulator_tag {};}{any circulator.}
\ccGlue
\ccStruct{struct Iterator_tag {};}{any iterator.}
\ccStruct{struct Forward_circulator_tag {};}{
derived from \ccc{forward_iterator_tag}.}
\ccGlue
\ccStruct{struct Bidirectional_circulator_tag {};}{
derived from \ccc{bidirectional_iterator_tag}.}
\ccGlue
\ccStruct{struct Random_access_circulator_tag {};}{
derived from \ccc{random_access_iterator_tag}.}
\ccHeading{Base Classes}
\begin{ccTexOnly}
\def\dummySkipASD{\\\hspace*{18mm}}
\ccStruct{template < class Category,
class T,
class Dist = std::ptrdiff_t,
class Size = std::size_t,\dummySkipASD
class Ptr = T*,
class Ref = T&>
struct Circulator_base {};}{}
\end{ccTexOnly}
\begin{ccHtmlOnly}
\ccStruct{template < class Category,
class T,
class Dist = std::ptrdiff_t,
class Size = std::size_t,
class Ptr = T*,
class Ref = T&>
struct Circulator_base {};}{}
\end{ccHtmlOnly}
\ccRefLabel{CGAL::Circulator_base}
\ccSetTwoColumns{}{random access.}
\def\ccTagTemplateInline{\ccTrue}
\ccStruct{template <class T, class Dist, class Size>
struct Forward_circulator_base {};}{}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
struct Bidirectional_circulator_base {};}{}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
struct Random_access_circulator_base {};}{}
\def\ccTagTemplateInline{\ccFalse}
\ccSeeAlso
\ccc{query_circulator_or_iterator},
\ccc{Circulator_traits},
\ccc{Assert_circulator},\\
\ccc{CGAL_For_all},
\ccc{is_empty_range},
\ccc{Circulator}.
\ccExample
The above declarations can be used to distinguish between iterators
and circulators and between different circulator categories. The
assertions can be used to protect a templatized algorithm against
instantiations that do not fulfill the requirements. The following
example program illustrates both.
\ccIncludeExampleCode{examples/Circulator/circulator_prog3.C}
\ccImplementation
Since not all current compilers can eliminate the space needed for the
compile time tags even when deriving from them, we implement a variant
for each base class that contains a protected \ccc{void*} data member
called \ccc{_ptr}. Here, the allocated space in the derived
classes can be reused.
\ccSetOneOfTwoColumns{8.4cm}
\ccStruct{template <class T, class Dist, class Size>
class Forward_circulator_ptrbase {};}{%
forward circulator.}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
class Bidirectional_circulator_ptrbase {};}{%
bidirectional circulator.}
\ccGlue
\ccStruct{template <class T, class Dist, class Size>
class Random_access_circulator_ptrbase {};}{%
random access circulator.}
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,73 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Circulator_traits
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{Circulator_traits<C>}
\ccDefinition
The circulator traits class distinguishes between circulators and
iterators. It defines a local type \ccc{category} that is identical to the
type \ccc{Circulator_tag} if the iterator category of the argument
\ccc{C} is a circulator category. Otherwise it is identical to the type
\ccc{Iterator_tag}.
The local type \ccc{iterator_category} gives the corresponding
iterator category for circulators, i.e.~one of
\ccc{forward_iterator_tag}, \ccc{bidirectional_iterator_tag}, or
\ccc{random_access_iterator_tag}.
The local type \ccc{circulator_category} gives the corresponding
circulator category for iterators, i.e.~one of
\ccc{Forward_circulator_tag}, \ccc{Bidirectional_circulator_tag}, or
\ccc{Random_access_circulator_tag}.
\ccInclude{CGAL/circulator.h}
\ccTypes
\ccTwo{Circulator_traits<C>:: \ \ circulator_category}{}
\ccNestedType{category}{either \ccc{Iterator_tag} or
\ccc{Circulator_tag}.}
\ccNestedType{iterator_category}{
corresponding iterator category for circulators.}
\ccNestedType{circulator_category}{
corresponding circulator category for iterator}
\ccExample
A generic function \ccc{bar} that distinguishes between a call with a
circulator range and a call with an iterator range:
\begin{ccExampleCode}
template <class I>
void bar( I i, I j, CGAL::Iterator_tag) {
CGAL::Assert_iterator(i);
// This function is called for iterator ranges [i,j).
}
template <class C>
void bar( C c, C d, CGAL::Circulator_tag) {
CGAL::Assert_circulator(c);
// This function is called for circulator ranges [c,d).
}
template <class IC>
void bar( IC i, IC j) { // calls the correct function
return bar( i, j, typename CGAL::Circulator_traits<IC>::category());
}
\end{ccExampleCode}
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,131 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: Forward_container_from_circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefClass}{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. By analogy to \stl\
container classes these member functions return a const iterator in
the case that the container itself is constant and a mutable iterator
otherwise.
\ccInclude{CGAL/circulator.h}
\ccTypes
\ccTypedef{typedef C Circulator;}{}
\ccGlue
\ccNestedType{iterator}{}
\ccGlue
\ccNestedType{const_iterator}{}
\ccGlue
\ccNestedType{value_type}{}
\ccGlue
\ccNestedType{reference}{}
\ccGlue
\ccNestedType{const_reference}{}
\ccGlue
\ccNestedType{pointer}{}
\ccGlue
\ccNestedType{const_pointer}{}
\ccGlue
\ccNestedType{size_type}{}
\ccGlue
\ccNestedType{difference_type}{}
\ccCreation
\ccCreationVariable{container}
\ccSetTwoColumns{Circulator}{}
\ccConstructor{Container_from_circulator();}{%
any iterator of \ccc{container} will have a singular value.}
\ccConstructor{Container_from_circulator(const C& c);}{%
any iterator of \ccc{container} 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.
\ccSeeAlso
\ccc{Circulator_from_iterator},
\ccc{Circulator_from_container},
\ccc{Circulator}.
\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 iterator adaptor keeps track of the number of rounds a circulator
has done around the ring-like data structure (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 internally.
This winding number is zero for the \ccStyle{begin()}-iterator and one
for the \ccStyle{end()}-iterator. It is incremented whenever the
internal 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, which is
here still possible in a defined manner. However, for random access
iterators it is not supported.
The random access iterator has to be able to compute the size of the
data structure in constant time. This is for example needed if the
difference of the past-the-end iterator and the begin iterator is
taken, which is exactly the the size of the data structure.
Therefore, if the circulator is of the random-access category, the
adapter chooses the minimal circulator for the internal anchor
position. The minimal circulator is part of the random access
circulator requirements, see
Page~\pageref{sectionMinCircleRequ}. For the random
access iterator the adaptor implements a total ordering relation that
is currently not required for random access circulators.
\end{ccRefClass}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,68 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: For_all.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefMacro}{CGAL_For_all}
\ccHtmlCrossLink{CGAL_For_all_backwards}
\ccHtmlIndexC[macro]{CGAL_For_all_backwards}
\ccDefinition
In order to write algorithms that work with iterator ranges as well as
with circulator ranges we have to consider the difference of
representing an empty range. For iterators this is the range $[i,i)$,
while for circulators it would be \ccc{c == NULL}, the empty sequence test.
The function \ccc{is_empty_range} provides the necessary generic test
which accepts an iterator range or a circulator range and says whether
the range is empty or not.
\ccInclude{CGAL/circulator.h}
A macro \ccc{CGAL_For_all( i, j)} simplifies the writing of such simple
loops as the one in the example of the function \ccc{is_empty_range}.
\ccc{i} and \ccc{j} can be either iterators or circulators. The macro
loops through the range [\ccc{i, j}). It increments \ccc{i} until it
reaches \ccc{j}. The implementation looks like:
\ccc{CGAL_For_all(i,j)} \ \ \ccTexHtml{$\equiv$}{:=} \ \
\begin{minipage}[t]{0.74\textwidth}
\begin{verbatim}
for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range(i,j);
_circ_loop_flag;
_circ_loop_flag = ((++i) != (j))
)
\end{verbatim}
\end{minipage}%
Note that the macro behaves like a \ccc{for}-loop. It can be used with
a single statement or with a statement block. For bidirectional
iterators or circulators exist a backwards loop macro
\ccc{CGAL_For_all_backwards( i, j)} that decrements \ccc{j} until
it reaches \ccc{i}.
\ccSeeAlso
\ccc{iterator_distance},
\ccc{is_empty_range},
\ccc{Circulator_tag},
\ccc{Circulator_traits},\\
\ccc{Assert_circulator_or_iterator},
\ccc{Circulator}.
\end{ccRefMacro}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,41 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: circulator_distance
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{circulator_distance}
\ccDefinition
\ccSetThreeColumns{template <class C> sieze_t}{XXX}{}
The distance of a circulator $c$ to a circulator $d$ is the number of
elements in the range $\left[c, d\right)$. It is defined to be zero
for a singular circulator and it returns the size of the data
structure when applied to a range of the form $\left[c, c\right)$.
\ccInclude{CGAL/circulator.h}
\ccGlobalFunction{template <class C> C::difference_type
circulator_distance(C c, C d);}
\ccSeeAlso
\ccc{circulator_size},
\ccc{iterator_distance},
\ccc{is_empty_range},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,44 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: circulator_size
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{circulator_size}
\ccDefinition
\ccSetThreeColumns{template <class C> sieze_t}{XXX}{}
The size of a circulator is the size of the data structure it refers
to. It is zero for a circulator with singular value. The size can be
computed in linear time for forward and bidirectional circulators, and
in constant time for random access circulators using the minimal
circulator. The function \ccStyle{circulator_size(c)}
returns the circulator size. It uses the
\ccStyle{c.min_circulator()} function if $c$ is a random
access circulator.
\ccInclude{CGAL/circulator.h}
\ccGlobalFunction{template <class C> C::size_type circulator_size(C c);}
\ccSeeAlso
\ccc{circulator_distance},
\ccc{iterator_distance},
\ccc{is_empty_range},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,92 @@
% +------------------------------------------------------------------------+
% | CBP Reference Manual: intro.tex
% +------------------------------------------------------------------------+
% | Model for a new style of manuals in CBP
% |
% | 14.05.1998 Lutz Kettner
% +------------------------------------------------------------------------+
\section{Reference Pages for Circulator}
\section*{Summary}
The concept of iterators in \stl\ is tailored for linear sequences.
In contrast, circular sequences occur naturally in many combinatorial
and geometric structures. Examples are polyhedral surfaces and planar
maps, where the edges emanating from a vertex or the edges around a
facet form a circular sequence.
We provide several functions, classes and macros to assist working
with circulators: distance computation, adaptor classes converting
between circulators and iterators, base classes to ease implementing
circulators, and support for generic algorithms that work with
circulators as well as with iterators.
\subsection*{Concepts}
\ccRefIdfierPage{Circulator}\\
\ccc{Forward_circulator}\\
\ccc{Bidirectional_circulator}\\
\ccc{Random_access_circulator}
\subsection*{Classes}
\ccRefIdfierPage{CGAL::Container_from_circulator<C>}\\
\ccRefIdfierPage{CGAL::Circulator_from_iterator<I>}\\
\ccRefIdfierPage{CGAL::Circulator_from_container<C>}\\
\ccc{CGAL::Const_circulator_from_container<C>}
\ccRefIdfierPage{CGAL::Circulator_tag}\\
\ccc{CGAL::Iterator_tag}\\
\ccc{CGAL::Forward_circulator_tag}\\
\ccc{CGAL::Bidirectional_circulator_tag}\\
\ccc{CGAL::Random_access_circulator_tag}
\ccRefIdfierPage{CGAL::Circulator_base}\\
\ccc{CGAL::Forward_circulator_base}\\
\ccc{CGAL::Bidirectional_circulator_base}\\
\ccc{CGAL::Random_access_circulator_base}
\ccRefIdfierPage{CGAL::Circulator_traits<C>}
\subsection*{Functions}
\ccThree{random_access_iterator_tag}{}{page 999.}
\ccFunction{size_type CGAL::circulator_size ( C c);}
{\hfill \ccRefPage{CGAL::circulator_size}}\ccGlue
\ccFunction{difference_type CGAL::circulator_distance ( C c, C d);}
{\hfill \ccRefPage{CGAL::circulator_distance}}\ccGlue
\ccFunction{difference_type CGAL::iterator_distance ( IC ic1, IC ic2);}
{\hfill \ccRefPage{CGAL::iterator_distance}}\ccGlue
\ccFunction{bool CGAL::is_empty_range ( IC i, IC j);}
{\hfill \ccRefPage{CGAL::is_empty_range}}
\ccFunction{CGAL::Circulator_tag CGAL::query_circulator_or_iterator ( C c);}
{\hfill \ccRefPage{CGAL::query_circulator_or_iterator}}\ccGlue
\ccFunction{CGAL::Iterator_tag CGAL::query_circulator_or_iterator ( I i);}
{}
\ccFunction{void CGAL::Assert_circulator ( C c);}
{\hfill \ccRefPage{CGAL::Assert_circulator}}\ccGlue
\ccFunction{void CGAL::Assert_iterator ( I i);}
{}\ccGlue
\ccFunction{void CGAL::Assert_input_category ( I i);}
{}\ccGlue
\ccFunction{void CGAL::Assert_output_category ( I i);}
{}\ccGlue
\ccFunction{void CGAL::Assert_forward_category ( IC ic);}
{}\ccGlue
\ccFunction{void CGAL::Assert_bidirectional_category ( IC ic);}
{}\ccGlue
\ccFunction{void CGAL::Assert_random_access_category ( IC ic);}
{}\ccGlue
\ccFunction{void CGAL::Assert_circulator_or_iterator ( IC i);}
{}
\subsection*{Macros}
\ccc{CGAL_For_all(i,j)}\hfill \ccRefPage{CGAL_For_all}\\
\ccc{CGAL_For_all_backwards(i,j)}
%% EOF %%

View File

@ -0,0 +1,69 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: is_empty_range.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{is_empty_range}
\ccDefinition
In order to write algorithms that work with iterator ranges as well as
with circulator ranges we have to consider the difference of
representing an empty range. For iterators this is the range $[i,i)$,
while for circulators it would be \ccc{c == NULL}, the empty sequence test.
The function \ccc{is_empty_range} provides the necessary generic test
which accepts an iterator range or a circulator range and says whether
the range is empty or not.
\ccInclude{CGAL/circulator.h}
\ccSetThreeColumns{bool}{is_empty_range( IC i, IC j);}{}
\ccFunction{template< class IC>
bool is_empty_range( const IC& i, const IC& j);}{%
is \ccc{true} if the range [\ccc{i, j}) is empty,
\ccc{false} otherwise.
\ccPrecond \ccc{IC} is either a circulator or an iterator
type. The range [\ccc{i, j}) is valid.
}
\ccExample
The following function \ccc{process_all} accepts a range $\left[i,
j\right)$ of an iterator or circulator \ccc{IC} and process each
element in this range:
\begin{verbatim}
template <class IC>
void process_all( IC i, IC j) {
if (! CGAL::is_empty_range( i, j)) {
do {
process(*i);
} while (++i != j);
}
}
\end{verbatim}
\ccSeeAlso
\ccc{iterator_distance},
\ccc{CGAL_For_all},
\ccc{Circulator_tag},
\ccc{Circulator_traits},\\
\ccc{Assert_circulator_or_iterator},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,44 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: iterator_distance
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{iterator_distance}
\ccDefinition
\ccSetThreeColumns{iterator_traits<IC>::difference_type;}{XXX}{}
The following function returns the distance between either two
iterators or two circulators. The return type is {\tt ptrdiff\_t} for
compilers not supporting iterator traits yet.
\ccInclude{CGAL/circulator.h}
\ccGlobalFunction{template <class IC> iterator_traits<IC>::difference_type
iterator_distance(IC ic1, IC ic2);}
\ccSeeAlso
\ccc{circulator_size},
\ccc{circulator_distance},
\ccc{is_empty_range},
\ccc{Circulator_tag},\\
\ccc{Assert_circulator_or_iterator},
\ccc{CGAL_For_all},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,46 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: query_circulator_or_iterator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
% | \RCSdef{\circRev}{$Revision$}
% | \RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
% +-----------------------------------------------------+
\begin{ccRefFunction}{query_circulator_or_iterator}
\ccDefinition
The following function distinguishes between circulators and
iterators. It is based on iterator traits~\cite{c-isplc-98,m-tnutt-95}
and \ccc{Circulator_traits}.
\ccInclude{CGAL/circulator.h}
\ccSetThreeColumns{Circulator_tag}{distance_type( C c);}{}
\ccFunction{template <class I>
Iterator_tag query_circulator_or_iterator( const I& i);}{
if the iterator category of \ccc{I} belongs to an iterator.}
\ccFunction{template <class C>
Circulator_tag query_circulator_or_iterator( const C& c);}{
if the iterator category of \ccc{C} belongs to a circulator.}
\ccSeeAlso
\ccc{Circulator_tag},
\ccc{Circulator_traits},
\ccc{Assert_circulator},
\ccc{Circulator}.
\end{ccRefFunction}
% +-----------------------------------------------------+
% EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,391 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: circulator.tex
% +------------------------------------------------------------------------+
% | Requirements for circulators in analogy to STL iterators.
% | Adaptors between circulators and iterators.
% | Proposal for CGAL.
% |
% | 11.10.1996 Lutz Kettner
% |
\RCSdef{\circRev}{$Revision$}
\RCSdefDate{\circDate}{$Date$}
% +------------------------------------------------------------------------+
\gdef\lciIfHtmlClassLinks{\lcFalse}
\gdef\lciIfHtmlRefLinks{\lcFalse}
\gdef\lciIfHtmlLinks{\lcFalse}
\chapter{Circulators}
\label{chapterCirculators}
\ccChapterRelease{\circRev. \ \circDate}\\
\ccChapterAuthor{Lutz Kettner}
An introduction to the concept of circulators is given here. A couple
of adaptors are presented that convert between iterators and
circulators. Some useful functions for circulators follow. This
chapter concludes with a discussion of the design decisions taken. For
the full description of the circulator requirements, the provided base
classes, the circulator tags, and the support for generic algorithms
that work for iterators as well as for circulators please refer to the
reference pages. Note that circulators are not part of \stl, but of \cgal.
% +-----------------------------------------------------+
\section{Introduction}
\label{sectionIntroduction}
\label{sectionCirculatorWarning}
The concept of iterators in \stl\ is tailored for linear
sequences~\cite{c-isplc-98,ms-strg-96}. In contrast, circular
sequences occur naturally in many combinatorial and geometric
structures. Examples are polyhedral surfaces and planar maps, where
the edges emanating from a vertex or the edges around a facet form a
circular sequence.
Since circular sequences cannot provide efficient iterators, we have
introduced the new concept of {\em circulators}. They share most of
the requirements with iterators, while the main difference is the lack
of a past-the-end position in the sequence. Appropriate adaptors are
provided between iterators and circulators to integrate circulators
smoothly into the framework of \stl. An example of a generic {\tt
contains} function illustrates the use of circulators. As usual for
circular structures, a {\tt do}-{\tt while} loop is preferable, such
that for the specific input, {\tt c == d}, all elements in the
sequence are reached.
\begin{ccExampleCode}
template <class Circulator, class T>
bool contains( Circulator c, Circulator d, const T& value) {
if (c != 0) {
do {
if (*c == value)
return true;
} while (++c != d);
}
return false;
}
\end{ccExampleCode}
\noindent
Three circulator categories are defined: forward, bidirectional and
random-access circulators. Given a circulator {\tt c}, the operation
{\tt *c} denotes the item the circulator refers to. The operation {\tt
++c} advances the circulator by one item and {\tt --c} steps a
bidirectional circulator one item backwards. For random-access
circulators {\tt c+n} advances the circulator {\tt n} steps. Two
circulators can be compared for equality.
Circulators have a different notion of reachability and ranges than
iterators. A circulator {\tt d} is called {\em reachable\/} from a
circulator {\tt c} if {\tt c} can be made equal to {\tt d} with
finitely many applications of the operator {\tt ++}. Due to the
circularity of the sequence this is always true if both circulators
refer to items of the same sequence. In particular, {\tt c} is always
reachable from {\tt c}. Given two circulators {\tt c} and {\tt d}, the
range {\tt [c,d)} denotes all circulators obtained by starting with
{\tt c} and advancing {\tt c} until {\tt d} is reached, but does not
include {\tt d}, for {\tt d} $\neq$ {\tt c}. So far it is the same
range definition as for iterators. The difference lies in the use of
{\tt [c,c)} to denote all items in the circular sequence, whereas for
an iterator {\tt i} the range {\tt [i,i)} denotes the empty range. As
long as {\tt c != d} the range {\tt[c,d)} behaves like an iterator
range and could be used in \stl\ algorithms. For circulators however,
an additional test {\tt c == NULL} is required that returns true if
and only if the circular sequence is empty. In this case the
circulator {\tt c} is said to have a {\em singular value}. As for
\CC, we recommend the use of 0 instead of {\tt NULL}.
Besides the conceptual cleanness, the main reason for inventing a new
concept with a similar intent as iterators is efficiency. An iterator
is supposed to be a light-weight object -- merely a pointer and a
single indirection to advance the iterator. Although iterators could
be written for circular sequences, we do not know of an efficient
solution. The missing past-the-end situation in circular sequences can
be solved with an arbitrary sentinel in the cyclic order, but this
would destroy the natural symmetry in the structure (which is in
itself a bad idea) and additional bookkeeping in the items and
checking in the iterator advance method reduces efficiency. Another
solution may use more bookkeeping in the iterator, e.g.~with a start
item, a current item, and a kind of winding-number that is zero for
the {\tt begin()}-iterator and one for the past-the-end
situation\footnote{This is currently implemented as the
adaptor class which provides a pair of iterators for a given
circulator.}. Though we have introduced the concept of circulators
that allows light-weight implementations and the \cgal\ support
library provides adaptor classes that convert between iterators and
circulators (with the corresponding penalty in efficiency), so as to
integrate this new concept into the framework of \stl.
A serious design problem is the slight change of the semantic for
circulator ranges as compared to iterator ranges. Since this semantic
is defined by the intuitive operators {\tt ++} and {\tt ==}, which we
would like to keep for circulators as well, circulator ranges can be
used in \stl\ algorithms. This is in itself a useful feature, if there
would not be the definition of a full range $\left[c, c\right)$ that
an \stl\ algorithm will treat as an empty range. However, the
likelihood of a mistake may be overestimated, since for a container
{\tt C} supporting circulators there is no {\tt end()} member
function, and an expression such as {\tt std::sort( C.begin(),
C.end())} will fail. It is easy to distinguish iterators and
circulators at compile time, which allows for generic algorithms
supporting both as arguments. It is also possible to protect
algorithms against inappropriate arguments using the same technique,
see the reference pages for circulators, specifically the
\ccc{Assert_iterator} and \ccc{is_empty_range} functions.
{\bf Warning:} Please note that the definition of a range is different
from 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.
% +---------------------------------------------+
\begin{ccHtmlClassFile}{Circulator.html}{Requirements for Circulators}
\ccHtmlNoClassLinks
\begin{ccClass}{Circulator}
\section{Forward Circulator}
A class \ccClassName\ that satisfies the requirements of a forward
circulator with the value type \ccStyle{T}, supports the following
operations. See the reference pages for the full set of requirements.
Note that the stated return values are not required, only a return
value that is convertible to the stated type is required. As for \CC,
we recommend the use of 0 instead of {\tt NULL}.
\ccTypes
\ccSetTwoColumns{Circulator:: iterator_category}{}
\ccNestedType{value_type}{the value type \ccStyle{T}.}
\ccGlue
\ccNestedType{reference}{either reference or const reference to \ccStyle{T}.}
\ccGlue
\ccNestedType{pointer}{either pointer or const pointer to \ccStyle{T}.}
\ccGlue
\ccNestedType{size_type}{unsigned integral type that can hold the size
of the sequence.}
\ccGlue
\ccNestedType{difference_type}{signed integral type that can hold the
distance between two circulators.}
\ccGlue
\ccNestedType{iterator_category}{circulator category
\ccc{Forward_circulator_tag}.}
\ccCreation
\ccCreationVariable{c}
%\ccSetThreeColumns{Circulator&}{int n + Circulator d}{}
\ccSetThreeColumns{difference_type}{difference_type n += d}{}
\ccPropagateThreeToTwoColumns
\ccConstructor{Circulator();}{a circulator equal to \ccc{NULL} denoting
an empty sequence.}
\ccGlue
\ccConstructor{Circulator(const Circulator& d);}{a circulator equal to $d$.}
\ccOperations
\ccMethod{Circulator& operator=(const Circulator &d);}
{Assignment.}
\ccGlue
\ccMethod{bool operator==(NULL) const;}
{Test for emptiness.}
\ccGlue
\ccMethod{bool operator!=(NULL) const;}
{Test for non-emptiness, i.e.~ \ccStyle{!(c == NULL)}.}
\ccGlue
\ccMethod{bool operator==(const Circulator &d) const;}
{$c$ is equal to $d$ if they refer to the same item.}
\ccGlue
\ccMethod{bool operator!=(const Circulator &d) const;}
{Test for inequality, i.e.~\ccStyle{!(c == d)}.}
\ccMethod{reference operator*();}
{Returns the value of the circulator.
If \ccClassName\ is mutable \ccStyle{*c = t} is valid.
\ccPrecond \ccVar\ is dereferenceable.}
\ccMethod{pointer operator->();}
{Returns a pointer to the value of the circulator.
\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}
\section{Bidirectional Circulator}
A class \ccClassName\ that satisfies the requirements of a bidirectional
circulator with the value type \ccStyle{T}, supports the following operations
in addition to the operations supported by a forward circulator.
\ccTypes
\ccSetTwoColumns{Circulator:: iterator_category}{}
\ccNestedType{iterator_category}{circulator category
\ccc{Bidirectional_circulator_tag}.}
\ccSetThreeColumns{difference_type}{difference_type n += d}{}
\ccPropagateThreeToTwoColumns
\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}
\section{Random Access Circulator}
\label{sectionRandomAccessCirculatorRequ}
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. In contrast to random access iterators, for
random access circulators are no comparison operators available.
\ccTypes
\ccSetTwoColumns{Circulator:: iterator_category}{}
\ccNestedType{iterator_category}{circulator category
\ccc{Random_access_circulator_tag}.}
\ccSetThreeColumns{difference_type}{difference_type n += d}{}
\ccPropagateThreeToTwoColumns
\ccCreationVariable{c}
\ccOperations
\ccMethod{Circulator& operator+=(difference_type 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+(difference_type n);}
{Same as above, but returns a new circulator.}
\def\ccTagRmEigenClassName{\ccTrue}
\ccFunction{Circulator operator+(difference_type n, Circulator c);}
{Same as above.}
\def\ccTagRmEigenClassName{\ccFalse}
\ccMethod{Circulator& operator-=(difference_type 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-(difference_type n);}
{Same as above, but returns a new circulator.}
\ccMethod{reference operator[](difference_type n);}
{Returns \ccStyle{*(c + n)}.}
\ccMethod{difference_type operator-(const Circulator& d) const;}
{returns the difference between the two circulators. The value will be
in the interval $\left[ 1-s , s-1 \right]$ if $s$ is the size of the
total sequence. 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.}
\end{ccClass}
\end{ccHtmlClassFile}
% +-----------------------------------------------------+
\section{Adaptors Between Iterators and Circulators}
\label{sectionCirculatorAdaptor}
Algorithms working on iterator ranges can not be applied to circulator
ranges in full generality, only to subranges (see the warning in
Section~\ref{sectionCirculatorWarning}). The following adaptors
convert circulators to iterators and vice versa (with the unavoidable
space and time penalty) to reestablish this generality.
\ccInclude{CGAL/circulator.h}
\begin{tabbing}
\ccc{Container_from_circulator}\ \ \ \=
container-like class with iterators build from a circulator\\
\ccc{Circulator_from_iterator} \>
circulator over a range of two iterators\\
\ccc{Circulator_from_container} \>
circulator for a container
\end{tabbing}
The following example applies the generic {\tt std::reverse()} algorithm
from \stl\ to a sequence given by a bidirectional circulator {\tt c}.
It uses the \ccc{Container_from_circulator} adaptor.
\begin{ccExampleCode}
Circulator c; // c must be at least bidirectional.
CGAL::Container_from_circulator<Circulator> container(c);
std::reverse( container.begin(), container.end());
\end{ccExampleCode}
Another example defines a circulator \ccc{c} for a vector of
\ccc{int}'s. However, since there are no elements in the vector, the
circulator denotes an empty sequence. Would have been elements in the
vector, the circulator would implement a random access modulus the
size of the sequence.
\begin{ccExampleCode}
std::vector<int> v;
typedef CGAL::Circulator_from_iterator<
std::vector<int>::iterator > Circulator;
Circulator c( v.begin(), v.end());
\end{ccExampleCode}
% +-----------------------------------------------------+
\section{Functions on Circulators}
\label{sectionCirculatorFunctions}
A few functions deal with circulators and circulator ranges. The type
\ccc{C} denotes a circulator. The type \ccc{IC} denotes either a circulator
or an iterator. More on algorithms that work with circulators as well with
iterators can be found in the reference pages.
\ccInclude{CGAL/circulator.h}
\begin{tabbing}
\ccTexHtml{\ccc{Forward_container_from_circulator}\ \ \ \= \kill}{}
\ccc{circulator_size(C c)} \>
size of the sequence reachable by \ccc{c}\\
\ccc{circulator_distance(C c, C d)} \>
number of elements in the range $\left[c, d\right)$ \\
\ccc{iterator_distance(IC ic1, IC ic2)} \>
number of elements in the range $\left[\ccc{ic2}, \ccc{ic1}\right)$ \\
\ccc{is_empty_range( IC ic1, IC ic2)} \>
test the range $\left[\ccc{ic2}, \ccc{ic1}\right)$ for emptiness
\end{tabbing}
% +-----------------------------------------------------+
% EOF

View File

@ -0,0 +1,28 @@
// circulator_prog1.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <vector>
#include <algorithm>
#include <CGAL/circulator.h>
typedef std::vector<int>::iterator I;
typedef CGAL::Circulator_from_iterator<I> Circulator;
typedef CGAL::Container_from_circulator<Circulator> Container;
typedef Container::iterator Iterator;
int main() {
std::vector<int> v;
v.push_back(5);
v.push_back(2);
v.push_back(9);
Circulator c( v.begin(), v.end());
Container container( c);
std::sort( container.begin(), container.end());
Iterator i = container.begin();
assert( *i == 2);
i++; assert( *i == 5);
i++; assert( *i == 9);
i++; assert( i == container.end());
return 0;
}

View File

@ -0,0 +1,27 @@
// circulator_prog2.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <vector>
#include <algorithm>
#include <CGAL/circulator.h>
typedef CGAL::Circulator_from_container< std::vector<int> > Circulator;
typedef CGAL::Container_from_circulator<Circulator> Container;
typedef Container::iterator Iterator;
int main() {
std::vector<int> v;
v.push_back(5);
v.push_back(2);
v.push_back(9);
Circulator c( &v);
Container container( c);
std::sort( container.begin(), container.end());
Iterator i = container.begin();
assert( *i == 2);
i++; assert( *i == 5);
i++; assert( *i == 9);
i++; assert( i == container.end());
return 0;
}

View File

@ -0,0 +1,45 @@
// circulator_prog3.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <list>
#include <CGAL/circulator.h>
template <class C> inline int foo( C c, std::forward_iterator_tag) {
CGAL::Assert_circulator( c);
CGAL::Assert_forward_category( c);
return 1;
}
template <class C> inline int foo( C c, std::random_access_iterator_tag) {
CGAL::Assert_circulator( c);
CGAL::Assert_random_access_category( c);
return 2;
}
template <class I> inline int foo( I i, CGAL::Iterator_tag) {
CGAL::Assert_iterator( i);
return 3;
}
template <class C> inline int foo( C c, CGAL::Circulator_tag) {
CGAL::Assert_circulator( c);
typedef std::iterator_traits<C> Traits;
typedef typename Traits::iterator_category iterator_category;
return foo( c, iterator_category());
}
template <class IC> inline int foo( IC ic) {
typedef CGAL::Circulator_traits<IC> Traits;
typedef typename Traits::category category;
return foo( ic, category());
}
int main() {
typedef CGAL::Forward_circulator_base<int> F;
typedef CGAL::Random_access_circulator_base<int> R;
F f = F();
R r = R();
std::list<int> l;
assert( foo( f) == 1);
assert( foo( r) == 2);
assert( foo( l.begin()) == 3);
return 0;
}

View File

@ -0,0 +1,39 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: main.tex
% +------------------------------------------------------------------------+
% | Circulator for CGAL
% |
% | 05.02.1998 Lutz Kettner
% +------------------------------------------------------------------------+
\input{circulator}
%% EOF %%
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: main.tex
% +------------------------------------------------------------------------+
% | Automatically generated driver file for the reference manual chapter
% | of this package. Do not edit manually, you may loose your changes.
% +------------------------------------------------------------------------+
\input{Circulator_ref/intro.tex}
\begin{ccHtmlOnly}
<HR><H2>Reference Pages</H2>
\end{ccHtmlOnly}
\input{Circulator_ref/Assert_circulator.tex}
\input{Circulator_ref/circulator_distance.tex}
\input{Circulator_ref/circulator_size.tex}
\input{Circulator_ref/Circulator.tex}
\input{Circulator_ref/Circulator_from_container.tex}
\input{Circulator_ref/Circulator_from_iterator.tex}
\input{Circulator_ref/Circulator_tag.tex}
\input{Circulator_ref/Circulator_traits.tex}
\input{Circulator_ref/Container_from_circulator.tex}
\input{Circulator_ref/For_all.tex}
\input{Circulator_ref/is_empty_range.tex}
\input{Circulator_ref/iterator_distance.tex}
\input{Circulator_ref/query_circulator_or_iterator.tex}
%% EOF

View File

@ -0,0 +1,54 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: wrapper.tex
% +------------------------------------------------------------------------+
% | Main TeX file for testing CGAL packages.
% +------------------------------------------------------------------------+
\documentclass{book}
\usepackage{alltt}
\usepackage{cprog}
\usepackage{cc_manual}
\usepackage{latex_converter}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{path}
\usepackage{ipe}
% page dimensions
% ---------------
\textwidth 15.6cm
\textheight 23 cm
\topmargin -14mm
\evensidemargin 3mm
\oddsidemargin 3mm
\marginparsep12mm
\marginparwidth13mm
\sloppy
\begin{document}
\def\ccTagChapterAuthor{\ccTrue}
\def\ccTagChapterRelease{\ccTrue}
% default column layout
% ---------------------
\newcommand{\cgalColumnLayout}{%
\ccSetThreeColumns{CGAL_Oriented_side}{}{\hspace*{8.5cm}}%
\ccPropagateThreeToTwoColumns
}
\cgalColumnLayout
\renewcommand{\ccRefPageBegin}{\ccParDims\cgalColumnLayout}
\ccDefGlobalScope{CGAL::}
\include{main}
\bibliographystyle{alpha}
\bibliography{geom,cgal}
\end{document}
%% EOF %%

View File

@ -0,0 +1,51 @@
% +------------------------------------------------------------------------+
% | CGAL Reference Manual: wrapper.tex
% +------------------------------------------------------------------------+
% | Main TeX file for testing CGAL packages.
% +------------------------------------------------------------------------+
\documentclass{book}
\usepackage{alltt}
\usepackage{cprog}
\usepackage{cc_manual}
\usepackage{latex_converter}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{path}
\usepackage{ipe}
% page dimensions
% ---------------
\textwidth 15.6cm
\textheight 23 cm
\topmargin -14mm
\evensidemargin 3mm
\oddsidemargin 3mm
\marginparsep12mm
\marginparwidth13mm
\sloppy
\begin{document}
% default column layout
% ---------------------
\newcommand{\cgalColumnLayout}{%
\ccSetThreeColumns{CGAL_Oriented_side}{}{\hspace*{8.5cm}}%
\ccPropagateThreeToTwoColumns
}
\cgalColumnLayout
\renewcommand{\ccRefPageBegin}{\ccParDims\cgalColumnLayout}
\ccDefGlobalScope{CGAL::}
\include{main}
\bibliographystyle{alpha}
\bibliography{geom,cgal}
\end{document}
%% EOF %%

View File

@ -0,0 +1,75 @@
#! /bin/sh
# This is a script for the CGAL test suite. Such a script must obey
# the following rules:
#
# - the name of the script is cgal_test
# - for every target two one line messages are written to the file 'error.txt'
# the first one indicates if the compilation was successful
# the second one indicates if the execution was successful
# if one of the two was not successful, the line should start with 'ERROR:'
# - running the script should not require any user interaction
# - the script should clean up object files and executables
ERRORFILE=error.txt
#---------------------------------------------------------------------#
# compile_and_run <target>
#---------------------------------------------------------------------#
compile_and_run()
{
echo "Compiling $1 ... "
if eval 'make CGAL_MAKEFILE=$CGAL_MAKEFILE \
TESTSUITE_CXXFLAGS="$TESTSUITE_CXXFLAGS" \
TESTSUITE_LDFLAGS="$TESTSUITE_LDFLAGS" $1' ; then
echo " compilation of $1 succeeded" >> $ERRORFILE
else
echo " ERROR: compilation of $1 failed" >> $ERRORFILE
fi
if [ -f $1 ] ; then
OUTPUTFILE=ProgramOutput.$1.$PLATFORM
rm -f $OUTPUTFILE
COMMAND="./$1"
if [ -f $1.cmd ] ; then
COMMAND="$COMMAND `cat $1.cmd`"
fi
if [ -f $1.cin ] ; then
COMMAND="cat $1.cin | $COMMAND"
fi
echo "Executing $1 ... "
echo
if eval 2>&1 $COMMAND > $OUTPUTFILE ; then
echo " execution of $1 succeeded" >> $ERRORFILE
else
echo " ERROR: execution of $1 failed" >> $ERRORFILE
fi
else
echo " ERROR: could not execute $1" >> $ERRORFILE
fi
eval "2>&1 make CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null "
}
#---------------------------------------------------------------------#
# remove the previous error file
#---------------------------------------------------------------------#
rm -f $ERRORFILE
touch $ERRORFILE
#---------------------------------------------------------------------#
# compile and run the tests
#---------------------------------------------------------------------#
if [ $# -ne 0 ] ; then
for file in $* ; do
compile_and_run $file
done
else
compile_and_run circulator_prog1
compile_and_run circulator_prog2
compile_and_run circulator_prog3
fi

View File

@ -0,0 +1,28 @@
// circulator_prog1.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <vector>
#include <algorithm>
#include <CGAL/circulator.h>
typedef std::vector<int>::iterator I;
typedef CGAL::Circulator_from_iterator<I> Circulator;
typedef CGAL::Container_from_circulator<Circulator> Container;
typedef Container::iterator Iterator;
int main() {
std::vector<int> v;
v.push_back(5);
v.push_back(2);
v.push_back(9);
Circulator c( v.begin(), v.end());
Container container( c);
std::sort( container.begin(), container.end());
Iterator i = container.begin();
assert( *i == 2);
i++; assert( *i == 5);
i++; assert( *i == 9);
i++; assert( i == container.end());
return 0;
}

View File

@ -0,0 +1,27 @@
// circulator_prog2.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <vector>
#include <algorithm>
#include <CGAL/circulator.h>
typedef CGAL::Circulator_from_container< std::vector<int> > Circulator;
typedef CGAL::Container_from_circulator<Circulator> Container;
typedef Container::iterator Iterator;
int main() {
std::vector<int> v;
v.push_back(5);
v.push_back(2);
v.push_back(9);
Circulator c( &v);
Container container( c);
std::sort( container.begin(), container.end());
Iterator i = container.begin();
assert( *i == 2);
i++; assert( *i == 5);
i++; assert( *i == 9);
i++; assert( i == container.end());
return 0;
}

View File

@ -0,0 +1,45 @@
// circulator_prog3.C
// ------------------------
#include <CGAL/basic.h>
#include <cassert>
#include <list>
#include <CGAL/circulator.h>
template <class C> inline int foo( C c, std::forward_iterator_tag) {
CGAL::Assert_circulator( c);
CGAL::Assert_forward_category( c);
return 1;
}
template <class C> inline int foo( C c, std::random_access_iterator_tag) {
CGAL::Assert_circulator( c);
CGAL::Assert_random_access_category( c);
return 2;
}
template <class I> inline int foo( I i, CGAL::Iterator_tag) {
CGAL::Assert_iterator( i);
return 3;
}
template <class C> inline int foo( C c, CGAL::Circulator_tag) {
CGAL::Assert_circulator( c);
typedef std::iterator_traits<C> Traits;
typedef typename Traits::iterator_category iterator_category;
return foo( c, iterator_category());
}
template <class IC> inline int foo( IC ic) {
typedef CGAL::Circulator_traits<IC> Traits;
typedef typename Traits::category category;
return foo( ic, category());
}
int main() {
typedef CGAL::Forward_circulator_base<int> F;
typedef CGAL::Random_access_circulator_base<int> R;
F f = F();
R r = R();
std::list<int> l;
assert( foo( f) == 1);
assert( foo( r) == 2);
assert( foo( l.begin()) == 3);
return 0;
}

View File

@ -0,0 +1,63 @@
# Created by the script create_makefile
# This is the makefile for compiling a CGAL application.
#---------------------------------------------------------------------#
# include platform specific settings
#---------------------------------------------------------------------#
# Choose the right include file from the <cgalroot>/make directory.
# CGAL_MAKEFILE = ENTER_YOUR_INCLUDE_MAKEFILE_HERE
include $(CGAL_MAKEFILE)
#---------------------------------------------------------------------#
# compiler flags
#---------------------------------------------------------------------#
CXXFLAGS = \
$(TESTSUITE_CXXFLAGS) \
$(EXTRA_FLAGS) \
$(CGAL_CXXFLAGS) \
$(DEBUG_OPT)
#---------------------------------------------------------------------#
# linker flags
#---------------------------------------------------------------------#
LIBPATH = \
$(TESTSUITE_LIBPATH) \
$(CGAL_LIBPATH)
LDFLAGS = \
$(TESTSUITE_LDFLAGS) \
$(CGAL_LDFLAGS)
#---------------------------------------------------------------------#
# target entries
#---------------------------------------------------------------------#
all: \
circulator_prog1 \
circulator_prog2 \
circulator_prog3
circulator_prog1$(EXE_EXT): circulator_prog1$(OBJ_EXT)
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)circulator_prog1 circulator_prog1$(OBJ_EXT) $(LDFLAGS)
circulator_prog2$(EXE_EXT): circulator_prog2$(OBJ_EXT)
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)circulator_prog2 circulator_prog2$(OBJ_EXT) $(LDFLAGS)
circulator_prog3$(EXE_EXT): circulator_prog3$(OBJ_EXT)
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)circulator_prog3 circulator_prog3$(OBJ_EXT) $(LDFLAGS)
clean: \
circulator_prog1.clean \
circulator_prog2.clean \
circulator_prog3.clean
#---------------------------------------------------------------------#
# suffix rules
#---------------------------------------------------------------------#
.C$(OBJ_EXT):
$(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $<

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,143 @@
// ======================================================================
//
// Copyright (c) 1997 The CGAL Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
//
// ----------------------------------------------------------------------
//
// release :
// release_date : 1999, September 02
//
// file : circulator_bases.h
// package : Circulator (3.4)
// chapter : $CGAL_Chapter: Circulators $
// source : circulator.fw
// revision : $Revision$
// revision_date : $Date$
// author(s) : Lutz Kettner <kettner@inf.ethz.ch>
//
// coordinator : INRIA, Sophia Antipolis
//
// Base classes and tags to build own circulators.
// ======================================================================
#ifndef CGAL_CIRCULATOR_BASES_H
#define CGAL_CIRCULATOR_BASES_H 1
#ifndef CGAL_PROTECT_CSTDDEF
#include <cstddef>
#define CGAL_PROTECT_CSTDDEF
#endif
#ifndef CGAL_PROTECT_ITERATOR
#include <iterator>
#define CGAL_PROTECT_ITERATOR
#endif
CGAL_BEGIN_NAMESPACE
struct Circulator_tag {}; // any circulator.
struct Iterator_tag {}; // any iterator.
struct Forward_circulator_tag
: public CGAL_STD::forward_iterator_tag {};
struct Bidirectional_circulator_tag
: public CGAL_STD::bidirectional_iterator_tag {};
struct Random_access_circulator_tag
: public CGAL_STD::random_access_iterator_tag {};
template <class T, class Dist = std::ptrdiff_t, class Size = std::size_t>
struct Forward_circulator_base {
typedef T value_type;
typedef Dist difference_type;
typedef Size size_type;
typedef T* pointer;
typedef T& reference;
typedef Forward_circulator_tag iterator_category;
};
template <class T, class Dist = std::ptrdiff_t, class Size = std::size_t>
struct Bidirectional_circulator_base {
typedef T value_type;
typedef Dist difference_type;
typedef Size size_type;
typedef T* pointer;
typedef T& reference;
typedef Bidirectional_circulator_tag iterator_category;
};
template <class T, class Dist = std::ptrdiff_t, class Size = std::size_t>
struct Random_access_circulator_base {
typedef T value_type;
typedef Dist difference_type;
typedef Size size_type;
typedef T* pointer;
typedef T& reference;
typedef Random_access_circulator_tag iterator_category;
};
template < class Category,
class T,
class Distance = std::ptrdiff_t,
class Size = std::size_t,
class Pointer = T*,
class Reference = T&>
struct Circulator_base {
typedef Category iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef Size size_type;
typedef Pointer pointer;
typedef Reference reference;
};
// variant base classes
// ---------------------
template <class T, class Dist = std::ptrdiff_t, class Size = std::size_t>
class Forward_circulator_ptrbase // forward circulator.
{
protected:
void* _ptr;
public:
typedef Forward_circulator_tag iterator_category;
typedef T value_type;
typedef Dist difference_type;
typedef Size size_type;
typedef T* pointer;
typedef T& reference;
Forward_circulator_ptrbase() : _ptr(NULL) {}
Forward_circulator_ptrbase(void* p) : _ptr(p) {}
};
template <class T, class Dist = std::ptrdiff_t, class Size = std::size_t>
class Bidirectional_circulator_ptrbase // bidirectional circulator.
{
protected:
void* _ptr;
public:
typedef Bidirectional_circulator_tag iterator_category;
typedef T value_type;
typedef Dist difference_type;
typedef Size size_type;
typedef T* pointer;
typedef T& reference;
Bidirectional_circulator_ptrbase() : _ptr(NULL) {}
Bidirectional_circulator_ptrbase(void* p) : _ptr(p) {}
};
template <class T, class Dist = std::ptrdiff_t, class Size = std::size_t>
class Random_access_circulator_ptrbase // random access circulator.
{
protected:
void* _ptr;
public:
typedef Random_access_circulator_tag iterator_category;
typedef T value_type;
typedef Dist difference_type;
typedef Size size_type;
typedef T* pointer;
typedef T& reference;
Random_access_circulator_ptrbase() : _ptr(NULL) {}
Random_access_circulator_ptrbase(void* p) : _ptr(p) {}
};
CGAL_END_NAMESPACE
#endif // CGAL_CIRCULATOR_BASES_H //
// EOF //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,694 @@
// ======================================================================
//
// Copyright (c) 1997 The CGAL Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
//
// ----------------------------------------------------------------------
//
// release :
// release_date : 1999, September 02
//
// file : circulator_impl.h
// package : Circulator (3.4)
// chapter : $CGAL_Chapter: Circulators $
// source : circulator.fw
// revision : $Revision$
// revision_date : $Date$
// author(s) : Lutz Kettner <kettner@inf.ethz.ch>
//
// coordinator : INRIA, Sophia Antipolis
//
// Support to build own circulators (internal and undocumented).
// ======================================================================
#ifndef CGAL_CIRCULATOR_IMPL_H
#define CGAL_CIRCULATOR_IMPL_H 1
#ifndef CGAL_CIRCULATOR_H
#include <CGAL/circulator.h>
#endif
CGAL_BEGIN_NAMESPACE
template < class S>
class Forward_circulator_over_struct
: public Forward_circulator_ptrbase<S,std::ptrdiff_t,std::size_t>{
public:
// DEFINITION
//
// Given a structure `S' that have a data member `S* next' that realizes a
// ring like data structure the adaptor
// `Forward_circulator_over_struct< S>' provides a forward circulator
// for it. If the structure `S' has additionally a second data member of
// type `S* prev' that realizes the reverse direction the adaptor
// `Bidirectional_circulator_over_struct< S>' provides a bidirectional
// circulator for it. In addition, adaptors for const circulators are
// provided with the names `Forward_const_circulator_over_struct< S>'
// and `Bidirectional_const_circulator_over_struct< S>'. A circulator
// becomes invalid whenever the object it refers to gets deleted from the
// data structure.
typedef Forward_circulator_over_struct<S> Self;
typedef Forward_circulator_ptrbase<S,std::ptrdiff_t,std::size_t> Base1;
typedef typename Base1::reference reference;
typedef typename Base1::pointer pointer;
// CREATION
//
// New creation variable is: `circ'
Forward_circulator_over_struct() {}
// a circulator `circ' with singular value.
Forward_circulator_over_struct( S* ptr)
: Forward_circulator_ptrbase<S,std::ptrdiff_t,std::size_t>( ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
reference operator*() const { return *(S*)_ptr;}
pointer operator->() const { return (S*)_ptr;}
Self& operator++() {
_ptr = ((S*)_ptr)->next;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class S>
class Forward_const_circulator_over_struct
: public Forward_circulator_ptrbase<S,std::ptrdiff_t,std::size_t>{
public:
typedef Forward_const_circulator_over_struct<S> Self;
typedef const S& reference;
typedef const S* pointer;
// CREATION
Forward_const_circulator_over_struct() {}
// a circulator `circ' with singular value.
Forward_const_circulator_over_struct( const S* ptr)
: Forward_circulator_ptrbase<S,std::ptrdiff_t,
std::size_t>((void*)ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
reference operator*() const { return *(const S*)_ptr;}
pointer operator->() const { return (const S*)_ptr;}
Self& operator++() {
_ptr = ((S*)_ptr)->next;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class S>
class Bidirectional_circulator_over_struct
: public Bidirectional_circulator_ptrbase<S,std::ptrdiff_t,std::size_t>{
public:
typedef Bidirectional_circulator_over_struct<S> Self;
typedef Bidirectional_circulator_ptrbase<S,std::ptrdiff_t,
std::size_t> Base1;
typedef typename Base1::reference reference;
typedef typename Base1::pointer pointer;
// CREATION
//
// New creation variable is: `circ'
Bidirectional_circulator_over_struct() {}
// a circulator `circ' with singular value.
Bidirectional_circulator_over_struct( S* ptr)
: Bidirectional_circulator_ptrbase<S,std::ptrdiff_t,
std::size_t>( ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
reference operator*() const { return *(S*)_ptr;}
pointer operator->() const { return (S*)_ptr;}
Self& operator++() {
_ptr = ((S*)_ptr)->next;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
Self& operator--() {
_ptr = ((S*)_ptr)->prev;
return *this;
}
Self operator--(int) {
Self tmp = *this;
--*this;
return tmp;
}
};
template < class S>
class Bidirectional_const_circulator_over_struct
: public Bidirectional_circulator_ptrbase<S,std::ptrdiff_t,std::size_t>{
public:
typedef Bidirectional_const_circulator_over_struct<S> Self;
typedef const S& reference;
typedef const S* pointer;
// CREATION
Bidirectional_const_circulator_over_struct() {}
// a circulator `circ' with singular value.
Bidirectional_const_circulator_over_struct( const S* ptr)
: Bidirectional_circulator_ptrbase<S,std::ptrdiff_t,std::size_t>(
(void*)ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
reference operator*() const { return *(const S*)_ptr;}
pointer operator->() const { return (const S*)_ptr;}
Self& operator++() {
_ptr = ((S*)_ptr)->next;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
Self& operator--() {
_ptr = ((S*)_ptr)->prev;
return *this;
}
Self operator--(int) {
Self tmp = *this;
--*this;
return tmp;
}
};
template < class C>
class Forward_circulator_over_class
: public Forward_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>{
public:
typedef Forward_circulator_over_class<C> Self;
// DEFINITION
//
// Given a class `C' that has a member function `C* next()' that realizes
// a ring like data structure the adaptor
// `Forward_circulator_over_class<C>' provides a forward circulator
// for it. If the class `C' has additionally a second member function `C*
// prev()' that realizes the reverse direction the adaptor
// `Bidirectional_circulator_over_class<C>' provides a bidirectional
// circulator for it. In addition, adaptors for const circulators are
// provided with the names `Forward_const_circulator_over_class<C>'
// and `Bidirectional_const_circulator_over_class<C>'. A circulator
// becomes invalid whenever the object it refers to gets deleted from the
// data structure.
Forward_circulator_over_class() {}
// a circulator `circ' with a singular value.
Forward_circulator_over_class( C* ptr)
: Forward_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>( ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
//
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
C& operator*() const { return *(C*)_ptr;}
C* operator->() const { return (C*)_ptr;}
Self& operator++() {
_ptr = ((C*)_ptr)->next();
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class C>
class Forward_const_circulator_over_class
: public Forward_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>{
public:
typedef Forward_const_circulator_over_class<C> Self;
Forward_const_circulator_over_class() {}
// a circulator `circ' with singular value.
Forward_const_circulator_over_class( const C* ptr)
: Forward_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>
((void*)ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
//
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
const C& operator*() const { return *(C*)_ptr;}
const C* operator->() const { return (C*)_ptr;}
Self& operator++() {
_ptr = (void*)(((C*)_ptr)->next());
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
};
template < class C>
class Bidirectional_circulator_over_class
: public Bidirectional_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>{
public:
typedef Bidirectional_circulator_over_class<C> Self;
Bidirectional_circulator_over_class() {}
// a circulator `circ' with singular value.
Bidirectional_circulator_over_class( C* ptr)
: Bidirectional_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>
(ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
//
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
C& operator*() const { return *(C*)_ptr;}
C* operator->() const { return (C*)_ptr;}
Self& operator++() {
_ptr = ((C*)_ptr)->next();
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
Self& operator--() {
_ptr = ((C*)_ptr)->prev();
return *this;
}
Self operator--(int) {
Self tmp = *this;
--*this;
return tmp;
}
};
template < class C>
class Bidirectional_const_circulator_over_class
: public Bidirectional_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>{
public:
typedef Bidirectional_const_circulator_over_class<C> Self;
//
// CREATION
Bidirectional_const_circulator_over_class() {}
// a circulator `circ' with singular value.
Bidirectional_const_circulator_over_class( const C* ptr)
: Bidirectional_circulator_ptrbase<C,std::ptrdiff_t,std::size_t>(
(void*)ptr) {}
// a circulator `circ' initialized to point to the element `*ptr'.
//
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _ptr == NULL;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const { return _ptr == c._ptr; }
bool operator!=( const Self& c) const { return !(*this == c); }
const C& operator*() const { return *(C*)_ptr;}
const C* operator->() const { return (C*)_ptr;}
Self& operator++() {
_ptr = (void*)(((C*)_ptr)->next());
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
Self& operator--() {
_ptr = (void*)(((C*)_ptr)->prev());
return *this;
}
Self operator--(int) {
Self tmp = *this;
--*this;
return tmp;
}
};
template < class A, class T, class U, class I>
class Circulator_over_array
: public Random_access_circulator_ptrbase<T,I,U>{
U _size;
U _i;
public:
// DEFINITION
//
// Given a data structure `A' that provides random access with an index of
// type `U' to its sequence of stored elements of type `T' with the member
// function `operator[]' the adaptor `Circulator_over_array< A, T, U,
// I>' provides a random access circulator for `A'. The corresponding
// const circulator is `Const_circulator_over_array< A, T, U, I>'. All
// circulators for an array `a' become invalid whenever `a' changes its
// size (due to deletions or insertions).
//
// `A' is a random access data structure and `T' its value type. `U' is
// the unsigned integral type carrying the size of the array and the
// actual index within the container. `I' is the signed integral type used
// as distance type and as index type in the random access circulator.
// TYPES
typedef A Array;
typedef Circulator_over_array<A,T,U,I> Self;
// CREATION
Circulator_over_array() : _size(0), _i(0) {}
// a circulator `circ' with singular value.
Circulator_over_array( A& array, U size, U start = 0)
: Random_access_circulator_ptrbase<T,I,U>( &array),
_size( size), _i(start) {}
// a circulator `circ' initialized to refer to the element
// `(array.*access)(start)'. The circulator `circ' contains a
// singular value if `start >= size'. Precondition: The
// expressions `(array.*access)(i)' are valid in the range
// 0 <= i < `size' .
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _i >= _size;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const {
CGAL_assertion( _ptr == c._ptr); // belong to the same array?
CGAL_assertion( _size == c._size); // same size when instantiated ?
return _i == c._i;
}
bool operator!=( const Self& c) const { return !(*this == c); }
T& operator*() const {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
return ((A*)_ptr)->operator[](_i);
}
T* operator->() const {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
return &(((A*)_ptr)->operator[](_i));
}
Self& operator++() {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
++ _i;
if ( _i >= _size)
_i = 0;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
Self& operator--() {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
if ( _i <= 0)
_i = _size - 1;
else
-- _i;
return *this;
}
Self operator--(int) {
Self tmp = *this;
--*this;
return tmp;
}
Self& operator+=( I n);
Self operator+( I n) const {
Self tmp = *this;
return tmp += n;
}
Self& operator-=( I n) { return operator+=( -n); }
Self operator-( I n) const {
Self tmp = *this;
return tmp += -n;
}
I operator-( const Self& c) const {
CGAL_assertion( _ptr == c._ptr); // belong to the same array?
CGAL_assertion( _size == c._size); // same size when instantiated ?
return _i - c._i;
}
T& operator[](I n) const {
Self tmp = *this;
tmp += n;
return tmp.operator*();
}
Self min_circulator() {
return Self( *((A*)_ptr), _size);
}
// no relational ordering
};
template < class Dist, class A, class T, class U, class I>
inline
Circulator_over_array< A, T, U, I>
operator+( Dist n, const Circulator_over_array< A, T, U, I>& circ) {
Circulator_over_array< A, T, U, I> tmp = circ;
return tmp += I(n);
}
template < class A, class T, class U, class I>
Circulator_over_array< A, T, U, I>&
Circulator_over_array< A, T, U, I>::
operator+=( I n) {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
_i = non_negative_mod( (I)(_i) + n, _size);
CGAL_assertion( _i < _size);
return *this;
}
template < class A, class T, class U, class I>
class Const_circulator_over_array
: public Random_access_circulator_ptrbase<T,I,U> {
U _size;
U _i;
public:
// TYPES
typedef A Array;
typedef Const_circulator_over_array<A,T,U,I> Self;
// New creation variable is: `circ'
//
// CREATION
Const_circulator_over_array() : _size(0), _i(0) {}
// a const circulator `circ' with singular value.
Const_circulator_over_array( const A& array, U size, U start = 0)
: Random_access_circulator_ptrbase<T,I,U>(
(void*)(&array)), _size( size), _i(start) {}
// a const circulator `circ' initialized to refer to the element
// `(array.*access)(start)'. The circulator `circ' contains a
// singular value if `start >= size'. Precondition: The
// expressions `(array.*access)(i)' are valid in the range
// 0 <= i < `size' .
//
// OPERATIONS
bool operator==( CGAL_NULL_TYPE p) const {
CGAL_assertion( p == CGAL_CIRC_NULL);
return _i >= _size;
}
bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); }
bool operator==( const Self& c) const {
CGAL_assertion( _ptr == c._ptr); // belong to the same array?
CGAL_assertion( _size == c._size); // same size when instantiated ?
return _i == c._i;
}
bool operator!=( const Self& c) const { return !(*this == c); }
const T& operator*() const {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
return ((const A*)_ptr)->operator[](_i);
}
const T* operator->() const {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
return &(((const A*)_ptr)->operator[](_i));
}
Self& operator++() {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
++ _i;
if ( _i >= _size)
_i = 0;
return *this;
}
Self operator++(int) {
Self tmp = *this;
++*this;
return tmp;
}
Self& operator--() {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
if ( _i <= 0)
_i = _size - 1;
else
-- _i;
return *this;
}
Self operator--(int) {
Self tmp = *this;
--*this;
return tmp;
}
Self& operator+=( I n);
Self operator+( I n) const {
Self tmp = *this;
return tmp += n;
}
Self& operator-=( I n) {
return operator+=( -n);
}
Self operator-( I n) const {
Self tmp = *this;
return tmp += -n;
}
I
operator-( const Self& c) const {
CGAL_assertion( _ptr == c._ptr); // belong to the same array?
CGAL_assertion( _size == c._size); // same size when instantiated ?
return _i - c._i;
}
const T& operator[](I n) const {
Self tmp = *this;
tmp += n;
return tmp.operator*();
}
Self min_circulator() {
return Self( *((const A*)_ptr), _size);
}
// no relational ordering
};
template < class Dist, class A, class T, class U, class I>
inline
Const_circulator_over_array< A, T, U, I>
operator+( Dist n, const Const_circulator_over_array<A,T,U,I>& circ) {
Const_circulator_over_array< A, T, U, I> tmp = circ;
return tmp += I(n);
}
template < class A, class T, class U, class I>
Const_circulator_over_array< A, T, U, I>&
Const_circulator_over_array< A, T, U, I>::
operator+=( I n) {
CGAL_assertion( _ptr != NULL);
CGAL_assertion( _i < _size);
_i = non_negative_mod( (I)(_i) + n, _size);
CGAL_assertion( _i < _size);
return *this;
}
CGAL_END_NAMESPACE
#endif // CGAL_CIRCULATOR_IMPL_H //
// EOF //

View File

@ -0,0 +1,30 @@
Circulator Package
---------------------------------------------------------------------
- CGAL/circulator.h
Support for circulator definitions (base classes, tags etc.).
Incluces circulator_bases.h for base classes and tags.
Functions on circulators (size and distance).
Adaptors between circulators and iterators.
Support to write programs for circulators and iterators
simultaneously.
- CGAL/circulator_bases.h
Circulator base classes and tags.
- CGAL/circulator_compat.h
Old circulator.h file from CGAL R2.0. Useful for compilers
not yet supporting std::iterator_traits. Distributed to stay
compatible.
- CGAL/circulator_impl.h
Adaptors that provide circulators for common types of
data structures like circular linked lists or arrays.
No longer supported in the documentation. Please refer
to the CGAL 0.9 Support Library manual.
Lutz Kettner

View File

@ -0,0 +1,2 @@
Submitted by: kettner@inf.ethz.ch.
URL: http://www.inf.ethz.ch/personal/kettner/CGAL/Circulator/Circulator.tar.gz.

View File

@ -0,0 +1,74 @@
#! /bin/sh
# This is a script for the CGAL test suite. Such a script must obey
# the following rules:
#
# - the name of the script is cgal_test
# - for every target two one line messages are written to the file 'error.txt'
# the first one indicates if the compilation was successful
# the second one indicates if the execution was successful
# if one of the two was not successful, the line should start with 'ERROR:'
# - running the script should not require any user interaction
# - the script should clean up object files and executables
ERRORFILE=error.txt
#---------------------------------------------------------------------#
# compile_and_run <target>
#---------------------------------------------------------------------#
compile_and_run()
{
echo "Compiling $1 ... "
if eval 'make CGAL_MAKEFILE=$CGAL_MAKEFILE \
TESTSUITE_CXXFLAGS="$TESTSUITE_CXXFLAGS" \
TESTSUITE_LDFLAGS="$TESTSUITE_LDFLAGS" $1' ; then
echo " compilation of $1 succeeded" >> $ERRORFILE
else
echo " ERROR: compilation of $1 failed" >> $ERRORFILE
fi
if [ -f $1 ] ; then
OUTPUTFILE=ProgramOutput.$1.$PLATFORM
rm -f $OUTPUTFILE
COMMAND="./$1"
if [ -f $1.cmd ] ; then
COMMAND="$COMMAND `cat $1.cmd`"
fi
if [ -f $1.cin ] ; then
COMMAND="cat $1.cin | $COMMAND"
fi
echo "Executing $1 ... "
echo
if eval 2>&1 $COMMAND > $OUTPUTFILE ; then
echo " execution of $1 succeeded" >> $ERRORFILE
else
echo " ERROR: execution of $1 failed" >> $ERRORFILE
fi
else
echo " ERROR: could not execute $1" >> $ERRORFILE
fi
eval "2>&1 make CGAL_MAKEFILE=$CGAL_MAKEFILE clean > /dev/null "
}
#---------------------------------------------------------------------#
# remove the previous error file
#---------------------------------------------------------------------#
rm -f $ERRORFILE
touch $ERRORFILE
#---------------------------------------------------------------------#
# compile and run the tests
#---------------------------------------------------------------------#
if [ $# -ne 0 ] ; then
for file in $* ; do
compile_and_run $file
done
else
compile_and_run test_circ1
compile_and_run test_circ2
fi

View File

@ -0,0 +1,58 @@
# Created by the script create_makefile
# This is the makefile for compiling a CGAL application.
#---------------------------------------------------------------------#
# include platform specific settings
#---------------------------------------------------------------------#
# Choose the right include file from the <cgalroot>/make directory.
# CGAL_MAKEFILE = ENTER_YOUR_INCLUDE_MAKEFILE_HERE
include $(CGAL_MAKEFILE)
#---------------------------------------------------------------------#
# compiler flags
#---------------------------------------------------------------------#
CXXFLAGS = \
$(TESTSUITE_CXXFLAGS) \
$(EXTRA_FLAGS) \
$(CGAL_CXXFLAGS) \
$(DEBUG_OPT)
#---------------------------------------------------------------------#
# linker flags
#---------------------------------------------------------------------#
LIBPATH = \
$(TESTSUITE_LIBPATH) \
$(CGAL_LIBPATH)
LDFLAGS = \
$(TESTSUITE_LDFLAGS) \
$(CGAL_LDFLAGS)
#---------------------------------------------------------------------#
# target entries
#---------------------------------------------------------------------#
all: \
test_circ1 \
test_circ2
test_circ1$(EXE_EXT): test_circ1$(OBJ_EXT)
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)test_circ1 test_circ1$(OBJ_EXT) $(LDFLAGS)
test_circ2$(EXE_EXT): test_circ2$(OBJ_EXT)
$(CGAL_CXX) $(LIBPATH) $(EXE_OPT)test_circ2 test_circ2$(OBJ_EXT) $(LDFLAGS)
clean: \
test_circ1.clean \
test_circ2.clean
#---------------------------------------------------------------------#
# suffix rules
#---------------------------------------------------------------------#
.C$(OBJ_EXT):
$(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $<

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
3.4 (02 Sep 1999)