mirror of https://github.com/CGAL/cgal
Initial revision
This commit is contained in:
parent
ca20f09a33
commit
bcfbe32c19
|
|
@ -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).
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
Circulator support and adaptors.
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 %%
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 %%
|
||||
|
|
@ -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 %%
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 %%
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 %%
|
||||
|
|
@ -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 %%
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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 //
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Submitted by: kettner@inf.ethz.ch.
|
||||
URL: http://www.inf.ethz.ch/personal/kettner/CGAL/Circulator/Circulator.tar.gz.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
3.4 (02 Sep 1999)
|
||||
Loading…
Reference in New Issue