diff --git a/Packages/Circulator/changes.txt b/Packages/Circulator/changes.txt new file mode 100644 index 00000000000..73c7bca178e --- /dev/null +++ b/Packages/Circulator/changes.txt @@ -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). + + diff --git a/Packages/Circulator/description.txt b/Packages/Circulator/description.txt new file mode 100644 index 00000000000..f72424a60a1 --- /dev/null +++ b/Packages/Circulator/description.txt @@ -0,0 +1 @@ +Circulator support and adaptors. diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Assert_circulator.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Assert_circulator.tex new file mode 100644 index 00000000000..ca0c3d9b888 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Assert_circulator.tex @@ -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 void}{X}{} + +\ccGlobalFunction{template + void Assert_circulator( const C &c);} +\ccGlue + +\ccGlobalFunction{template + void Assert_iterator( const I &i);} +\ccGlue + +\ccGlobalFunction{template< class IC> + void Assert_circulator_or_iterator(const IC& i);} + +\ccGlobalFunction{template + void Assert_input_category( const I &i);} +\ccGlue + +\ccGlobalFunction{template + void Assert_output_category( const I &i);} +\ccGlue + +\ccGlobalFunction{template + void Assert_forward_category( const IC &ic);} +\ccGlue + +\ccGlobalFunction{template + void Assert_bidirectional_category( const IC &ic);} +\ccGlue + +\ccGlobalFunction{template + 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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator.tex new file mode 100644 index 00000000000..7a1516668f0 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator.tex @@ -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 +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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_from_container.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_from_container.tex new file mode 100644 index 00000000000..880592dd9ee --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_from_container.tex @@ -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} +\label{pageCircFromContainerRef} + +\ccHtmlCrossLink{Const_circulator_from_container} +\ccHtmlCrossLink{Const_circulator_from_container} +\ccHtmlIndexC[class]{Const_circulator_from_container} + +\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}. + +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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_from_iterator.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_from_iterator.tex new file mode 100644 index 00000000000..f7036af9892 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_from_iterator.tex @@ -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} +\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& 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 c(b,e)} is a random circulator +\ccStyle{c} over this array. + +\end{ccRefClass} + +% +-----------------------------------------------------+ +% EOF diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_tag.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_tag.tex new file mode 100644 index 00000000000..f53896f7d17 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_tag.tex @@ -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} +\ccHtmlIndexC[class]{Circulator_base} + +\ccHtmlCrossLink{Forward_circulator_base} +\ccHtmlCrossLink{Forward_circulator_base} +\ccHtmlIndexC[class]{Forward_circulator_base} +\ccHtmlCrossLink{Bidirectional_circulator_base} +\ccHtmlCrossLink{Bidirectional_circulator_base} +\ccHtmlIndexC[class]{Bidirectional_circulator_base} +\ccHtmlCrossLink{Random_access_circulator_base} +\ccHtmlCrossLink{Random_access_circulator_base} +\ccHtmlIndexC[class]{Random_access_circulator_base} + +\ccHtmlCrossLink{Forward_circulator_ptrbase} +\ccHtmlCrossLink{Forward_circulator_ptrbase} +\ccHtmlIndexC[class]{Forward_circulator_ptrbase} +\ccHtmlCrossLink{Bidirectional_circulator_ptrbase} +\ccHtmlCrossLink{Bidirectional_circulator_ptrbase} +\ccHtmlIndexC[class]{Bidirectional_circulator_ptrbase} +\ccHtmlCrossLink{Random_access_circulator_ptrbase} +\ccHtmlCrossLink{Random_access_circulator_ptrbase} +\ccHtmlIndexC[class]{Random_access_circulator_ptrbase} + +\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 + struct Forward_circulator_base {};}{} +\ccGlue +\ccStruct{template + struct Bidirectional_circulator_base {};}{} +\ccGlue +\ccStruct{template + 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 Forward_circulator_ptrbase {};}{% + forward circulator.} +\ccGlue +\ccStruct{template + class Bidirectional_circulator_ptrbase {};}{% + bidirectional circulator.} +\ccGlue +\ccStruct{template + class Random_access_circulator_ptrbase {};}{% + random access circulator.} + +\end{ccRefClass} +% +-----------------------------------------------------+ +% EOF diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_traits.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_traits.tex new file mode 100644 index 00000000000..2339f178d09 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Circulator_traits.tex @@ -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} + +\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:: \ \ 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 +void bar( I i, I j, CGAL::Iterator_tag) { + CGAL::Assert_iterator(i); + // This function is called for iterator ranges [i,j). +} +template +void bar( C c, C d, CGAL::Circulator_tag) { + CGAL::Assert_circulator(c); + // This function is called for circulator ranges [c,d). +} +template +void bar( IC i, IC j) { // calls the correct function + return bar( i, j, typename CGAL::Circulator_traits::category()); +} +\end{ccExampleCode} + +\end{ccRefClass} +% +-----------------------------------------------------+ + +% EOF diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Container_from_circulator.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Container_from_circulator.tex new file mode 100644 index 00000000000..a8725d53163 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/Container_from_circulator.tex @@ -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} + +\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 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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/For_all.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/For_all.tex new file mode 100644 index 00000000000..f6fbbe17e16 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/For_all.tex @@ -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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/circulator_distance.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/circulator_distance.tex new file mode 100644 index 00000000000..3463f9ed540 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/circulator_distance.tex @@ -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 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 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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/circulator_size.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/circulator_size.tex new file mode 100644 index 00000000000..cb5ed65b51f --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/circulator_size.tex @@ -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 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 C::size_type circulator_size(C c);} + +\ccSeeAlso + +\ccc{circulator_distance}, +\ccc{iterator_distance}, +\ccc{is_empty_range}, +\ccc{Circulator}. + +\end{ccRefFunction} + +% +-----------------------------------------------------+ +% EOF diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/intro.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/intro.tex new file mode 100644 index 00000000000..b55cefd762a --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/intro.tex @@ -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}\\ +\ccRefIdfierPage{CGAL::Circulator_from_iterator}\\ +\ccRefIdfierPage{CGAL::Circulator_from_container}\\ +\ccc{CGAL::Const_circulator_from_container} + +\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} + +\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 %% diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/is_empty_range.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/is_empty_range.tex new file mode 100644 index 00000000000..7dde298e944 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/is_empty_range.tex @@ -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 +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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/iterator_distance.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/iterator_distance.tex new file mode 100644 index 00000000000..f7bef237e7b --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/iterator_distance.tex @@ -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::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 iterator_traits::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 diff --git a/Packages/Circulator/doc_tex/Circulator/Circulator_ref/query_circulator_or_iterator.tex b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/query_circulator_or_iterator.tex new file mode 100644 index 00000000000..4a4e0809023 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/Circulator_ref/query_circulator_or_iterator.tex @@ -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 + Iterator_tag query_circulator_or_iterator( const I& i);}{ + if the iterator category of \ccc{I} belongs to an iterator.} + +\ccFunction{template + 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 diff --git a/Packages/Circulator/doc_tex/Circulator/cgal.bib b/Packages/Circulator/doc_tex/Circulator/cgal.bib new file mode 100644 index 00000000000..138a5dac8ac --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/cgal.bib @@ -0,0 +1,1082 @@ +% ------------------------------------------------------------------------ +% cgal.bib +% -------- +% BiBTeX references used in the CGAL project which are not in geombib. +% geombib is available from: +% +% file://ftp.cs.usask.ca/pub/geometry/geombib.tar.Z +% +% 29.04.1997 Lutz Kettner kettner_inf.ethz.ch +% +% annote entry might contain "recommended C++ reading" or +% "recommended OO reading". +% +% ------------------------------------------------------------------------ + + +% Common abbreviations for publishers, journals, ... +% -------------------------------------------------- + +@string{ addison = {Addison-Wesley}} +@string{ mcgraw = {McGraw-Hill}} +@string{ academic = {Academic Press}} +@string{ springer = {Springer Verlag}} +@string{ oldenbourg = {Oldenbourg Verlag, M\"unchen, Wien}} +@string{ gruyter = {Walter de Gruyter, Berlin}} +@string{ elsevier = {Elsevier Science Publishers, Amsterdam, The + Netherlands}} +@string{ acm = {ACM Press}} +@string{ wiley = {John Wiley \& Sons, New York}} +@string{ cambridge = {Cambridge University Press}} +@string{ kaufmann = {Morgan Kaufmann}} +@string{ kluwer = {Kluwer Academic Publishers Group}} + +% Alphabetically sorted list of references. +% ----------------------------------------- + +@incollection{ a-cgs-97 + ,author = "N. Amenta" + ,title = "Computational Geometry Software" + ,booktitle = "Handbook of Discrete and Computational Geometry" + ,editors = "J. Goodman and J. O'Rourke" + ,publisher = "CRC Press" + ,year = "1997" + ,pages = "951--960" + ,update = "98.01 schirra" +} + +@inproceedings{ a-nqimr-67 + ,author = {Arthur Appel} + ,title = {The Notion of Quantitive Invisibility and the + Machine Rendering of Solids} + ,booktitle = {Proc. ACM National Conf.} + ,year = 1967 + ,pages = {387--393} + ,annote = {Basis for the contour edge idea in hidden surface + removal.} + ,update = "97.04 kettner" +} + +@book{ bn-sec++-94 + ,author = "J. J. Barton and L. R. Nackman" + ,title = "Scientific and Engineering {C{\tt ++}}" + ,publisher = "Addison-Wesley, Reading, MA" + ,year = "1997" + ,update = "98.01 schirra" +} + +@inproceedings{ bfh-mgedm-95 + ,author = {Heinzgerd Bendels and Dieter W. Fellner and Sven + Havemann} + ,title = {Modellierung der Grundlagen: Erweiterbare + Datenstrukturen zur Modellierung und Visualisierung + polygonaler Welten} + ,booktitle = {Modeling -- Virtual Worlds -- Distributed Graphics} + ,year = 1995 + ,editor = {D. W. Fellner} + ,pages = {149--157} + ,address = {Bad Honnef / Bonn} + ,month = {27.--28. November} + ,annote = {A reference for the halfedge data structure and + Euler operators (preserving the topological type).} + ,update = "97.04 kettner" +} + +@misc{ bpp-vrml-95 + ,author = {Gavin Bell and Anthony Parisi and Mark Pesce} + ,title = {VRML The Virtual Reality Modeling Language: + Version 1.0 Specification} + ,howpublished = {\path|http://www.vrml.org/|} + ,month = {May 26} + ,year = 1995 + ,note = {Third Draft} + ,update = "97.04 kettner" +} + +@incollection{ bv-sbc-96 + ,author = "G. Booch and M. Vilot" + ,title = "Simplifying the Booch Components" + ,booktitle = "{\CC\ }Gems" + ,publisher = "SIGS publications" + ,editor = "Lippman, S." + ,year = "1996" + ,pages = "59--89" + ,update = "98.01 schirra" +} + +@incollection{ cgal-nt-97 + ,author = {{CGAL} consortium} + ,title = {Number Types} + ,booktitle = {{CGAL} Reference Manual. {P}art 3: {S}upport Library} + ,editor = {Andreas Fabri and Stefan Schirra and + Remco Veltkamp} + ,year = 1997 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "98.01 giezeman" +} + +@misc{ + ,author = {{CGAL} consortium} + ,title = {{CGAL} Workpackage 4, Report 2} + ,howpublished = {\path|http://www.cs.ruu.nl/CGAL|} + ,month = {fall} + ,year = 1997 + ,update = "98.01 kettner" +} + +@misc{ + ,author = {{CGAL} consortium} + ,title = {{CGAL} Workpackage 4, Report 1} + ,howpublished = {\path|http://www.cs.ruu.nl/CGAL|} + ,month = apr + ,year = 1997 + ,update = "98.01 kettner" +} + +@inproceedings{ cvmtwabw-se-96 + ,author = {Jonathan Cohen and Amitabh Varshney and Dinesh + Manocha and Greg Turk and Hans Weber and Pankaj + Agarwal and Frederick Brooks and William Wright} + ,title = {Simplification Envelopes} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '96)" + ,volume = 30 + ,year = 1996 + ,pages = {119--128} + ,note = {Examples and code in + \path|http://www.cs.unc.edu/~geom/envelope.html|} + ,update = "97.08 kettner" +} + +@inproceedings{ cl-vmbcm-96 + ,author = {Brian Curless and Marc Levoy} + ,title = {A Volumetric Method for Building Complex + Models from Range Images} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '96)" + ,volume = 30 + ,year = 1996 + ,pages = {303--312} + ,update = "97.08 kettner" +} + +@misc{ c-wpdpi-95 + ,key = {C++AnsiDraft} + ,title = "Working Paper for Draft Proposed International + Standard for Information Systems -- Programming + Language {C{\tt ++}}" + ,howpublished = {ANSI X3, Information Processing Systems} + ,month = apr + ,year = 1995 + ,note = {\path|http://www.cygnus.com/misc/wp/|} + ,update = "97.04 kettner" +} + +@misc{ c-wpdpi-96 + ,key = {{C}{\tt ++}} + ,title = "Working Paper for Draft Proposed International + Standard for Information Systems -- Programming + Language {C{\tt ++}}" + ,howpublished = {Doc.~No.~X3J16/96 - 0225 - WG21/N1043} + ,month = Dec + ,year = 1996 + ,note = {\path|http://www.maths.warwick.ac.uk/c++/pub/|} + ,update = "97.04 kettner, 98.02 schirra" +} + +@misc{ c-isplc-98 + ,key = {{C}{\tt ++}} + ,title = "International Standard ISO/IEC 14882: + Programming languages -- {C{\tt ++}}" + ,howpublished = {American National Standards Institute, 11 West 42nd + Street, New York 10036} + ,year = 1998 + ,mynote = {\path|http://webstore.ansi.org/|} + ,update = "99.02 kettner" +} + +@misc{ c-isplc-98 + ,key = {{C}{\tt ++}} + ,title = "International Standard ISO/IEC 14882: + Programming languages -- {C{\tt ++}}" + ,howpublished = {American National Standards Institute, 11 West 42nd + Street, New York 10036} + ,year = 1998 + ,mynote = {\path|http://webstore.ansi.org/|} + ,update = "98.11 kettner" +} + +@misc{ OLD-c-wpdpi-96 + ,key = {C++AnsiDraft} + ,title = "Working Paper for Draft Proposed International + Standard for Information Systems -- Programming + Language {C{\tt ++}}" + ,howpublished = {ANSI X3, Information Processing Systems} + ,month = dec + ,year = 1996 + ,note = {\path|http://www.maths.warwick.ac.uk/c++/pub/|} + ,update = "97.04 kettner" +} + +@inproceedings{ eddhls-maam-95 + ,author = {Matthias Eck and Tony DeRose and Tom Duchamp and + Hugues Hoppe and Michael Lounsbery and Werner Stuetzle} + ,title = {Multiresolution Analysis of Arbitrary Meshes} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '95)" + ,volume = 29 + ,year = 1995 + ,pages = {173--182} + ,note = {Examples in + \path|file://ftp.cs.washington.edu/pub/graphics|} + ,update = "97.08 kettner" +} + +@inproceedings{ fgkss-ckbgc-96 + ,author = {Andreas Fabri and Geert-Jan Giezeman and Lutz + Kettner and Stefan Schirra and Sven Sch{\"o}nherr} + ,title = {The {CGAL} Kernel: A Basis for Geometric Computation} + ,booktitle = {ACM Workshop on Applied Computational Geometry} + ,editor = {M. C. Lin and D. Manocha} + ,address = {Philadelphia, Pennsylvenia} + ,month = {May, 27--28} + ,year = 1996 + ,pages = {191--202} + ,note = {Springer Lecture Notes in Computer Science 1148} + ,update = "97.04 kettner" +} + +@book{ f-sec-85 + ,author = {Richard Fairley} + ,title = {Software Engineering Concepts} + ,publisher = {McGraw-Hill} + ,year = 1985 + ,series = {McGraw-Hill Series in Software Engineering and Technology} + ,annote = {recommended software engineering reading. + Topics from pre-object-oriented software engineering.} + ,update = "98.01 kettner" +} + +@book{ ghjv-dpero-95 + ,author = {E. Gamma and R. Helm and R. Johnson and J. Vlissides} + ,title = {Design Patterns -- Elements of Reusable + Object-Oriented Software} + ,publisher = addison + ,year = 1995 + ,annote = {recommended OO reading.} + ,update = "97.04 kettner" +} + +@article{ g-ieva-85 + ,author = {Ronald N. Goldman} + ,title = {Illicit Expressions in Vector Algebra} + ,journal = {ACM Transaction on Graphics} + ,year = 1985 + ,volume = 4 + ,number = 3 + ,month = jul + ,pages = {223--243} + ,update = "98.01 kettner" +} + +@book{ hw-vrml2h-96 + ,author = {Jed Hartman and Josie Wernecke} + ,title = {The {VRML} 2.0 Handbook: Building Moving Worlds on the + Web} + ,publisher = addison + ,year = 1996 + ,annote = {The VRML 2.0 Introduction and Reference by + Silicon Graphics.} + ,update = "98.02 kettner" +} + +@misc{ h-97 + ,author = {Michael Hoffmann} + ,year = 1997 + ,note = {personal communication} + ,update = "98.01 kettner" +} + +@inproceedings{ hddms-srup-92 + ,author = {Hugues Hoppe and Tony DeRose and Tom Duchamp and + John McDonald and Werner Stuetzle} + ,title = {Surface Reconstruction from Unorganized Points} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '90)" + ,volume = 26 + ,year = 1992 + ,pages = {71--77} + ,update = "97.08 kettner" +} + +@inproceedings{ hddms-mo-93 + ,author = {Hugues Hoppe and Tony DeRose and Tom Duchamp and + John McDonald and Werner Stuetzle} + ,title = {Mesh Optimization} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '93)" + ,volume = 27 + ,year = 1993 + ,pages = {19--26} + ,note = {Examples and code in + \path|file://ftp.cs.washington.edu/pub/graphics|} + ,update = "97.08 kettner" +} + +@phdthesis{ h-srup-94 + ,author = {Hugues Hoppe} + ,title = {Surface reconstruction from unorganized points} + ,school = {University of Washington} + ,year = 1994 + ,update = "97.08 kettner" +} + +@inproceedings{ hddhjmss-pssr-94 + ,author = {Hugues Hoppe and Tony DeRose and Tom Duchamp and + Mark Halstaed and Hubert Jin and John McDonald and + Jean Schweitzer and Werner Stuetzle} + ,title = {Piecewise Smooth Surface Reconstruction} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '94)" + ,volume = 28 + ,year = 1994 + ,pages = {295--302} + ,note = {Examples and code in + \path|file://ftp.cs.washington.edu/pub/graphics|} + ,update = "97.08 kettner" +} + +@inproceedings{ h-pm-96 + ,author = {Hugues Hoppe} + ,title = {Progressive Meshes} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '96)" + ,volume = 30 + ,year = 1996 + ,pages = {99--108} + ,update = "97.08 kettner" +} + +@incollection{ k-dat-96 + ,author = "Keffer, T." + ,title = "The Design and Architecture of {T}ools.h{\tt ++}" + ,booktitle = "{C{\tt ++}}~Gems" + ,publisher = "SIGS publications" + ,editor = "Lippman, S." + ,year = "1996" + ,pages = "43--57" + ,update = "98.01 schirra" +} + +@incollection{ kw-ceapp-97 + ,author = {Lutz Kettner and Emo Welzl} + ,title = {Contour Edge Analysis for Polyhedron Projections} + ,booktitle = {Geometric Modeling: Theory and Practice} + ,year = 1997 + ,pages = {379--394} + ,publisher = {Springer Verlag} + ,editor = {Wolfgang Strasser and Reinhard Klein and Rene Rau} + ,update = "97.04 kettner, 97.08 kettner" +} + +@incollection{ kw-osepg-98 + ,author = {Lutz Kettner and Emo Welzl} + ,title = {One Sided Error Predicates in Geometric Computing} + ,booktitle = {Proc. 15th IFIP World Computer Congress, + Fundamentals - Foundations of Computer Science} + ,year = 1998 + ,pages = {13--26} + ,editor = {Kurt Mehlhorn} + ,update = "98.08 kettner" +} + +@inproceedings{ k-ddsps-98 + ,author = {Lutz Kettner} + ,title = {Designing a Data Structure for Polyhedral Surfaces} + ,booktitle = {Proc. 14th Annu. ACM Sympos. Comput. Geom.} + ,year = 1998 + ,pages = {146--154} + ,abstract = { + Design solutions for a program library are presented for combinatorial + data structures in computational geometry, such as planar maps and + polyhedral surfaces. Design issues considered are genericity, + flexibility, time and space efficiency, and ease-of-use. We focus on + topological aspects of polyhedral surfaces. Edge-based representations + for polyhedrons are evaluated with respect to the design goals. A + design for polyhedral surfaces in a halfedge data structure is + developed following the generic programming paradigm known from the + Standard Template Library STL for C++. Connections are shown to planar + maps and face-based structures managing holes in facets} +} + +@techreport{ k-ddsps-97 + ,author = {Lutz Kettner} + ,title = {Designing a Data Structure for Polyhedral Surfaces} + ,institution = {Department Informatik, ETH Z{\"u}rich} + ,year = 1997 + ,type = {Technical Report} + ,number = {\#278} + ,address = {Switzerland} + ,pages = {27} + ,month = dec + ,abstract = { + Design solutions for a program library are presented for combinatorial + data structures in computational geometry, such as planar maps and + polyhedral surfaces. Design issues considered are genericity, + flexibility, time and space efficiency, and ease-of-use. We focus on + topological aspects of polyhedral surfaces. Edge-based representations + for polyhedrons are evaluated with respect to the design goals. A + design for polyhedral surfaces in a halfedge data structure is + developed following the generic programming paradigm known from the + Standard Template Library STL for C++. Connections are shown to planar + maps and face-based structures managing holes in facets} + ,update = "98.01 kettner" +} + +@incollection{ k-ps-97 + ,author = {Lutz Kettner} + ,title = {{3D}-Polyhedral Surfaces} + ,booktitle = {{CGAL} Reference Manual. Part 2: Basic Library} + ,editor = {Andreas Fabri and Stefan Schirra and Remco Veltkamp} + ,year = 1997 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner" +} + +@incollection{ k-c-97 + ,author = {Lutz Kettner} + ,title = {Circulators} + ,booktitle = {{CGAL} Reference Manual. Part 3: Support Library} + ,editor = {Andreas Fabri and Stefan Schirra and Remco Veltkamp} + ,year = 1997 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner" +} + +@article{ k-ugpdd-99 + ,author = {Lutz Kettner} + ,title = {Using Generic Programming for + Designing a Data Structure for Polyhedral Surfaces} + ,journal = {Computational Geometry: Theory and Applications} + ,year = 1999 + ,note = {to appear} + ,abstract = { + Design solutions for a program library are presented for combinatorial + data structures in computational geometry, such as planar maps and + polyhedral surfaces. Design issues considered are genericity, + flexibility, time and space efficiency, and ease-of-use. We focus on + topological aspects of polyhedral surfaces. Edge-based representations + for polyhedrons are evaluated with respect to the design goals. A + design for polyhedral surfaces in a halfedge data structure is + developed following the generic programming paradigm known from the + Standard Template Library STL for C++. Connections are shown to planar + maps and face-based structures managing holes in facets} + ,update = "99.03 kettner" +} + +@manual{ kl-cssd-94 + ,title = {The {CWEB} System of Structured Documentation} + ,author = {Donald E. Knuth and Silvio Levy} + ,edition = {Version 3.0} + ,year = 1994 + ,update = "98.01 kettner" +} + +@article{ k-lp-84 + ,author = {Donald E. Knuth} + ,title = {Literate Programming} + ,journal = {The Computer Journal} + ,year = 1984 + ,volume = 27 + ,number = 2 + ,pages = {97--111} + ,update = "98.01 kettner" +} + +@article{ kl-isc++l-96 + ,author = "K. Kreft and A. Langer" + ,title = "Iterators in the Standard {\CC\ }Library" + ,journal = "{C{\tt ++}}~Report" + ,volume = "8" + ,number = "10" + ,month = "Nov.-Dec." + ,year = "1996" + ,pages = "27--32" + ,update = "98.01 schirra" +} + +@techreport{ kw-dat-96 + ,author = {Dietmar K{\"u}hl and Karsten Weihe} + ,title = {Data Access Templates} + ,institution = {Universit\"at Konstanz, Germany} + ,year = 1996 + ,type = {Konstanzer Schriften in Mathematik und Informatik} + ,number = {Nr. 9} + ,month = may + ,note = {\path|http://www.informatik.uni-konstanz.de/Schriften|} + ,annote = {recommended C++ reading.} + ,update = "97.04 kettner" +} + +@book{ l-lscsd-96 + ,author = {John Lakos} + ,title = {Large Scale {C{\tt ++}} Software Design} + ,publisher = addison + ,year = 1996 + ,annote = {recommended OO reading.} + ,update = "97.04 kettner" +} + +@inproceedings{ l-vgasa-96 + ,author = "D. T. Lee" + ,title = "Visualizing Geometric Algorithms -- State of the Art" + ,editor = "M. C. Lin and D. Manocha" + ,booktitle = "Applied Computational Geometry (Proc. WACG~'96)" + ,series = "Lecture Notes Comput. Sci." + ,volume = 1148 + ,publisher = "Springer-Verlag" + ,year = 1996 + ,pages = "45--50" + ,update = "98.01 schirra" +} + +@book{ l-icom-96 + ,author = {Stanley B. Lippman} + ,title = {Inside the {C{\tt ++}} Object Model} + ,publisher = addison + ,year = 1996 + ,annote = {Insides into C++ compiler implementations. + Performance issues of various C++ features. } + ,update = "97.04 kettner" +} + +@book{ m-wsc-93 + ,author = {Steve Maguire} + ,title = {Writing Solid Code} + ,publisher = {Microsoft Press} + ,year = 1993 + ,annote = {Microsoft's techniques for developing bug-free C programs} + ,update = "98.01 schirra" +} + +@inproceedings{ m-pppd-96 + ,author = "Kurt Mehlhorn" + ,title = "Position Paper for Panel Discussion" + ,editor = "M. C. Lin and D. Manocha" + ,booktitle = "Applied Computational Geometry (Proc. WACG~'96)" + ,series = "Lecture Notes Comput. Sci." + ,volume = 1148 + ,publisher = "Springer-Verlag" + ,year = 1996 + ,pages = "51--52" + ,update = "98.01 schirra" +} + +@manual{ mnu-lum-97 + ,author = {Mehlhorn, K. and N\"aher, S. and Uhrig, C.} + ,title = {The {LEDA} {U}ser {M}anual, {V}ersion 3.5} + ,organization = {Max-Planck-Insitut f\"ur Informatik} + ,address = {66123 Saarbr\"ucken, Germany} + ,year = {1997} + ,note = {\path|http://www.mpi-sb.mpg.de/LEDA/leda.html|} + ,update = "97.12 kettner, 98.02 schirra" +} + +@manual{ OLD-mnu-lum-97 + ,title = {The {LEDA} {U}ser {M}anual, {V}ersion 3.5} + ,author = {Kurt Mehlhorn and Stefan N{\"a}her and Christian Uhrig} + ,organization = {LEDA Software GmbH} + ,address = {66123 Saarbr\"ucken, Germany} + ,year = 1997 + ,update = "97.12 kettner" +} + +@book{ m-ec-92 + ,author = {Scott Meyers} + ,title = "Effective {C{\tt ++}}" + ,publisher = addison + ,year = 1992 + ,annote = {recommended C++ reading. 50 Specific Ways to + Improve Your Programs and Designs} + ,update = "97.04 schönherr" +} + +@book{ m-mec-96 + ,author = {Scott Meyers} + ,title = "More Effective {C{\tt ++}}" + ,publisher = addison + ,year = 1996 + ,annote = {recommended C++ reading. 35 New Ways to + Improve Your Programs and Designs} + ,update = "97.04 schönherr" +} + +@book{ m-cst-93 + ,author = {Robert B. Murray} + ,title = "{C{\tt ++}} Strategies and Tactics" + ,publisher = addison + ,year = 1993 + ,annote = {recommended C++ reading} + ,update = "98.01 schirra" +} + +@article{ m-tnutt-95 + ,author = {Nathan C. Myers} + ,title = {Traits: a New and Useful Template Technique} + ,journal = "{C{\tt ++}}~Report" + ,year = 1995 + ,month = jun + ,annote = {recommended C++ reading. stream traits, iterator + traits, typedef's.} + ,update = "97.04 kettner" +} + +@inproceedings{ ms-gp-89 + ,author = {David R.~Musser and Alexander A.~Stepanov} + ,title = {Generic Programming} + ,booktitle = {1st Intl.\ Joint Conf.\ of ISSAC-88 and AAEC-6} + ,year = 1989 + ,pages = {13--25} + ,publisher = {Springer LNCS 358} +} + +@article{ ms-aogl-94 + ,author = {David R.~Musser and Alexander A.~Stepanov} + ,title = {Algorithm-oriented Generic Libraries} + ,journal = {Software -- Practice and Experience} + ,year = 1994 + ,volume = 24 + ,number = 7 + ,pages = {623--642} + ,month = jul +} + +@book{ ms-strg-96 + ,author = {David R. Musser and Atul Saini} + ,title = "{STL} Tutorial and Reference Guide: + {C{\tt ++}}~Programming with the Standard Template + Library" + ,publisher = addison + ,year = 1996 + ,annote = {recommended C++ reading.} + ,update = "97.04 kettner" +} + +@manual{ nu-leda32-95 + ,title = {The {L}{E}{D}{A} {U}ser {M}anual, {V}ersion {R} 3.2} + ,author = {S.~N{\"a}her and C.~Uhrig} + ,organization = {Max-Planck-Institut f\"ur Informatik} + ,address = {Saarbr\"ucken, Germany} + ,year = 1995 + ,update = "97.04 kettner" +} + +@book{ ndw-opgog-93 + ,author = {Jackie Neider and Tom Davis and Mason Woo} + ,title = {OpenGL Programming Guide: The Official Guide to + Learning OpenGL, Release 1} + ,publisher = addison + ,year = 1993 + ,update = "97.04 kettner" +} + +@inproceedings{ o-dcgal-96 + ,author = {Mark H. Overmars} + ,title = {Designing the Computational Geometry Algorithms + Library {CGAL}} + ,booktitle = {ACM Workshop on Applied Computational Geometry} + ,editor = {M. C. Lin and D. Manocha} + ,address = {Philadelphia, Pennsylvenia} + ,month = {May, 27--28} + ,year = 1996 + ,note = {Lecture Notes in Computer Science 1148} + ,update = "97.04 kettner" +} + +@article{ pc-rdp-86 + ,author = {David L. Parnas and Paul C. Clements} + ,title = {A Rational Design Process: How and Why to Fake It} + ,journal = {IEEE Transactions on Software Engineering} + ,year = 1986 + ,volume = 12 + ,number = 2 + ,pages = {251-257} + ,update = "98.01 kettner" +} + +@manual{ p-gmgv15-94 + ,title = {Geomview Manual: Geomview Version 1.5 for Silicon + Graphics Workstations} + ,author = {Mark Phillips} + ,organization = {The Geometry Center} + ,address = {University of Minnesota} + ,month = oct + ,year = 1994 + ,note = {\path|http://www.geom.umn.edu/software/download/geomview.html|} + ,annote = {Reference for object file format (OFF).} + ,update = "97.04 kettner" +} + +@book{ rbpel-oomd-91 + ,author = {James Rumbaugh and Michael Blaha and William + Premerlani and Frederick Eddy and William Lorenson} + ,title = {Object-Oriented Modeling and Design} + ,publisher = {Prentice Hall} + ,address = {Englewood Cliffs, NJ} + ,year = 1991 + ,annote = {Object and class diagram notation as used in the + book of design patterns ghjv-dpero-95.} + ,update = "97.04 kettner" +} + +@article{ r-lomom-94 + ,author = {James Rumbaugh} + ,title = {The Life of an Object Model: How the Object-Model + Changes During Development} + ,journal = {Journal of Object-Oriented Programming} + ,year = 1994 + ,volume = 7 + ,number = 1 + ,pages = {24--32} + ,month = {March/April} + ,annote = {Object and class diagram notation as used in the + book of design patterns ghjv-dpero-95.} + ,update = "97.04 kettner" +} + +@misc{ s-dcgal-96 + ,author = "S. Schirra" + ,title = "Designing a Computational Geometry Algorithms Library" + ,howpublished = "Lecture Notes for Advanced School on Algorithmic + Foundations of Geographic Information Systems, CISM, + Udine" + ,month = "September 16-20" + ,year = "1996" + ,update = "98.01 schirra" +} + +@techreport{ s-picpc-98 + ,author = {Schirra, Stefan} + ,title = {Parameterized Implementations of Classical Planar + Convex Hull Algorithms and Extreme Point Computations} + ,type = {Research Report} + ,institution = {Max-Planck-Institut f{\"u}r Informatik} + ,address = {Im Stadtwald, D-66123 Saarbr{\"u}cken, Germany} + ,number = {MPI-I-98-1-003} + ,month = {January} + ,year = {1998} + ,issn = {0946-011X} + ,update = "98.01 schirra" +} + +@incollection{s-ixgpe-91a + ,author = "Peter Schorn" + ,title = "Implementing the {XYZ} {GeoBench}: A programming + environment for geometric algorithms" + ,booktitle = "Computational Geometry --- Methods, Algorithms and + Applications: Proc. Internat. Workshop Comput. + Geom. CG '91" + ,series = "Lecture Notes Comput. Sci." + ,volume = 553 + ,publisher = "Springer-Verlag" + ,year = 1991 + ,pages = "187--202" + ,note = {\path|http://wwwjn.inf.ethz.ch/geobench/XYZGeoBench.html|} + ,update = "94.01 rote, 98.01 kettner" +} + +%%\bibitem{schutte} Michael Schutte, Zufaellige Konvexe Mengen, +%% Diplomarbeit Freie Universitaet Berlin, 1996. + +@mastersthesis{ s-zkm-96 + ,author = {Michael Schutte} + ,title = {Zuf{\"a}llige Konvexe Mengen} + ,school = {Freie Universit{\"a}t Berlin} + ,year = 1996 + ,address = {Germany} +} + +@misc{ sgcsi-stlpg-97 + ,author = {{Silicon Graphics Computer Systems{,} Inc.}} + ,title = {Standard Template Library Programmer's Guide} + ,howpublished = {\path|http://www.sgi.com/Technology/STL/|} + ,year = 1997 + ,annote = {Web reference to the STL from SGI. + recommended C++ and STL reference material.} + ,update = "97.12 kettner" +} + +@article{ ss-ablp-91 + ,author = {Lisa M. C. Smith and Mansur H. Samadzadeh} + ,title = {An Annotated Bibliography of Literate Programming} + ,journal = {ACM SIGPLAN Notices} + ,year = 1991 + ,volume = 26 + ,number = 1 + ,pages = {14--20} + ,month = jan + ,update = "98.01 kettner" +} + +@book{ s-cpl-91 + ,author = {Bjarne Stroustrup} + ,title = "The {C{\tt ++}}~Programming Language" + ,publisher = addison + ,year = 1991 + ,edition = {2nd} + ,annote = {recommended C++ reading.} + ,update = "97.04 kettner" +} + +@book{ s-cpl-97 + ,author = {Bjarne Stroustrup} + ,title = "The {C{\tt ++}}~Programming Language" + ,publisher = addison + ,year = 1997 + ,edition = {3rd} + ,annote = {recommended C++ reading.} + ,update = "97.12 kettner" +} + +@misc{ sl-stl-95 + ,author = {Alexander Stepanov and Meng Lee} + ,title = {The Standard Template Library} + ,howpublished = {\path|http://www.cs.rpi.edu/~musser/doc.ps|} + ,month = oct + ,year = 1995 + ,annote = {recommended C++ reading. Short introduction to the + STL. Precise requirements for the iterators and + containers. Explanation of iterator tags (outdated).} + ,update = "97.04 kettner" +} + +@article{ v-tm-95 + ,author = {Todd Veldhuizen} + ,title = {Template Metaprograms} + ,journal = "{C{\tt ++}}~Report" + ,year = 1995 + ,month = may + ,pages = {36--43} + ,annote = {Prime numbers at compiler time, C++ programs at + compile time, control structures, local variables.} + ,update = "98.01 kettner" +} + +@article{ v-et-95 + ,author = {Todd Veldhuizen} + ,title = {Expressions Templates} + ,journal = "{C{\tt ++}}~Report" + ,year = 1995 + ,month = jun + ,pages = {26--31} + ,annote = {Inlining vector expressions and parameter passing + of expressions at compile time. Template Metaprograms.} + ,update = "98.01 kettner" +} + +@article{ v-lactm-96 + ,author = {Todd Veldhuizen and Kumaraswamy Ponnambalam} + ,title = {Linear Algebra with {C{\tt ++}} Template Metaprograms} + ,journal = {Dr. Dobb's Journal} + ,year = 1996 + ,month = aug + ,annote = {Vector operations without temporary variables.} + ,update = "98.01 kettner" +} + +@inproceedings{ v-gpc-97 + ,author = "R. C. Veltkamp" + ,title = "Generic Programming in {CGAL}, the Computational + Geometry Algorithms Library" + ,booktitle = "Proceedings of the 6th Eurographics Workshop on + Programming Paradigms in Graphics" + ,year = "1997" + ,update = "98.01 schirra" +} + +@misc{ vrmls-96 + ,key = {VRML2} + ,title = {The Virtual Reality Modeling Language Specification: + Version 2.0, {ISO}/{IEC} {CD} 14772} + ,howpublished = {\path|http://www.vrml.org/|} + ,month = {August 4} + ,year = 1996 + ,update = "98.01 kettner" +} + +@incollection{ w-fvt-90 + ,author = {Bob Wallis} + ,title = {Forms, Vectors, and Transforms} + ,booktitle = {Graphics Gems} + ,publisher = academic + ,year = 1990 + ,editor = {Andrew S. Glassner} + ,pages = {533-538} + ,annote = {Normal vectors under affine transformations, + tensor algebra and differential geometry, triangular + interpolants, subdeviding a parametric polynomial + curve} + ,update = "98.01 kettner" +} + +@article{ w-ebdss-85 + ,author = {Kevin Weiler} + ,title = {Edge-Based Data Structures for Solid Modeling in + Curved-Surface Environments} + ,journal = {IEEE Computer Graphics and Application} + ,year = 1985 + ,volume = 5 + ,number = 1 + ,pages = {21--40} + ,month = jan + ,annote = {Good halfedge reference. reference from Foley90} + ,update = "98.01 kettner" +} + +@book{ w-impoo-94 + ,author = {Josie Wernicke} + ,title = {The Inventor Mentor: Programming Object-Oriented + 3D Graphics with Open Inventor, Release 2} + ,publisher = addison + ,year = 1994 + ,update = "97.04 kettner" +} + +@manual{ w-fum-92 + ,title = {{FunnelWeb} User's Manual} + ,author = {Ross N. Williams} + ,edition = {{V1.0} for {FunnelWeb} {V3.0}} + ,year = 1992 + ,month = may + ,update = "98.01 kettner" +} + +%% Updates by Stefan for CGAL paper, which do not follow geombib conventions. + +@inproceedings{ Me-Naeher:IFIP94 + ,author = {K. Mehlhorn and S. N\"aher} + ,title = {The Implementation of Geometric Algorithms} + ,booktitle = {13th World Computer Congress IFIP94} + ,publisher = {Elsevier Science B.V. North-Holland, Amsterdam} + ,volume = {1} + ,pages = {223--231} + ,year = {1994} + ,update = "98.01 schirra" +} + +@incollection{ s-purigc-handbook + ,key = {Sch} + ,author = "S. Schirra" + ,title = "Precision and Robustness Issues in Geometric Computation" + ,booktitle = "Handbook on Computational Geometry" + ,editors = "J. R. Sack and J. Urrutia" + ,publisher = elsevier + ,year = "1998" + ,update = "98.01 schirra" +} + +@manual{ Protocgal + ,author = {Avnaim, F.} + ,title = "{C}{\tt ++}{GAL}: {A} {C}{\tt ++} Library for Geometric + Algorithms" + ,organization = {INRIA Sophia-Antipolis} + ,year = 1994 + ,update = "98.01 schirra" +} + +@manual{ PlaGeo + ,author = {Giezeman, G.-J.} + ,title = {{PlaGeo}, a library for planar geometry, and {SpaGeo}, + a library for spatial geometry} + ,organization = {Utrecht University} + ,year = 1994 + ,update = "98.01 schirra" +} + +@article{ LEDA_ACM + ,author = {Mehlhorn, K. and N\"aher, S.} + ,title = {{LEDA}, a Platform for Combinatorial and + Geometric Computing} + ,journal = {Communications of the ACM} + ,volume = {38} + ,pages = {96-102} + ,year = {1995} + ,update = "98.01 schirra" +} + +%% manuscript{ geomlib ?? + +@misc{ geomlib + ,author = {Baker, J. E. and Tamassia, R. and Vismara, L.} + ,title = {{GeomLib}: {A}lgorithm Engineering for a Geometric + Computing Library} + ,note = {(Preliminary report)} + ,institution = {Center for Geometric Computing} + ,year = {1997} + ,update = "98.01 schirra" +} + +@manual{ gmp + ,title = {{GNU MP}, The {GNU} Multiple Precision Arithmetic Library} + ,author = {Granlund, T.} + ,edition = {2.0.2} + ,month = {June} + ,year = {1996} + ,update = "98.01 schirra" +} + +@techreport{ reals_TR + ,author = {Burnikel, C. and Mehlhorn, K. and Schirra, S.} + ,title = {The {LEDA} Class {\tt real} Number} + ,institution = {Max-Planck-Institut f\"ur Informatik} + ,number = {MPI-I-96-1-001} + ,year = 1996 + ,update = "98.01 schirra" +} + +@techreport{bp_lsi_TR + ,author = "Boissonnat, J.-D. and Preparata, F." + ,title = "Robust plane sweep for intersecting segments" + ,institution = {INRIA} + ,address = {Sophia-Antipolis, France} + ,number = {3270} + ,year = {September 1997} + ,update = "98.01 schirra" +} + +@incollection{ cgal-nt-98 + ,author = {{CGAL} consortium} + ,title = {Number Types} + ,booktitle = {{CGAL} Reference Manual. {P}art 3: {S}upport Library} + ,editor = {Herv\'e Br\"onnimann and Andreas Fabri and + Stefan Schirra and Remco Veltkamp} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "98.01 giezeman, 98.01 schönherr, 98.02 schirra" +} + +@manual{ gvw-gsc-98 + ,author = {Geert-Jan Giezeman and Remco Veltkamp and + Wieger Wesselink} + ,title = {Getting Started with {CGAL}} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "98.01 schönherr" +} + +@incollection{ k-ps-98 + ,author = {Lutz Kettner} + ,title = {{3D}-Polyhedral Surfaces} + ,booktitle = {{CGAL} Reference Manual. Part 2: Basic Library} + ,editor = {Herv\'e Br\"onnimann and Andreas Fabri and + Stefan Schirra and Remco Veltkamp} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner, 98.01 schönherr, 98.02 schirra" +} + +@incollection{ k-c-98 + ,author = {Lutz Kettner} + ,title = {Circulators} + ,booktitle = {{CGAL} Reference Manual. Part 3: Support Library} + ,editor = {Herv\'e Br\"onnimann and Andreas Fabri and + Stefan Schirra and Remco Veltkamp} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner, 98.01 schönherr, 98.02 schirra" +} + +%% EOF %% diff --git a/Packages/Circulator/doc_tex/Circulator/circulator.tex b/Packages/Circulator/doc_tex/Circulator/circulator.tex new file mode 100644 index 00000000000..e5252a75b77 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/circulator.tex @@ -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 +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 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 v; +typedef CGAL::Circulator_from_iterator< + std::vector::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 diff --git a/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog1.C b/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog1.C new file mode 100644 index 00000000000..c8a458c828e --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog1.C @@ -0,0 +1,28 @@ +// circulator_prog1.C +// ------------------------ +#include +#include +#include +#include +#include + +typedef std::vector::iterator I; +typedef CGAL::Circulator_from_iterator Circulator; +typedef CGAL::Container_from_circulator Container; +typedef Container::iterator Iterator; + +int main() { + std::vector 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; +} diff --git a/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog2.C b/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog2.C new file mode 100644 index 00000000000..e60a8906906 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog2.C @@ -0,0 +1,27 @@ +// circulator_prog2.C +// ------------------------ +#include +#include +#include +#include +#include + +typedef CGAL::Circulator_from_container< std::vector > Circulator; +typedef CGAL::Container_from_circulator Container; +typedef Container::iterator Iterator; + +int main() { + std::vector 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; +} diff --git a/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog3.C b/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog3.C new file mode 100644 index 00000000000..4094ed56712 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/examples/Circulator/circulator_prog3.C @@ -0,0 +1,45 @@ +// circulator_prog3.C +// ------------------------ +#include +#include +#include +#include + +template inline int foo( C c, std::forward_iterator_tag) { + CGAL::Assert_circulator( c); + CGAL::Assert_forward_category( c); + return 1; +} +template inline int foo( C c, std::random_access_iterator_tag) { + CGAL::Assert_circulator( c); + CGAL::Assert_random_access_category( c); + return 2; +} +template inline int foo( I i, CGAL::Iterator_tag) { + CGAL::Assert_iterator( i); + return 3; +} + +template inline int foo( C c, CGAL::Circulator_tag) { + CGAL::Assert_circulator( c); + typedef std::iterator_traits Traits; + typedef typename Traits::iterator_category iterator_category; + return foo( c, iterator_category()); +} +template inline int foo( IC ic) { + typedef CGAL::Circulator_traits Traits; + typedef typename Traits::category category; + return foo( ic, category()); +} + +int main() { + typedef CGAL::Forward_circulator_base F; + typedef CGAL::Random_access_circulator_base R; + F f = F(); + R r = R(); + std::list l; + assert( foo( f) == 1); + assert( foo( r) == 2); + assert( foo( l.begin()) == 3); + return 0; +} diff --git a/Packages/Circulator/doc_tex/Circulator/main.tex b/Packages/Circulator/doc_tex/Circulator/main.tex new file mode 100644 index 00000000000..b2386e3d4ef --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/main.tex @@ -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} +

Reference Pages

+\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 diff --git a/Packages/Circulator/doc_tex/Circulator/manual.tex b/Packages/Circulator/doc_tex/Circulator/manual.tex new file mode 100644 index 00000000000..def7105860c --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/manual.tex @@ -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 %% diff --git a/Packages/Circulator/doc_tex/Circulator/wrapper.tex b/Packages/Circulator/doc_tex/Circulator/wrapper.tex new file mode 100644 index 00000000000..4426a088db4 --- /dev/null +++ b/Packages/Circulator/doc_tex/Circulator/wrapper.tex @@ -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 %% diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Assert_circulator.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Assert_circulator.tex new file mode 100644 index 00000000000..ca0c3d9b888 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Assert_circulator.tex @@ -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 void}{X}{} + +\ccGlobalFunction{template + void Assert_circulator( const C &c);} +\ccGlue + +\ccGlobalFunction{template + void Assert_iterator( const I &i);} +\ccGlue + +\ccGlobalFunction{template< class IC> + void Assert_circulator_or_iterator(const IC& i);} + +\ccGlobalFunction{template + void Assert_input_category( const I &i);} +\ccGlue + +\ccGlobalFunction{template + void Assert_output_category( const I &i);} +\ccGlue + +\ccGlobalFunction{template + void Assert_forward_category( const IC &ic);} +\ccGlue + +\ccGlobalFunction{template + void Assert_bidirectional_category( const IC &ic);} +\ccGlue + +\ccGlobalFunction{template + 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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator.tex new file mode 100644 index 00000000000..7a1516668f0 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator.tex @@ -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 +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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_from_container.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_from_container.tex new file mode 100644 index 00000000000..880592dd9ee --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_from_container.tex @@ -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} +\label{pageCircFromContainerRef} + +\ccHtmlCrossLink{Const_circulator_from_container} +\ccHtmlCrossLink{Const_circulator_from_container} +\ccHtmlIndexC[class]{Const_circulator_from_container} + +\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}. + +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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_from_iterator.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_from_iterator.tex new file mode 100644 index 00000000000..f7036af9892 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_from_iterator.tex @@ -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} +\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& 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 c(b,e)} is a random circulator +\ccStyle{c} over this array. + +\end{ccRefClass} + +% +-----------------------------------------------------+ +% EOF diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_tag.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_tag.tex new file mode 100644 index 00000000000..f53896f7d17 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_tag.tex @@ -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} +\ccHtmlIndexC[class]{Circulator_base} + +\ccHtmlCrossLink{Forward_circulator_base} +\ccHtmlCrossLink{Forward_circulator_base} +\ccHtmlIndexC[class]{Forward_circulator_base} +\ccHtmlCrossLink{Bidirectional_circulator_base} +\ccHtmlCrossLink{Bidirectional_circulator_base} +\ccHtmlIndexC[class]{Bidirectional_circulator_base} +\ccHtmlCrossLink{Random_access_circulator_base} +\ccHtmlCrossLink{Random_access_circulator_base} +\ccHtmlIndexC[class]{Random_access_circulator_base} + +\ccHtmlCrossLink{Forward_circulator_ptrbase} +\ccHtmlCrossLink{Forward_circulator_ptrbase} +\ccHtmlIndexC[class]{Forward_circulator_ptrbase} +\ccHtmlCrossLink{Bidirectional_circulator_ptrbase} +\ccHtmlCrossLink{Bidirectional_circulator_ptrbase} +\ccHtmlIndexC[class]{Bidirectional_circulator_ptrbase} +\ccHtmlCrossLink{Random_access_circulator_ptrbase} +\ccHtmlCrossLink{Random_access_circulator_ptrbase} +\ccHtmlIndexC[class]{Random_access_circulator_ptrbase} + +\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 + struct Forward_circulator_base {};}{} +\ccGlue +\ccStruct{template + struct Bidirectional_circulator_base {};}{} +\ccGlue +\ccStruct{template + 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 Forward_circulator_ptrbase {};}{% + forward circulator.} +\ccGlue +\ccStruct{template + class Bidirectional_circulator_ptrbase {};}{% + bidirectional circulator.} +\ccGlue +\ccStruct{template + class Random_access_circulator_ptrbase {};}{% + random access circulator.} + +\end{ccRefClass} +% +-----------------------------------------------------+ +% EOF diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_traits.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_traits.tex new file mode 100644 index 00000000000..2339f178d09 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Circulator_traits.tex @@ -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} + +\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:: \ \ 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 +void bar( I i, I j, CGAL::Iterator_tag) { + CGAL::Assert_iterator(i); + // This function is called for iterator ranges [i,j). +} +template +void bar( C c, C d, CGAL::Circulator_tag) { + CGAL::Assert_circulator(c); + // This function is called for circulator ranges [c,d). +} +template +void bar( IC i, IC j) { // calls the correct function + return bar( i, j, typename CGAL::Circulator_traits::category()); +} +\end{ccExampleCode} + +\end{ccRefClass} +% +-----------------------------------------------------+ + +% EOF diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Container_from_circulator.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Container_from_circulator.tex new file mode 100644 index 00000000000..a8725d53163 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/Container_from_circulator.tex @@ -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} + +\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 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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/For_all.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/For_all.tex new file mode 100644 index 00000000000..f6fbbe17e16 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/For_all.tex @@ -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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/circulator_distance.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/circulator_distance.tex new file mode 100644 index 00000000000..3463f9ed540 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/circulator_distance.tex @@ -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 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 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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/circulator_size.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/circulator_size.tex new file mode 100644 index 00000000000..cb5ed65b51f --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/circulator_size.tex @@ -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 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 C::size_type circulator_size(C c);} + +\ccSeeAlso + +\ccc{circulator_distance}, +\ccc{iterator_distance}, +\ccc{is_empty_range}, +\ccc{Circulator}. + +\end{ccRefFunction} + +% +-----------------------------------------------------+ +% EOF diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/intro.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/intro.tex new file mode 100644 index 00000000000..b55cefd762a --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/intro.tex @@ -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}\\ +\ccRefIdfierPage{CGAL::Circulator_from_iterator}\\ +\ccRefIdfierPage{CGAL::Circulator_from_container}\\ +\ccc{CGAL::Const_circulator_from_container} + +\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} + +\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 %% diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/is_empty_range.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/is_empty_range.tex new file mode 100644 index 00000000000..7dde298e944 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/is_empty_range.tex @@ -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 +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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/iterator_distance.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/iterator_distance.tex new file mode 100644 index 00000000000..f7bef237e7b --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/iterator_distance.tex @@ -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::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 iterator_traits::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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/query_circulator_or_iterator.tex b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/query_circulator_or_iterator.tex new file mode 100644 index 00000000000..4a4e0809023 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/Circulator_ref/query_circulator_or_iterator.tex @@ -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 + Iterator_tag query_circulator_or_iterator( const I& i);}{ + if the iterator category of \ccc{I} belongs to an iterator.} + +\ccFunction{template + 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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/cgal.bib b/Packages/Circulator/doc_tex/support/Circulator/cgal.bib new file mode 100644 index 00000000000..138a5dac8ac --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/cgal.bib @@ -0,0 +1,1082 @@ +% ------------------------------------------------------------------------ +% cgal.bib +% -------- +% BiBTeX references used in the CGAL project which are not in geombib. +% geombib is available from: +% +% file://ftp.cs.usask.ca/pub/geometry/geombib.tar.Z +% +% 29.04.1997 Lutz Kettner kettner_inf.ethz.ch +% +% annote entry might contain "recommended C++ reading" or +% "recommended OO reading". +% +% ------------------------------------------------------------------------ + + +% Common abbreviations for publishers, journals, ... +% -------------------------------------------------- + +@string{ addison = {Addison-Wesley}} +@string{ mcgraw = {McGraw-Hill}} +@string{ academic = {Academic Press}} +@string{ springer = {Springer Verlag}} +@string{ oldenbourg = {Oldenbourg Verlag, M\"unchen, Wien}} +@string{ gruyter = {Walter de Gruyter, Berlin}} +@string{ elsevier = {Elsevier Science Publishers, Amsterdam, The + Netherlands}} +@string{ acm = {ACM Press}} +@string{ wiley = {John Wiley \& Sons, New York}} +@string{ cambridge = {Cambridge University Press}} +@string{ kaufmann = {Morgan Kaufmann}} +@string{ kluwer = {Kluwer Academic Publishers Group}} + +% Alphabetically sorted list of references. +% ----------------------------------------- + +@incollection{ a-cgs-97 + ,author = "N. Amenta" + ,title = "Computational Geometry Software" + ,booktitle = "Handbook of Discrete and Computational Geometry" + ,editors = "J. Goodman and J. O'Rourke" + ,publisher = "CRC Press" + ,year = "1997" + ,pages = "951--960" + ,update = "98.01 schirra" +} + +@inproceedings{ a-nqimr-67 + ,author = {Arthur Appel} + ,title = {The Notion of Quantitive Invisibility and the + Machine Rendering of Solids} + ,booktitle = {Proc. ACM National Conf.} + ,year = 1967 + ,pages = {387--393} + ,annote = {Basis for the contour edge idea in hidden surface + removal.} + ,update = "97.04 kettner" +} + +@book{ bn-sec++-94 + ,author = "J. J. Barton and L. R. Nackman" + ,title = "Scientific and Engineering {C{\tt ++}}" + ,publisher = "Addison-Wesley, Reading, MA" + ,year = "1997" + ,update = "98.01 schirra" +} + +@inproceedings{ bfh-mgedm-95 + ,author = {Heinzgerd Bendels and Dieter W. Fellner and Sven + Havemann} + ,title = {Modellierung der Grundlagen: Erweiterbare + Datenstrukturen zur Modellierung und Visualisierung + polygonaler Welten} + ,booktitle = {Modeling -- Virtual Worlds -- Distributed Graphics} + ,year = 1995 + ,editor = {D. W. Fellner} + ,pages = {149--157} + ,address = {Bad Honnef / Bonn} + ,month = {27.--28. November} + ,annote = {A reference for the halfedge data structure and + Euler operators (preserving the topological type).} + ,update = "97.04 kettner" +} + +@misc{ bpp-vrml-95 + ,author = {Gavin Bell and Anthony Parisi and Mark Pesce} + ,title = {VRML The Virtual Reality Modeling Language: + Version 1.0 Specification} + ,howpublished = {\path|http://www.vrml.org/|} + ,month = {May 26} + ,year = 1995 + ,note = {Third Draft} + ,update = "97.04 kettner" +} + +@incollection{ bv-sbc-96 + ,author = "G. Booch and M. Vilot" + ,title = "Simplifying the Booch Components" + ,booktitle = "{\CC\ }Gems" + ,publisher = "SIGS publications" + ,editor = "Lippman, S." + ,year = "1996" + ,pages = "59--89" + ,update = "98.01 schirra" +} + +@incollection{ cgal-nt-97 + ,author = {{CGAL} consortium} + ,title = {Number Types} + ,booktitle = {{CGAL} Reference Manual. {P}art 3: {S}upport Library} + ,editor = {Andreas Fabri and Stefan Schirra and + Remco Veltkamp} + ,year = 1997 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "98.01 giezeman" +} + +@misc{ + ,author = {{CGAL} consortium} + ,title = {{CGAL} Workpackage 4, Report 2} + ,howpublished = {\path|http://www.cs.ruu.nl/CGAL|} + ,month = {fall} + ,year = 1997 + ,update = "98.01 kettner" +} + +@misc{ + ,author = {{CGAL} consortium} + ,title = {{CGAL} Workpackage 4, Report 1} + ,howpublished = {\path|http://www.cs.ruu.nl/CGAL|} + ,month = apr + ,year = 1997 + ,update = "98.01 kettner" +} + +@inproceedings{ cvmtwabw-se-96 + ,author = {Jonathan Cohen and Amitabh Varshney and Dinesh + Manocha and Greg Turk and Hans Weber and Pankaj + Agarwal and Frederick Brooks and William Wright} + ,title = {Simplification Envelopes} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '96)" + ,volume = 30 + ,year = 1996 + ,pages = {119--128} + ,note = {Examples and code in + \path|http://www.cs.unc.edu/~geom/envelope.html|} + ,update = "97.08 kettner" +} + +@inproceedings{ cl-vmbcm-96 + ,author = {Brian Curless and Marc Levoy} + ,title = {A Volumetric Method for Building Complex + Models from Range Images} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '96)" + ,volume = 30 + ,year = 1996 + ,pages = {303--312} + ,update = "97.08 kettner" +} + +@misc{ c-wpdpi-95 + ,key = {C++AnsiDraft} + ,title = "Working Paper for Draft Proposed International + Standard for Information Systems -- Programming + Language {C{\tt ++}}" + ,howpublished = {ANSI X3, Information Processing Systems} + ,month = apr + ,year = 1995 + ,note = {\path|http://www.cygnus.com/misc/wp/|} + ,update = "97.04 kettner" +} + +@misc{ c-wpdpi-96 + ,key = {{C}{\tt ++}} + ,title = "Working Paper for Draft Proposed International + Standard for Information Systems -- Programming + Language {C{\tt ++}}" + ,howpublished = {Doc.~No.~X3J16/96 - 0225 - WG21/N1043} + ,month = Dec + ,year = 1996 + ,note = {\path|http://www.maths.warwick.ac.uk/c++/pub/|} + ,update = "97.04 kettner, 98.02 schirra" +} + +@misc{ c-isplc-98 + ,key = {{C}{\tt ++}} + ,title = "International Standard ISO/IEC 14882: + Programming languages -- {C{\tt ++}}" + ,howpublished = {American National Standards Institute, 11 West 42nd + Street, New York 10036} + ,year = 1998 + ,mynote = {\path|http://webstore.ansi.org/|} + ,update = "99.02 kettner" +} + +@misc{ c-isplc-98 + ,key = {{C}{\tt ++}} + ,title = "International Standard ISO/IEC 14882: + Programming languages -- {C{\tt ++}}" + ,howpublished = {American National Standards Institute, 11 West 42nd + Street, New York 10036} + ,year = 1998 + ,mynote = {\path|http://webstore.ansi.org/|} + ,update = "98.11 kettner" +} + +@misc{ OLD-c-wpdpi-96 + ,key = {C++AnsiDraft} + ,title = "Working Paper for Draft Proposed International + Standard for Information Systems -- Programming + Language {C{\tt ++}}" + ,howpublished = {ANSI X3, Information Processing Systems} + ,month = dec + ,year = 1996 + ,note = {\path|http://www.maths.warwick.ac.uk/c++/pub/|} + ,update = "97.04 kettner" +} + +@inproceedings{ eddhls-maam-95 + ,author = {Matthias Eck and Tony DeRose and Tom Duchamp and + Hugues Hoppe and Michael Lounsbery and Werner Stuetzle} + ,title = {Multiresolution Analysis of Arbitrary Meshes} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '95)" + ,volume = 29 + ,year = 1995 + ,pages = {173--182} + ,note = {Examples in + \path|file://ftp.cs.washington.edu/pub/graphics|} + ,update = "97.08 kettner" +} + +@inproceedings{ fgkss-ckbgc-96 + ,author = {Andreas Fabri and Geert-Jan Giezeman and Lutz + Kettner and Stefan Schirra and Sven Sch{\"o}nherr} + ,title = {The {CGAL} Kernel: A Basis for Geometric Computation} + ,booktitle = {ACM Workshop on Applied Computational Geometry} + ,editor = {M. C. Lin and D. Manocha} + ,address = {Philadelphia, Pennsylvenia} + ,month = {May, 27--28} + ,year = 1996 + ,pages = {191--202} + ,note = {Springer Lecture Notes in Computer Science 1148} + ,update = "97.04 kettner" +} + +@book{ f-sec-85 + ,author = {Richard Fairley} + ,title = {Software Engineering Concepts} + ,publisher = {McGraw-Hill} + ,year = 1985 + ,series = {McGraw-Hill Series in Software Engineering and Technology} + ,annote = {recommended software engineering reading. + Topics from pre-object-oriented software engineering.} + ,update = "98.01 kettner" +} + +@book{ ghjv-dpero-95 + ,author = {E. Gamma and R. Helm and R. Johnson and J. Vlissides} + ,title = {Design Patterns -- Elements of Reusable + Object-Oriented Software} + ,publisher = addison + ,year = 1995 + ,annote = {recommended OO reading.} + ,update = "97.04 kettner" +} + +@article{ g-ieva-85 + ,author = {Ronald N. Goldman} + ,title = {Illicit Expressions in Vector Algebra} + ,journal = {ACM Transaction on Graphics} + ,year = 1985 + ,volume = 4 + ,number = 3 + ,month = jul + ,pages = {223--243} + ,update = "98.01 kettner" +} + +@book{ hw-vrml2h-96 + ,author = {Jed Hartman and Josie Wernecke} + ,title = {The {VRML} 2.0 Handbook: Building Moving Worlds on the + Web} + ,publisher = addison + ,year = 1996 + ,annote = {The VRML 2.0 Introduction and Reference by + Silicon Graphics.} + ,update = "98.02 kettner" +} + +@misc{ h-97 + ,author = {Michael Hoffmann} + ,year = 1997 + ,note = {personal communication} + ,update = "98.01 kettner" +} + +@inproceedings{ hddms-srup-92 + ,author = {Hugues Hoppe and Tony DeRose and Tom Duchamp and + John McDonald and Werner Stuetzle} + ,title = {Surface Reconstruction from Unorganized Points} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '90)" + ,volume = 26 + ,year = 1992 + ,pages = {71--77} + ,update = "97.08 kettner" +} + +@inproceedings{ hddms-mo-93 + ,author = {Hugues Hoppe and Tony DeRose and Tom Duchamp and + John McDonald and Werner Stuetzle} + ,title = {Mesh Optimization} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '93)" + ,volume = 27 + ,year = 1993 + ,pages = {19--26} + ,note = {Examples and code in + \path|file://ftp.cs.washington.edu/pub/graphics|} + ,update = "97.08 kettner" +} + +@phdthesis{ h-srup-94 + ,author = {Hugues Hoppe} + ,title = {Surface reconstruction from unorganized points} + ,school = {University of Washington} + ,year = 1994 + ,update = "97.08 kettner" +} + +@inproceedings{ hddhjmss-pssr-94 + ,author = {Hugues Hoppe and Tony DeRose and Tom Duchamp and + Mark Halstaed and Hubert Jin and John McDonald and + Jean Schweitzer and Werner Stuetzle} + ,title = {Piecewise Smooth Surface Reconstruction} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '94)" + ,volume = 28 + ,year = 1994 + ,pages = {295--302} + ,note = {Examples and code in + \path|file://ftp.cs.washington.edu/pub/graphics|} + ,update = "97.08 kettner" +} + +@inproceedings{ h-pm-96 + ,author = {Hugues Hoppe} + ,title = {Progressive Meshes} + ,booktitle = "Computer Graphics (Proc. SIGGRAPH '96)" + ,volume = 30 + ,year = 1996 + ,pages = {99--108} + ,update = "97.08 kettner" +} + +@incollection{ k-dat-96 + ,author = "Keffer, T." + ,title = "The Design and Architecture of {T}ools.h{\tt ++}" + ,booktitle = "{C{\tt ++}}~Gems" + ,publisher = "SIGS publications" + ,editor = "Lippman, S." + ,year = "1996" + ,pages = "43--57" + ,update = "98.01 schirra" +} + +@incollection{ kw-ceapp-97 + ,author = {Lutz Kettner and Emo Welzl} + ,title = {Contour Edge Analysis for Polyhedron Projections} + ,booktitle = {Geometric Modeling: Theory and Practice} + ,year = 1997 + ,pages = {379--394} + ,publisher = {Springer Verlag} + ,editor = {Wolfgang Strasser and Reinhard Klein and Rene Rau} + ,update = "97.04 kettner, 97.08 kettner" +} + +@incollection{ kw-osepg-98 + ,author = {Lutz Kettner and Emo Welzl} + ,title = {One Sided Error Predicates in Geometric Computing} + ,booktitle = {Proc. 15th IFIP World Computer Congress, + Fundamentals - Foundations of Computer Science} + ,year = 1998 + ,pages = {13--26} + ,editor = {Kurt Mehlhorn} + ,update = "98.08 kettner" +} + +@inproceedings{ k-ddsps-98 + ,author = {Lutz Kettner} + ,title = {Designing a Data Structure for Polyhedral Surfaces} + ,booktitle = {Proc. 14th Annu. ACM Sympos. Comput. Geom.} + ,year = 1998 + ,pages = {146--154} + ,abstract = { + Design solutions for a program library are presented for combinatorial + data structures in computational geometry, such as planar maps and + polyhedral surfaces. Design issues considered are genericity, + flexibility, time and space efficiency, and ease-of-use. We focus on + topological aspects of polyhedral surfaces. Edge-based representations + for polyhedrons are evaluated with respect to the design goals. A + design for polyhedral surfaces in a halfedge data structure is + developed following the generic programming paradigm known from the + Standard Template Library STL for C++. Connections are shown to planar + maps and face-based structures managing holes in facets} +} + +@techreport{ k-ddsps-97 + ,author = {Lutz Kettner} + ,title = {Designing a Data Structure for Polyhedral Surfaces} + ,institution = {Department Informatik, ETH Z{\"u}rich} + ,year = 1997 + ,type = {Technical Report} + ,number = {\#278} + ,address = {Switzerland} + ,pages = {27} + ,month = dec + ,abstract = { + Design solutions for a program library are presented for combinatorial + data structures in computational geometry, such as planar maps and + polyhedral surfaces. Design issues considered are genericity, + flexibility, time and space efficiency, and ease-of-use. We focus on + topological aspects of polyhedral surfaces. Edge-based representations + for polyhedrons are evaluated with respect to the design goals. A + design for polyhedral surfaces in a halfedge data structure is + developed following the generic programming paradigm known from the + Standard Template Library STL for C++. Connections are shown to planar + maps and face-based structures managing holes in facets} + ,update = "98.01 kettner" +} + +@incollection{ k-ps-97 + ,author = {Lutz Kettner} + ,title = {{3D}-Polyhedral Surfaces} + ,booktitle = {{CGAL} Reference Manual. Part 2: Basic Library} + ,editor = {Andreas Fabri and Stefan Schirra and Remco Veltkamp} + ,year = 1997 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner" +} + +@incollection{ k-c-97 + ,author = {Lutz Kettner} + ,title = {Circulators} + ,booktitle = {{CGAL} Reference Manual. Part 3: Support Library} + ,editor = {Andreas Fabri and Stefan Schirra and Remco Veltkamp} + ,year = 1997 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner" +} + +@article{ k-ugpdd-99 + ,author = {Lutz Kettner} + ,title = {Using Generic Programming for + Designing a Data Structure for Polyhedral Surfaces} + ,journal = {Computational Geometry: Theory and Applications} + ,year = 1999 + ,note = {to appear} + ,abstract = { + Design solutions for a program library are presented for combinatorial + data structures in computational geometry, such as planar maps and + polyhedral surfaces. Design issues considered are genericity, + flexibility, time and space efficiency, and ease-of-use. We focus on + topological aspects of polyhedral surfaces. Edge-based representations + for polyhedrons are evaluated with respect to the design goals. A + design for polyhedral surfaces in a halfedge data structure is + developed following the generic programming paradigm known from the + Standard Template Library STL for C++. Connections are shown to planar + maps and face-based structures managing holes in facets} + ,update = "99.03 kettner" +} + +@manual{ kl-cssd-94 + ,title = {The {CWEB} System of Structured Documentation} + ,author = {Donald E. Knuth and Silvio Levy} + ,edition = {Version 3.0} + ,year = 1994 + ,update = "98.01 kettner" +} + +@article{ k-lp-84 + ,author = {Donald E. Knuth} + ,title = {Literate Programming} + ,journal = {The Computer Journal} + ,year = 1984 + ,volume = 27 + ,number = 2 + ,pages = {97--111} + ,update = "98.01 kettner" +} + +@article{ kl-isc++l-96 + ,author = "K. Kreft and A. Langer" + ,title = "Iterators in the Standard {\CC\ }Library" + ,journal = "{C{\tt ++}}~Report" + ,volume = "8" + ,number = "10" + ,month = "Nov.-Dec." + ,year = "1996" + ,pages = "27--32" + ,update = "98.01 schirra" +} + +@techreport{ kw-dat-96 + ,author = {Dietmar K{\"u}hl and Karsten Weihe} + ,title = {Data Access Templates} + ,institution = {Universit\"at Konstanz, Germany} + ,year = 1996 + ,type = {Konstanzer Schriften in Mathematik und Informatik} + ,number = {Nr. 9} + ,month = may + ,note = {\path|http://www.informatik.uni-konstanz.de/Schriften|} + ,annote = {recommended C++ reading.} + ,update = "97.04 kettner" +} + +@book{ l-lscsd-96 + ,author = {John Lakos} + ,title = {Large Scale {C{\tt ++}} Software Design} + ,publisher = addison + ,year = 1996 + ,annote = {recommended OO reading.} + ,update = "97.04 kettner" +} + +@inproceedings{ l-vgasa-96 + ,author = "D. T. Lee" + ,title = "Visualizing Geometric Algorithms -- State of the Art" + ,editor = "M. C. Lin and D. Manocha" + ,booktitle = "Applied Computational Geometry (Proc. WACG~'96)" + ,series = "Lecture Notes Comput. Sci." + ,volume = 1148 + ,publisher = "Springer-Verlag" + ,year = 1996 + ,pages = "45--50" + ,update = "98.01 schirra" +} + +@book{ l-icom-96 + ,author = {Stanley B. Lippman} + ,title = {Inside the {C{\tt ++}} Object Model} + ,publisher = addison + ,year = 1996 + ,annote = {Insides into C++ compiler implementations. + Performance issues of various C++ features. } + ,update = "97.04 kettner" +} + +@book{ m-wsc-93 + ,author = {Steve Maguire} + ,title = {Writing Solid Code} + ,publisher = {Microsoft Press} + ,year = 1993 + ,annote = {Microsoft's techniques for developing bug-free C programs} + ,update = "98.01 schirra" +} + +@inproceedings{ m-pppd-96 + ,author = "Kurt Mehlhorn" + ,title = "Position Paper for Panel Discussion" + ,editor = "M. C. Lin and D. Manocha" + ,booktitle = "Applied Computational Geometry (Proc. WACG~'96)" + ,series = "Lecture Notes Comput. Sci." + ,volume = 1148 + ,publisher = "Springer-Verlag" + ,year = 1996 + ,pages = "51--52" + ,update = "98.01 schirra" +} + +@manual{ mnu-lum-97 + ,author = {Mehlhorn, K. and N\"aher, S. and Uhrig, C.} + ,title = {The {LEDA} {U}ser {M}anual, {V}ersion 3.5} + ,organization = {Max-Planck-Insitut f\"ur Informatik} + ,address = {66123 Saarbr\"ucken, Germany} + ,year = {1997} + ,note = {\path|http://www.mpi-sb.mpg.de/LEDA/leda.html|} + ,update = "97.12 kettner, 98.02 schirra" +} + +@manual{ OLD-mnu-lum-97 + ,title = {The {LEDA} {U}ser {M}anual, {V}ersion 3.5} + ,author = {Kurt Mehlhorn and Stefan N{\"a}her and Christian Uhrig} + ,organization = {LEDA Software GmbH} + ,address = {66123 Saarbr\"ucken, Germany} + ,year = 1997 + ,update = "97.12 kettner" +} + +@book{ m-ec-92 + ,author = {Scott Meyers} + ,title = "Effective {C{\tt ++}}" + ,publisher = addison + ,year = 1992 + ,annote = {recommended C++ reading. 50 Specific Ways to + Improve Your Programs and Designs} + ,update = "97.04 schönherr" +} + +@book{ m-mec-96 + ,author = {Scott Meyers} + ,title = "More Effective {C{\tt ++}}" + ,publisher = addison + ,year = 1996 + ,annote = {recommended C++ reading. 35 New Ways to + Improve Your Programs and Designs} + ,update = "97.04 schönherr" +} + +@book{ m-cst-93 + ,author = {Robert B. Murray} + ,title = "{C{\tt ++}} Strategies and Tactics" + ,publisher = addison + ,year = 1993 + ,annote = {recommended C++ reading} + ,update = "98.01 schirra" +} + +@article{ m-tnutt-95 + ,author = {Nathan C. Myers} + ,title = {Traits: a New and Useful Template Technique} + ,journal = "{C{\tt ++}}~Report" + ,year = 1995 + ,month = jun + ,annote = {recommended C++ reading. stream traits, iterator + traits, typedef's.} + ,update = "97.04 kettner" +} + +@inproceedings{ ms-gp-89 + ,author = {David R.~Musser and Alexander A.~Stepanov} + ,title = {Generic Programming} + ,booktitle = {1st Intl.\ Joint Conf.\ of ISSAC-88 and AAEC-6} + ,year = 1989 + ,pages = {13--25} + ,publisher = {Springer LNCS 358} +} + +@article{ ms-aogl-94 + ,author = {David R.~Musser and Alexander A.~Stepanov} + ,title = {Algorithm-oriented Generic Libraries} + ,journal = {Software -- Practice and Experience} + ,year = 1994 + ,volume = 24 + ,number = 7 + ,pages = {623--642} + ,month = jul +} + +@book{ ms-strg-96 + ,author = {David R. Musser and Atul Saini} + ,title = "{STL} Tutorial and Reference Guide: + {C{\tt ++}}~Programming with the Standard Template + Library" + ,publisher = addison + ,year = 1996 + ,annote = {recommended C++ reading.} + ,update = "97.04 kettner" +} + +@manual{ nu-leda32-95 + ,title = {The {L}{E}{D}{A} {U}ser {M}anual, {V}ersion {R} 3.2} + ,author = {S.~N{\"a}her and C.~Uhrig} + ,organization = {Max-Planck-Institut f\"ur Informatik} + ,address = {Saarbr\"ucken, Germany} + ,year = 1995 + ,update = "97.04 kettner" +} + +@book{ ndw-opgog-93 + ,author = {Jackie Neider and Tom Davis and Mason Woo} + ,title = {OpenGL Programming Guide: The Official Guide to + Learning OpenGL, Release 1} + ,publisher = addison + ,year = 1993 + ,update = "97.04 kettner" +} + +@inproceedings{ o-dcgal-96 + ,author = {Mark H. Overmars} + ,title = {Designing the Computational Geometry Algorithms + Library {CGAL}} + ,booktitle = {ACM Workshop on Applied Computational Geometry} + ,editor = {M. C. Lin and D. Manocha} + ,address = {Philadelphia, Pennsylvenia} + ,month = {May, 27--28} + ,year = 1996 + ,note = {Lecture Notes in Computer Science 1148} + ,update = "97.04 kettner" +} + +@article{ pc-rdp-86 + ,author = {David L. Parnas and Paul C. Clements} + ,title = {A Rational Design Process: How and Why to Fake It} + ,journal = {IEEE Transactions on Software Engineering} + ,year = 1986 + ,volume = 12 + ,number = 2 + ,pages = {251-257} + ,update = "98.01 kettner" +} + +@manual{ p-gmgv15-94 + ,title = {Geomview Manual: Geomview Version 1.5 for Silicon + Graphics Workstations} + ,author = {Mark Phillips} + ,organization = {The Geometry Center} + ,address = {University of Minnesota} + ,month = oct + ,year = 1994 + ,note = {\path|http://www.geom.umn.edu/software/download/geomview.html|} + ,annote = {Reference for object file format (OFF).} + ,update = "97.04 kettner" +} + +@book{ rbpel-oomd-91 + ,author = {James Rumbaugh and Michael Blaha and William + Premerlani and Frederick Eddy and William Lorenson} + ,title = {Object-Oriented Modeling and Design} + ,publisher = {Prentice Hall} + ,address = {Englewood Cliffs, NJ} + ,year = 1991 + ,annote = {Object and class diagram notation as used in the + book of design patterns ghjv-dpero-95.} + ,update = "97.04 kettner" +} + +@article{ r-lomom-94 + ,author = {James Rumbaugh} + ,title = {The Life of an Object Model: How the Object-Model + Changes During Development} + ,journal = {Journal of Object-Oriented Programming} + ,year = 1994 + ,volume = 7 + ,number = 1 + ,pages = {24--32} + ,month = {March/April} + ,annote = {Object and class diagram notation as used in the + book of design patterns ghjv-dpero-95.} + ,update = "97.04 kettner" +} + +@misc{ s-dcgal-96 + ,author = "S. Schirra" + ,title = "Designing a Computational Geometry Algorithms Library" + ,howpublished = "Lecture Notes for Advanced School on Algorithmic + Foundations of Geographic Information Systems, CISM, + Udine" + ,month = "September 16-20" + ,year = "1996" + ,update = "98.01 schirra" +} + +@techreport{ s-picpc-98 + ,author = {Schirra, Stefan} + ,title = {Parameterized Implementations of Classical Planar + Convex Hull Algorithms and Extreme Point Computations} + ,type = {Research Report} + ,institution = {Max-Planck-Institut f{\"u}r Informatik} + ,address = {Im Stadtwald, D-66123 Saarbr{\"u}cken, Germany} + ,number = {MPI-I-98-1-003} + ,month = {January} + ,year = {1998} + ,issn = {0946-011X} + ,update = "98.01 schirra" +} + +@incollection{s-ixgpe-91a + ,author = "Peter Schorn" + ,title = "Implementing the {XYZ} {GeoBench}: A programming + environment for geometric algorithms" + ,booktitle = "Computational Geometry --- Methods, Algorithms and + Applications: Proc. Internat. Workshop Comput. + Geom. CG '91" + ,series = "Lecture Notes Comput. Sci." + ,volume = 553 + ,publisher = "Springer-Verlag" + ,year = 1991 + ,pages = "187--202" + ,note = {\path|http://wwwjn.inf.ethz.ch/geobench/XYZGeoBench.html|} + ,update = "94.01 rote, 98.01 kettner" +} + +%%\bibitem{schutte} Michael Schutte, Zufaellige Konvexe Mengen, +%% Diplomarbeit Freie Universitaet Berlin, 1996. + +@mastersthesis{ s-zkm-96 + ,author = {Michael Schutte} + ,title = {Zuf{\"a}llige Konvexe Mengen} + ,school = {Freie Universit{\"a}t Berlin} + ,year = 1996 + ,address = {Germany} +} + +@misc{ sgcsi-stlpg-97 + ,author = {{Silicon Graphics Computer Systems{,} Inc.}} + ,title = {Standard Template Library Programmer's Guide} + ,howpublished = {\path|http://www.sgi.com/Technology/STL/|} + ,year = 1997 + ,annote = {Web reference to the STL from SGI. + recommended C++ and STL reference material.} + ,update = "97.12 kettner" +} + +@article{ ss-ablp-91 + ,author = {Lisa M. C. Smith and Mansur H. Samadzadeh} + ,title = {An Annotated Bibliography of Literate Programming} + ,journal = {ACM SIGPLAN Notices} + ,year = 1991 + ,volume = 26 + ,number = 1 + ,pages = {14--20} + ,month = jan + ,update = "98.01 kettner" +} + +@book{ s-cpl-91 + ,author = {Bjarne Stroustrup} + ,title = "The {C{\tt ++}}~Programming Language" + ,publisher = addison + ,year = 1991 + ,edition = {2nd} + ,annote = {recommended C++ reading.} + ,update = "97.04 kettner" +} + +@book{ s-cpl-97 + ,author = {Bjarne Stroustrup} + ,title = "The {C{\tt ++}}~Programming Language" + ,publisher = addison + ,year = 1997 + ,edition = {3rd} + ,annote = {recommended C++ reading.} + ,update = "97.12 kettner" +} + +@misc{ sl-stl-95 + ,author = {Alexander Stepanov and Meng Lee} + ,title = {The Standard Template Library} + ,howpublished = {\path|http://www.cs.rpi.edu/~musser/doc.ps|} + ,month = oct + ,year = 1995 + ,annote = {recommended C++ reading. Short introduction to the + STL. Precise requirements for the iterators and + containers. Explanation of iterator tags (outdated).} + ,update = "97.04 kettner" +} + +@article{ v-tm-95 + ,author = {Todd Veldhuizen} + ,title = {Template Metaprograms} + ,journal = "{C{\tt ++}}~Report" + ,year = 1995 + ,month = may + ,pages = {36--43} + ,annote = {Prime numbers at compiler time, C++ programs at + compile time, control structures, local variables.} + ,update = "98.01 kettner" +} + +@article{ v-et-95 + ,author = {Todd Veldhuizen} + ,title = {Expressions Templates} + ,journal = "{C{\tt ++}}~Report" + ,year = 1995 + ,month = jun + ,pages = {26--31} + ,annote = {Inlining vector expressions and parameter passing + of expressions at compile time. Template Metaprograms.} + ,update = "98.01 kettner" +} + +@article{ v-lactm-96 + ,author = {Todd Veldhuizen and Kumaraswamy Ponnambalam} + ,title = {Linear Algebra with {C{\tt ++}} Template Metaprograms} + ,journal = {Dr. Dobb's Journal} + ,year = 1996 + ,month = aug + ,annote = {Vector operations without temporary variables.} + ,update = "98.01 kettner" +} + +@inproceedings{ v-gpc-97 + ,author = "R. C. Veltkamp" + ,title = "Generic Programming in {CGAL}, the Computational + Geometry Algorithms Library" + ,booktitle = "Proceedings of the 6th Eurographics Workshop on + Programming Paradigms in Graphics" + ,year = "1997" + ,update = "98.01 schirra" +} + +@misc{ vrmls-96 + ,key = {VRML2} + ,title = {The Virtual Reality Modeling Language Specification: + Version 2.0, {ISO}/{IEC} {CD} 14772} + ,howpublished = {\path|http://www.vrml.org/|} + ,month = {August 4} + ,year = 1996 + ,update = "98.01 kettner" +} + +@incollection{ w-fvt-90 + ,author = {Bob Wallis} + ,title = {Forms, Vectors, and Transforms} + ,booktitle = {Graphics Gems} + ,publisher = academic + ,year = 1990 + ,editor = {Andrew S. Glassner} + ,pages = {533-538} + ,annote = {Normal vectors under affine transformations, + tensor algebra and differential geometry, triangular + interpolants, subdeviding a parametric polynomial + curve} + ,update = "98.01 kettner" +} + +@article{ w-ebdss-85 + ,author = {Kevin Weiler} + ,title = {Edge-Based Data Structures for Solid Modeling in + Curved-Surface Environments} + ,journal = {IEEE Computer Graphics and Application} + ,year = 1985 + ,volume = 5 + ,number = 1 + ,pages = {21--40} + ,month = jan + ,annote = {Good halfedge reference. reference from Foley90} + ,update = "98.01 kettner" +} + +@book{ w-impoo-94 + ,author = {Josie Wernicke} + ,title = {The Inventor Mentor: Programming Object-Oriented + 3D Graphics with Open Inventor, Release 2} + ,publisher = addison + ,year = 1994 + ,update = "97.04 kettner" +} + +@manual{ w-fum-92 + ,title = {{FunnelWeb} User's Manual} + ,author = {Ross N. Williams} + ,edition = {{V1.0} for {FunnelWeb} {V3.0}} + ,year = 1992 + ,month = may + ,update = "98.01 kettner" +} + +%% Updates by Stefan for CGAL paper, which do not follow geombib conventions. + +@inproceedings{ Me-Naeher:IFIP94 + ,author = {K. Mehlhorn and S. N\"aher} + ,title = {The Implementation of Geometric Algorithms} + ,booktitle = {13th World Computer Congress IFIP94} + ,publisher = {Elsevier Science B.V. North-Holland, Amsterdam} + ,volume = {1} + ,pages = {223--231} + ,year = {1994} + ,update = "98.01 schirra" +} + +@incollection{ s-purigc-handbook + ,key = {Sch} + ,author = "S. Schirra" + ,title = "Precision and Robustness Issues in Geometric Computation" + ,booktitle = "Handbook on Computational Geometry" + ,editors = "J. R. Sack and J. Urrutia" + ,publisher = elsevier + ,year = "1998" + ,update = "98.01 schirra" +} + +@manual{ Protocgal + ,author = {Avnaim, F.} + ,title = "{C}{\tt ++}{GAL}: {A} {C}{\tt ++} Library for Geometric + Algorithms" + ,organization = {INRIA Sophia-Antipolis} + ,year = 1994 + ,update = "98.01 schirra" +} + +@manual{ PlaGeo + ,author = {Giezeman, G.-J.} + ,title = {{PlaGeo}, a library for planar geometry, and {SpaGeo}, + a library for spatial geometry} + ,organization = {Utrecht University} + ,year = 1994 + ,update = "98.01 schirra" +} + +@article{ LEDA_ACM + ,author = {Mehlhorn, K. and N\"aher, S.} + ,title = {{LEDA}, a Platform for Combinatorial and + Geometric Computing} + ,journal = {Communications of the ACM} + ,volume = {38} + ,pages = {96-102} + ,year = {1995} + ,update = "98.01 schirra" +} + +%% manuscript{ geomlib ?? + +@misc{ geomlib + ,author = {Baker, J. E. and Tamassia, R. and Vismara, L.} + ,title = {{GeomLib}: {A}lgorithm Engineering for a Geometric + Computing Library} + ,note = {(Preliminary report)} + ,institution = {Center for Geometric Computing} + ,year = {1997} + ,update = "98.01 schirra" +} + +@manual{ gmp + ,title = {{GNU MP}, The {GNU} Multiple Precision Arithmetic Library} + ,author = {Granlund, T.} + ,edition = {2.0.2} + ,month = {June} + ,year = {1996} + ,update = "98.01 schirra" +} + +@techreport{ reals_TR + ,author = {Burnikel, C. and Mehlhorn, K. and Schirra, S.} + ,title = {The {LEDA} Class {\tt real} Number} + ,institution = {Max-Planck-Institut f\"ur Informatik} + ,number = {MPI-I-96-1-001} + ,year = 1996 + ,update = "98.01 schirra" +} + +@techreport{bp_lsi_TR + ,author = "Boissonnat, J.-D. and Preparata, F." + ,title = "Robust plane sweep for intersecting segments" + ,institution = {INRIA} + ,address = {Sophia-Antipolis, France} + ,number = {3270} + ,year = {September 1997} + ,update = "98.01 schirra" +} + +@incollection{ cgal-nt-98 + ,author = {{CGAL} consortium} + ,title = {Number Types} + ,booktitle = {{CGAL} Reference Manual. {P}art 3: {S}upport Library} + ,editor = {Herv\'e Br\"onnimann and Andreas Fabri and + Stefan Schirra and Remco Veltkamp} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "98.01 giezeman, 98.01 schönherr, 98.02 schirra" +} + +@manual{ gvw-gsc-98 + ,author = {Geert-Jan Giezeman and Remco Veltkamp and + Wieger Wesselink} + ,title = {Getting Started with {CGAL}} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "98.01 schönherr" +} + +@incollection{ k-ps-98 + ,author = {Lutz Kettner} + ,title = {{3D}-Polyhedral Surfaces} + ,booktitle = {{CGAL} Reference Manual. Part 2: Basic Library} + ,editor = {Herv\'e Br\"onnimann and Andreas Fabri and + Stefan Schirra and Remco Veltkamp} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner, 98.01 schönherr, 98.02 schirra" +} + +@incollection{ k-c-98 + ,author = {Lutz Kettner} + ,title = {Circulators} + ,booktitle = {{CGAL} Reference Manual. Part 3: Support Library} + ,editor = {Herv\'e Br\"onnimann and Andreas Fabri and + Stefan Schirra and Remco Veltkamp} + ,year = 1998 + ,note = {{CGAL} {R}1.0. \path|http://www.cs.ruu.nl/CGAL|.} + ,update = "97.12 kettner, 98.01 schönherr, 98.02 schirra" +} + +%% EOF %% diff --git a/Packages/Circulator/doc_tex/support/Circulator/circulator.tex b/Packages/Circulator/doc_tex/support/Circulator/circulator.tex new file mode 100644 index 00000000000..e5252a75b77 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/circulator.tex @@ -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 +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 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 v; +typedef CGAL::Circulator_from_iterator< + std::vector::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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog1.C b/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog1.C new file mode 100644 index 00000000000..c8a458c828e --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog1.C @@ -0,0 +1,28 @@ +// circulator_prog1.C +// ------------------------ +#include +#include +#include +#include +#include + +typedef std::vector::iterator I; +typedef CGAL::Circulator_from_iterator Circulator; +typedef CGAL::Container_from_circulator Container; +typedef Container::iterator Iterator; + +int main() { + std::vector 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; +} diff --git a/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog2.C b/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog2.C new file mode 100644 index 00000000000..e60a8906906 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog2.C @@ -0,0 +1,27 @@ +// circulator_prog2.C +// ------------------------ +#include +#include +#include +#include +#include + +typedef CGAL::Circulator_from_container< std::vector > Circulator; +typedef CGAL::Container_from_circulator Container; +typedef Container::iterator Iterator; + +int main() { + std::vector 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; +} diff --git a/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog3.C b/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog3.C new file mode 100644 index 00000000000..4094ed56712 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/examples/Circulator/circulator_prog3.C @@ -0,0 +1,45 @@ +// circulator_prog3.C +// ------------------------ +#include +#include +#include +#include + +template inline int foo( C c, std::forward_iterator_tag) { + CGAL::Assert_circulator( c); + CGAL::Assert_forward_category( c); + return 1; +} +template inline int foo( C c, std::random_access_iterator_tag) { + CGAL::Assert_circulator( c); + CGAL::Assert_random_access_category( c); + return 2; +} +template inline int foo( I i, CGAL::Iterator_tag) { + CGAL::Assert_iterator( i); + return 3; +} + +template inline int foo( C c, CGAL::Circulator_tag) { + CGAL::Assert_circulator( c); + typedef std::iterator_traits Traits; + typedef typename Traits::iterator_category iterator_category; + return foo( c, iterator_category()); +} +template inline int foo( IC ic) { + typedef CGAL::Circulator_traits Traits; + typedef typename Traits::category category; + return foo( ic, category()); +} + +int main() { + typedef CGAL::Forward_circulator_base F; + typedef CGAL::Random_access_circulator_base R; + F f = F(); + R r = R(); + std::list l; + assert( foo( f) == 1); + assert( foo( r) == 2); + assert( foo( l.begin()) == 3); + return 0; +} diff --git a/Packages/Circulator/doc_tex/support/Circulator/main.tex b/Packages/Circulator/doc_tex/support/Circulator/main.tex new file mode 100644 index 00000000000..b2386e3d4ef --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/main.tex @@ -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} +

Reference Pages

+\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 diff --git a/Packages/Circulator/doc_tex/support/Circulator/manual.tex b/Packages/Circulator/doc_tex/support/Circulator/manual.tex new file mode 100644 index 00000000000..def7105860c --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/manual.tex @@ -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 %% diff --git a/Packages/Circulator/doc_tex/support/Circulator/wrapper.tex b/Packages/Circulator/doc_tex/support/Circulator/wrapper.tex new file mode 100644 index 00000000000..4426a088db4 --- /dev/null +++ b/Packages/Circulator/doc_tex/support/Circulator/wrapper.tex @@ -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 %% diff --git a/Packages/Circulator/examples/Circulator/cgal_test b/Packages/Circulator/examples/Circulator/cgal_test new file mode 100755 index 00000000000..a41c834a1e4 --- /dev/null +++ b/Packages/Circulator/examples/Circulator/cgal_test @@ -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 +#---------------------------------------------------------------------# + +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 + diff --git a/Packages/Circulator/examples/Circulator/circulator_prog1.C b/Packages/Circulator/examples/Circulator/circulator_prog1.C new file mode 100644 index 00000000000..c8a458c828e --- /dev/null +++ b/Packages/Circulator/examples/Circulator/circulator_prog1.C @@ -0,0 +1,28 @@ +// circulator_prog1.C +// ------------------------ +#include +#include +#include +#include +#include + +typedef std::vector::iterator I; +typedef CGAL::Circulator_from_iterator Circulator; +typedef CGAL::Container_from_circulator Container; +typedef Container::iterator Iterator; + +int main() { + std::vector 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; +} diff --git a/Packages/Circulator/examples/Circulator/circulator_prog2.C b/Packages/Circulator/examples/Circulator/circulator_prog2.C new file mode 100644 index 00000000000..e60a8906906 --- /dev/null +++ b/Packages/Circulator/examples/Circulator/circulator_prog2.C @@ -0,0 +1,27 @@ +// circulator_prog2.C +// ------------------------ +#include +#include +#include +#include +#include + +typedef CGAL::Circulator_from_container< std::vector > Circulator; +typedef CGAL::Container_from_circulator Container; +typedef Container::iterator Iterator; + +int main() { + std::vector 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; +} diff --git a/Packages/Circulator/examples/Circulator/circulator_prog3.C b/Packages/Circulator/examples/Circulator/circulator_prog3.C new file mode 100644 index 00000000000..4094ed56712 --- /dev/null +++ b/Packages/Circulator/examples/Circulator/circulator_prog3.C @@ -0,0 +1,45 @@ +// circulator_prog3.C +// ------------------------ +#include +#include +#include +#include + +template inline int foo( C c, std::forward_iterator_tag) { + CGAL::Assert_circulator( c); + CGAL::Assert_forward_category( c); + return 1; +} +template inline int foo( C c, std::random_access_iterator_tag) { + CGAL::Assert_circulator( c); + CGAL::Assert_random_access_category( c); + return 2; +} +template inline int foo( I i, CGAL::Iterator_tag) { + CGAL::Assert_iterator( i); + return 3; +} + +template inline int foo( C c, CGAL::Circulator_tag) { + CGAL::Assert_circulator( c); + typedef std::iterator_traits Traits; + typedef typename Traits::iterator_category iterator_category; + return foo( c, iterator_category()); +} +template inline int foo( IC ic) { + typedef CGAL::Circulator_traits Traits; + typedef typename Traits::category category; + return foo( ic, category()); +} + +int main() { + typedef CGAL::Forward_circulator_base F; + typedef CGAL::Random_access_circulator_base R; + F f = F(); + R r = R(); + std::list l; + assert( foo( f) == 1); + assert( foo( r) == 2); + assert( foo( l.begin()) == 3); + return 0; +} diff --git a/Packages/Circulator/examples/Circulator/makefile b/Packages/Circulator/examples/Circulator/makefile new file mode 100644 index 00000000000..2e6f706f20b --- /dev/null +++ b/Packages/Circulator/examples/Circulator/makefile @@ -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 /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) $< + diff --git a/Packages/Circulator/include/CGAL/circulator.h b/Packages/Circulator/include/CGAL/circulator.h new file mode 100644 index 00000000000..7b3c0d3db7b --- /dev/null +++ b/Packages/Circulator/include/CGAL/circulator.h @@ -0,0 +1,1172 @@ +// ====================================================================== +// +// 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.h +// package : Circulator (3.4) +// chapter : $CGAL_Chapter: Circulators $ +// source : circulator.fw +// revision : $Revision$ +// revision_date : $Date$ +// author(s) : Lutz Kettner +// +// coordinator : INRIA, Sophia Antipolis +// +// Circulator support and Adaptors between circulators and iterators. +// ====================================================================== + +#ifndef CGAL_CIRCULATOR_H +#define CGAL_CIRCULATOR_H 1 + +#ifndef CGAL_BASIC_H +#include +#endif +#ifndef CGAL_PROTECT_CSTDDEF +#include +#define CGAL_PROTECT_CSTDDEF +#endif +#ifndef CGAL_PROTECT_FUNCTIONAL +#include +#define CGAL_PROTECT_FUNCTIONAL +#endif +#ifndef CGAL_PROTECT_ITERATOR +#include +#define CGAL_PROTECT_ITERATOR +#endif +#ifndef CGAL_CIRCULATOR_BASES_H +#include +#endif + +#ifndef CGAL_NULL_TYPE +#if defined( __GNUG__ ) + // (__GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)) +#define CGAL_NULL_TYPE const void* +#define CGAL_CIRC_NULL 0 +#else // __GNUG__ // +#define CGAL_NULL_TYPE int +#define CGAL_CIRC_NULL NULL +#endif // __GNUG__ // +#endif // CGAL_NULL_TYPE // + +// These are name redefinitions for backwards compatibility +// with the pre iterator-traits style adaptors. + +#define Forward_container_from_circulator \ + Container_from_circulator +#define Bidirectional_container_from_circulator \ + Container_from_circulator +#define Random_access_container_from_circulator \ + Container_from_circulator + +#define Forward_circulator_from_iterator \ + Circulator_from_iterator +#define Forward_const_circulator_from_iterator \ + Circulator_from_iterator +#define Bidirectional_circulator_from_iterator \ + Circulator_from_iterator +#define Bidirectional_const_circulator_from_iterator \ + Circulator_from_iterator +#define Random_access_circulator_from_iterator \ + Circulator_from_iterator +#define Random_access_const_circulator_from_iterator \ + Circulator_from_iterator + +#define Forward_circulator_from_container \ + Circulator_from_container +#define Bidirectional_circulator_from_container \ + Circulator_from_container +#define Random_access_circulator_from_container \ + Circulator_from_container + +#define Forward_const_circulator_from_container \ + Const_circulator_from_container +#define Bidirectional_const_circulator_from_container \ + Const_circulator_from_container +#define Random_access_const_circulator_from_container \ + Const_circulator_from_container + + + +CGAL_BEGIN_NAMESPACE + +template +struct I_Circulator_traits { + typedef Iterator_tag category; +}; +CGAL_TEMPLATE_NULL +struct I_Circulator_traits { + typedef Circulator_tag category; +}; +CGAL_TEMPLATE_NULL +struct I_Circulator_traits { + typedef Circulator_tag category; +}; +CGAL_TEMPLATE_NULL +struct I_Circulator_traits { + typedef Circulator_tag category; +}; + +// Circulator_size_traits are used by general adaptors for +// iterators and circulators. For example the N_step_adaptor +// works for iterators as well as for circulators. Circulators +// need a local type called size_type which is not needed for +// iterators. But a general adaptor has to declare this type +// in any case and the following Circulator_size_traits helps +// in this case. It declares size_type to be std::size_t for +// iterators and to be C::size_type for any circulator C. +template +struct I_Circulator_size_traits { + typedef std::size_t size_type; +}; +#ifndef CGAL_CFG_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION +template +struct I_Circulator_size_traits< Forward_circulator_tag, C> { + typedef typename C::size_type size_type; +}; +template +struct I_Circulator_size_traits< Bidirectional_circulator_tag, C> { + typedef typename C::size_type size_type; +}; +template +struct I_Circulator_size_traits< Random_access_circulator_tag, C> { + typedef typename C::size_type size_type; +}; +#endif // CGAL_CFG_NO_PARTIAL_CLASS_TEMPLATE_SPECIALISATION // + +template +struct I_Iterator_from_circulator_traits { + typedef CCtg iterator_category; +}; +CGAL_TEMPLATE_NULL +struct I_Iterator_from_circulator_traits< Forward_circulator_tag> { + typedef std::forward_iterator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct I_Iterator_from_circulator_traits< + Bidirectional_circulator_tag> { + typedef std::bidirectional_iterator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct I_Iterator_from_circulator_traits< + Random_access_circulator_tag> { + typedef std::random_access_iterator_tag iterator_category; +}; + +template +struct I_Circulator_from_iterator_traits { + typedef ICtg iterator_category; +}; +CGAL_TEMPLATE_NULL +struct I_Circulator_from_iterator_traits< std::forward_iterator_tag> { + typedef Forward_circulator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct I_Circulator_from_iterator_traits { + typedef Bidirectional_circulator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct I_Circulator_from_iterator_traits { + typedef Random_access_circulator_tag iterator_category; +}; + +template +struct Circulator_traits { + typedef std::iterator_traits traits; + typedef typename traits::iterator_category ICAT; + typedef I_Circulator_traits C_traits; + typedef typename C_traits::category category; + + typedef I_Iterator_from_circulator_traits Ic_traits; + typedef typename Ic_traits::iterator_category iterator_category; + + typedef I_Circulator_from_iterator_traits Ci_traits; + typedef typename Ci_traits::iterator_category circulator_category; +}; + +template +typename Circulator_traits::category +query_circulator_or_iterator( const C&) { + typedef typename Circulator_traits::category category; + return category(); +} +/* A function that asserts a specific compile time tag */ +/* forcing its two arguments to have equal type. */ +/* It is encapsulated with #ifdef since it will be defined also elsewhere. */ +#ifndef CGAL_ASSERT_COMPILE_TIME_TAG +#define CGAL_ASSERT_COMPILE_TIME_TAG 1 +template +struct I_Assert_tag_class { + void match_compile_time_tag( const Base&) const {} +}; +template< class Tag, class Derived> +inline void Assert_compile_time_tag( const Tag&, const Derived& b) { + I_Assert_tag_class x; + x.match_compile_time_tag(b); +} +#endif + +template inline +void Assert_circulator( const C &c) { + Assert_compile_time_tag( Circulator_tag(),query_circulator_or_iterator(c)); +} +template inline +void Assert_iterator( const I &i) { + Assert_compile_time_tag( Iterator_tag(), query_circulator_or_iterator(i)); +} +template inline +void Assert_input_category( const I &i) { + Assert_compile_time_tag( std::input_iterator_tag(), + std::iterator_category(i)); +} +template inline +void Assert_output_category( const I &i) { + Assert_compile_time_tag( std::output_iterator_tag(), + std::iterator_category(i)); +} +template inline +void Assert_forward_category( const IC &ic) { + Assert_compile_time_tag( std::forward_iterator_tag(), + std::iterator_category(ic)); +} +template inline +void Assert_bidirectional_category( const IC &ic) { + Assert_compile_time_tag( std::bidirectional_iterator_tag(), + std::iterator_category(ic)); +} +template inline +void Assert_random_access_category( const IC &ic) { + Assert_compile_time_tag( std::random_access_iterator_tag(), + std::iterator_category(ic)); +} + +// The assert at-least-category functions use the following +// functions to resolve properly. Note the proper order of the +// arguments: 1st is the to be type, 2nd is the actual type. +inline void I_Has_to_be_at_least( std::input_iterator_tag, + std::input_iterator_tag){} +inline void I_Has_to_be_at_least( std::input_iterator_tag, + std::forward_iterator_tag){} +inline void I_Has_to_be_at_least( std::input_iterator_tag, + std::bidirectional_iterator_tag){} +inline void I_Has_to_be_at_least( std::input_iterator_tag, + std::random_access_iterator_tag){} + +inline void I_Has_to_be_at_least( std::output_iterator_tag, + std::output_iterator_tag){} +inline void I_Has_to_be_at_least( std::output_iterator_tag, + std::forward_iterator_tag){} +inline void I_Has_to_be_at_least( std::output_iterator_tag, + std::bidirectional_iterator_tag){} +inline void I_Has_to_be_at_least( std::output_iterator_tag, + std::random_access_iterator_tag){} + +inline void I_Has_to_be_at_least( std::forward_iterator_tag, + std::forward_iterator_tag){} +inline void I_Has_to_be_at_least( std::forward_iterator_tag, + std::bidirectional_iterator_tag){} +inline void I_Has_to_be_at_least( std::forward_iterator_tag, + std::random_access_iterator_tag){} + +inline void I_Has_to_be_at_least( std::bidirectional_iterator_tag, + std::bidirectional_iterator_tag){} +inline void I_Has_to_be_at_least( std::bidirectional_iterator_tag, + std::random_access_iterator_tag){} + +inline void I_Has_to_be_at_least( std::random_access_iterator_tag, + std::random_access_iterator_tag){} + +// The is-at-least assertions. +template inline +void Assert_is_at_least_input_category( const I& i) { + I_Has_to_be_at_least( std::input_iterator_tag(), + std::iterator_category(i)); +} +template inline +void Assert_is_at_least_output_category( const I& i) { + I_Has_to_be_at_least( std::output_iterator_tag(), + std::iterator_category(i)); +} +template inline +void Assert_is_at_least_forward_category( const IC& ic) { + I_Has_to_be_at_least( std::forward_iterator_tag(), + std::iterator_category(ic)); +} +template inline +void Assert_is_at_least_bidirectional_category( const IC& ic) { + I_Has_to_be_at_least( std::bidirectional_iterator_tag(), + std::iterator_category(ic)) ; + } +template inline +void Assert_is_at_least_random_access_category( const IC& ic) { + I_Has_to_be_at_least( std::random_access_iterator_tag(), + std::iterator_category(ic)); +} + +template< class C> inline +bool I_is_empty_range( const C& c1, const C&, Circulator_tag){ + return c1 == CGAL_CIRC_NULL; +} + +template< class I> inline +bool I_is_empty_range( const I& i1, const I& i2, Iterator_tag){ + return i1 == i2; +} + +template< class IC> inline +bool is_empty_range( const IC& ic1, const IC& ic2){ + // is `true' if the range [`ic1, ic2') is empty, `false' otherwise. + // Precondition: `T' is either a circulator or an iterator type. The + // range [`ic1, ic2') is valid. + return I_is_empty_range( ic1, ic2, query_circulator_or_iterator(ic1)); +} + +struct Circulator_or_iterator_tag {}; // any circulator or iterator. + +inline +Circulator_or_iterator_tag +check_circulator_or_iterator( Circulator_tag ){ + return Circulator_or_iterator_tag(); +} +inline +Circulator_or_iterator_tag +check_circulator_or_iterator( Iterator_tag ){ + return Circulator_or_iterator_tag(); +} + +template< class IC> inline +void Assert_circulator_or_iterator( const IC &ic){ + Assert_compile_time_tag( + Circulator_or_iterator_tag(), + check_circulator_or_iterator( query_circulator_or_iterator(ic))); +} + +#define CGAL_For_all( ic1, ic2) \ + for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range( ic1, ic2); \ + _circ_loop_flag; \ + _circ_loop_flag = ((++ic1) != (ic2)) ) + +#define CGAL_For_all_backwards( ic1, ic2) \ + for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range( ic1, ic2); \ + _circ_loop_flag; \ + _circ_loop_flag = ((ic1) != (--ic2)) ) + + + +template inline +typename C::size_type +I_min_circulator_size( const C& c) { + Assert_circulator(c); + Assert_random_access_category(c); + typedef typename C::size_type size_type; + size_type n = 0; + if ( c != CGAL_CIRC_NULL) { + n = (c-1) - c + 1; + CGAL_assertion(n > 0); + } + return n; +} + +template +typename C::size_type +I_circulator_size( const C& c, Forward_circulator_tag) { + // Simply count. + if ( c == CGAL_CIRC_NULL) + return 0; + typedef typename C::size_type size_type; + size_type n = 0; + C d = c; + do { + ++n; + ++d; + } while( c != d); + return n; +} +template inline +typename C::size_type +I_circulator_size( const C& c, Bidirectional_circulator_tag) { + return I_circulator_size( c, Forward_circulator_tag()); +} +template inline +typename C::size_type +I_circulator_size( const C& c, Random_access_circulator_tag) { + return I_min_circulator_size( c.min_circulator()); +} + +template inline +typename C::size_type +circulator_size( const C& c) { + return I_circulator_size( c, std::iterator_category(c)); +} +template +typename C::difference_type +I_circulator_distance( C c, const C& d, Forward_circulator_tag) { + // Simply count. + if ( c == CGAL_CIRC_NULL) + return 0; + typedef typename C::difference_type difference_type; + difference_type n = 0; + do { + ++n; + } while( ++c != d); + return n; +} +template inline +typename C::difference_type +I_circulator_distance( const C& c, const C& d, + Bidirectional_circulator_tag) { + return I_circulator_distance( c, d, Forward_circulator_tag()); +} +template inline +typename C::difference_type +I_circulator_distance( const C& c, const C& d, + Random_access_circulator_tag) { + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + if ( d - c > 0) + return (d - c); + return difference_type( size_type( I_min_circulator_size( + c.min_circulator()))) - (c-d); +} + +template inline +typename C::difference_type +circulator_distance( const C& c, const C& d) { + return I_circulator_distance( c, d, std::iterator_category(c)); +} +template inline +typename std::iterator_traits::difference_type +I_iterator_distance(const C& c1, const C& c2, Circulator_tag) { + return circulator_distance( c1, c2); +} + +template inline +typename std::iterator_traits::difference_type +I_iterator_distance(const I& i1, const I& i2, Iterator_tag) { + return std::distance( i1, i2); +} + +template inline +typename std::iterator_traits::difference_type +iterator_distance(const IC& ic1, const IC& ic2) { + return I_iterator_distance( ic1, ic2, + query_circulator_or_iterator(ic1)); +} +template inline +C I_get_min_circulator( C c, Forward_circulator_tag) { + return c; +} +template inline +C I_get_min_circulator( C c, Bidirectional_circulator_tag) { + return c; +} +template inline +C I_get_min_circulator( C c, Random_access_circulator_tag) { + return c.min_circulator(); +} +template inline +C get_min_circulator( C c) { + return I_get_min_circulator( c, std::iterator_category(c)); +} +template inline +I non_negative_mod(I n, U m) { + CGAL_precondition( m > 0); + #if (-1 % 3) > 0 + n = n % m; + #else + if (n < 0) + n = - (( - n - 1) % m) + m - 1; + else + n = n % m; + #endif + CGAL_postcondition( n >= 0); + return n; +} + +template < class C, class Ref, class Ptr> +class Iterator_from_circulator { +private: + // The m_anchor is normalized to be a minimal circulator. + const C* m_anchor; + C current; + int m_winding; + + typedef std::iterator_traits I_traits; + typedef typename I_traits::iterator_category I_Iter_cat; + typedef I_Iterator_from_circulator_traits I__traits; + +public: +// +// TYPES + + typedef C Circulator; + typedef Iterator_from_circulator Self; + + typedef typename I__traits::iterator_category iterator_category; + + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + typedef typename C::reference reference; + typedef typename C::pointer pointer; + +// +// CREATION + + Iterator_from_circulator() : m_anchor(0), m_winding(0) {} + + Iterator_from_circulator( const C* circ, int n) + : m_anchor( circ), current( *circ), m_winding(n) {} + + // Allow construction from Iterator_from_circulator with + // assignment compatible circulator CC: + template + Iterator_from_circulator( + const Iterator_from_circulator& c) + : m_anchor( c.anchor()), current( c.current_circulator()), + m_winding(c.winding()) {} + +// +// OPERATIONS + + bool operator==( const Self& i) const { + CGAL_assertion( m_anchor == i.m_anchor); // same anchor? + return ( current == i.current) && ( m_winding == i.m_winding); + } + bool operator!=( const Self& i) const { + return !(*this == i); + } + Ref operator*() const { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ref(*current); + } + Ptr operator->() const { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ptr(current.operator->()); + } + Self& operator++() { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + ++current; + if ( current == *m_anchor) + ++m_winding; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( current == *m_anchor) + --m_winding; + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + Self& operator+=( difference_type n) { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( n < 0 && current == *m_anchor) // We are leaving the anchor. + --m_winding; + current += n; + if ( n > 0 && current == *m_anchor) // Back again at the anchor. + ++m_winding; + return *this; + } + Self operator+( difference_type n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( difference_type n) { + return operator+=( -n); + } + Self operator-( difference_type n) const { + Self tmp = *this; + return tmp += -n; + } +#ifndef _MSC_VER + difference_type operator-( const Self& i) const; +#else + difference_type operator-( const Self& i) const { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + CGAL_assertion( m_anchor == i.m_anchor); + if ( m_winding != i.m_winding) { + difference_type s = I_min_circulator_size( *m_anchor); + return (current - *m_anchor) - (i.current - *m_anchor) + + s * (m_winding - i.m_winding); + } + return (current - *m_anchor) - (i.current - *m_anchor); + } +#endif + + Ref operator[](difference_type n) const { + Self tmp = *this; + tmp += n; + return tmp.operator*(); + } + bool operator<( const Self& i) const { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + CGAL_assertion( m_anchor == i.m_anchor); + return ( (m_winding < i.m_winding) + || ( (m_winding == i.m_winding) + && (current - *m_anchor) < (i.current - *m_anchor) + ) + ); + } + bool operator> ( const Self& i) const { return i < *this; } + bool operator<=( const Self& i) const { return !(i < *this); } + bool operator>=( const Self& i) const { return !(*this < i); } + + const C* anchor() const { return m_anchor;} + int winding() const { return m_winding;} + Circulator current_circulator() const { return current;} +}; + +template < class Dist, class C, class Ref, class Ptr> +Iterator_from_circulator +operator+( Dist n, const Iterator_from_circulator& circ) { + Iterator_from_circulator tmp = circ; + return tmp += n; +} + +#ifndef _MSC_VER +template < class C, class Ref, class Ptr> +typename C::difference_type +Iterator_from_circulator:: +operator-( const Iterator_from_circulator& i) const { + CGAL_assertion( m_anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + CGAL_assertion( m_anchor == i.m_anchor); + if ( m_winding != i.m_winding) { + difference_type s = I_min_circulator_size( *m_anchor); + return (current - *m_anchor) - (i.current - *m_anchor) + + s * (m_winding - i.m_winding); + } + return (current - *m_anchor) - (i.current - *m_anchor); +} +#endif // _MSC_VER // + +template < class C > +class Container_from_circulator { +private: + C anchor; +public: +// +// CREATION + + Container_from_circulator() {} + // the resulting iterators will have a singular value. + + Container_from_circulator(const C& c) + // The anchor is normalized to be a minimal circulator. + : anchor(get_min_circulator(c)) {} + // the resulting iterators will have a singular value if the + // circulator `c' is singular. + +// +// TYPES + +typedef C Circulator; + +typedef typename C::value_type value_type; +typedef value_type& reference; +typedef const value_type& const_reference; +typedef value_type* pointer; +typedef const value_type* const_pointer; +typedef typename C::size_type size_type; +typedef typename C::difference_type difference_type; + +typedef Iterator_from_circulator< C, reference, pointer> + iterator; +typedef Iterator_from_circulator< C, const_reference, const_pointer> + const_iterator; +// +// OPERATIONS + + iterator begin() { + // the start iterator. + return iterator( &anchor, 0); + } + const_iterator begin() const { + // the start const iterator. + return const_iterator( &anchor, 0); + } + iterator end() { + // the past-the-end iterator. + return anchor == CGAL_CIRC_NULL ? iterator( &anchor, 0) + : iterator( &anchor, 1); + } + const_iterator end() const { + // the past-the-end const iterator. + return anchor == CGAL_CIRC_NULL ? const_iterator( &anchor, 0) + : const_iterator( &anchor, 1); + } +}; +template < class Ctnr> +class Circulator_from_container { +public: +// TYPES + + typedef Circulator_from_container Self; + typedef Ctnr Container; + typedef typename Ctnr::iterator iterator; + typedef typename Ctnr::value_type value_type; + typedef typename Ctnr::reference reference; + typedef value_type* pointer; + typedef typename Ctnr::size_type size_type; + typedef typename Ctnr::difference_type difference_type; + + typedef std::iterator_traits ITraits; + typedef typename ITraits::iterator_category Icategory; + typedef I_Circulator_from_iterator_traits CTraits; + typedef typename CTraits::iterator_category iterator_category; + +private: + Ctnr* ctnr; + iterator i; + +public: +// CREATION + + Circulator_from_container() : ctnr(NULL) {} + Circulator_from_container( Ctnr* c) : ctnr(c), i(c->begin()) {} + Circulator_from_container( Ctnr* c, iterator j) : ctnr(c), i(j) {} + +// Gnu-bug workaround: define operator= explicitly. + Self& operator=( const Self& c) { + ctnr = c.ctnr; + i = c.i; + return *this; + } + +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (ctnr == NULL) || (ctnr->begin() == ctnr->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); } + bool operator==( const Self& c) const { return i == c.i; } + bool operator!=( const Self& c) const { return !(*this == c); } + reference operator*() const { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + return i.operator->(); + } + Self& operator++() { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + ++i; + if ( i == ctnr->end()) + i = ctnr->begin(); + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + if ( i == ctnr->begin()) + i = ctnr->end(); + --i; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } +#ifndef _MSC_VER + Self& operator+=( difference_type n); +#else + Self& operator+=( difference_type n) { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + typename Ctnr::difference_type j = i - ctnr->begin(); + typename Ctnr::difference_type size = ctnr->size(); + CGAL_assertion( j >= 0); + CGAL_assertion( size >= 0); + j = non_negative_mod( j + n, size); + CGAL_assertion( j >= 0); + CGAL_assertion( j < size); + i = ctnr->begin() + j; + return *this; + } +#endif + Self operator+( difference_type n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( difference_type n) { return operator+=( -n); } + Self operator-( difference_type n) const { + Self tmp = *this; + return tmp += -n; + } + difference_type operator-( const Self& c) const { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( c.ctnr != NULL); + return i - c.i; + } + reference operator[]( difference_type n) const { + Self tmp = *this; + tmp += n; + return *tmp; + } + iterator current_iterator() const { return i;} + Self min_circulator() const { return Self(ctnr); } + Ctnr* container() const { return ctnr; } +}; + +template +inline +Circulator_from_container +operator+( typename Circulator_from_container::difference_type n, + const Circulator_from_container& c) { + Circulator_from_container tmp = c; + return tmp += n; +} + +#ifndef _MSC_VER +template +Circulator_from_container& +Circulator_from_container:: +operator+=( typename Ctnr::difference_type n) { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + typename Ctnr::difference_type j = i - ctnr->begin(); + typename Ctnr::difference_type size = ctnr->size(); + CGAL_assertion( j >= 0); + CGAL_assertion( size >= 0); + j = non_negative_mod( j + n, size); + CGAL_assertion( j >= 0); + CGAL_assertion( j < size); + i = ctnr->begin() + j; + return *this; +} +#endif // _MSC_VER // + + +template < class Ctnr> +class Const_circulator_from_container { +public: +// TYPES + + typedef Const_circulator_from_container Self; + typedef Circulator_from_container Mutable; + typedef Ctnr Container; + typedef typename Ctnr::const_iterator const_iterator; + typedef typename Ctnr::value_type value_type; + typedef typename Ctnr::const_reference reference; + typedef const value_type* pointer; + typedef typename Ctnr::size_type size_type; + typedef typename Ctnr::difference_type difference_type; + + typedef std::iterator_traits ITraits; + typedef typename ITraits::iterator_category Icategory; + typedef I_Circulator_from_iterator_traits CTraits; + typedef typename CTraits::iterator_category iterator_category; + +private: + const Ctnr* ctnr; + const_iterator i; + +public: +// CREATION + + Const_circulator_from_container() : ctnr(NULL) {} + Const_circulator_from_container( const Ctnr* c) + : ctnr(c), i(c->begin()) {} + Const_circulator_from_container( const Ctnr* c, const_iterator j) + : ctnr(c), i(j) {} + Const_circulator_from_container( const Mutable& c) + : ctnr( c.container()), i( c.current_iterator()) {} + +// Gnu-bug workaround: define operator= explicitly. + Self& operator=( const Self& c) { + ctnr = c.ctnr; + i = c.i; + return *this; + } + +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (ctnr == NULL) || (ctnr->begin() == ctnr->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); } + bool operator==( const Self& c) const { return i == c.i; } + bool operator!=( const Self& c) const { return !(*this == c); } + reference operator*() const { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + return i.operator->(); + } + Self& operator++() { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + ++i; + if ( i == ctnr->end()) + i = ctnr->begin(); + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + if ( i == ctnr->begin()) + i = ctnr->end(); + --i; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } +#ifndef _MSC_VER + Self& operator+=( difference_type n); +#else + Self& operator+=( difference_type n) { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + typename Ctnr::difference_type j = i - ctnr->begin(); + typename Ctnr::difference_type size = ctnr->size(); + CGAL_assertion( j >= 0); + CGAL_assertion( size >= 0); + j = non_negative_mod( j + n, size); + CGAL_assertion( j >= 0); + CGAL_assertion( j < size); + i = ctnr->begin() + j; + return *this; + } +#endif + Self operator+( difference_type n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( difference_type n) { return operator+=( -n); } + Self operator-( difference_type n) const { + Self tmp = *this; + return tmp += -n; + } + difference_type operator-( const Self& c) const { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( c.ctnr != NULL); + return i - c.i; + } + reference operator[]( difference_type n) const { + Self tmp = *this; + tmp += n; + return *tmp; + } + const_iterator current_iterator() const { return i;} + Self min_circulator() const { return Self(ctnr); } + const Ctnr* container() const { return ctnr; } +}; + +template +inline +Const_circulator_from_container +operator+( typename Const_circulator_from_container:: + difference_type n, + const Const_circulator_from_container& c) { + Const_circulator_from_container tmp = c; + return tmp += n; +} + +#ifndef _MSC_VER +template +Const_circulator_from_container& +Const_circulator_from_container:: +operator+=( typename Ctnr::difference_type n) { + CGAL_assertion( ctnr != NULL); + CGAL_assertion( i != ctnr->end()); + typename Ctnr::difference_type j = i - ctnr->begin(); + typename Ctnr::difference_type size = ctnr->size(); + CGAL_assertion( j >= 0); + CGAL_assertion( size >= 0); + j = non_negative_mod( j + n, size); + CGAL_assertion( j >= 0); + CGAL_assertion( j < size); + i = ctnr->begin() + j; + return *this; +} +#endif _MSC_VER +// Note: TT, SS, and DD are here for backwards compatibility, they are +// not used. +template < class I, class TT = int, class SS = int, class DD = int> +class Circulator_from_iterator { +public: +// TYPES + + typedef Circulator_from_iterator Self; + typedef I iterator; + typedef std::iterator_traits Traits; + + typedef typename Traits::value_type value_type; + typedef std::size_t size_type; + typedef typename Traits::difference_type difference_type; + typedef typename Traits::reference reference; + typedef typename Traits::pointer pointer; + + typedef typename Traits::iterator_category Icategory; + typedef I_Circulator_from_iterator_traits CTraits; + typedef typename CTraits::iterator_category iterator_category; + +private: + I m_begin; + I m_end; + I current; + +public: +// CREATION + + Circulator_from_iterator() : m_begin(I()), m_end(I()), current(I()) {} + + Circulator_from_iterator( const I& bgn, const I& end) + : m_begin(bgn), m_end(end), current(bgn) {} + + Circulator_from_iterator( const I& bgn, const I& end, const I& cur) + : m_begin(bgn), m_end(end), current(cur) {} + + Circulator_from_iterator( const Self& c, const I& cur) + : m_begin( c.m_begin), m_end( c.m_end), current(cur) {} + + + template + // Allow construction from Circulator_from_iterator with + // assignment compatible iterator II: + Circulator_from_iterator( + const Circulator_from_iterator& ii) + : m_begin( ii.begin()), m_end( ii.end()), + current(ii.current_iterator()) {} + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + CGAL_assertion((m_end == m_begin) || (current != m_end)); + return m_end == m_begin; + } + bool operator!=( CGAL_NULL_TYPE p) const { return !(*this == p); } + bool operator==( const Self& c) const { return current == c.current;} + bool operator!=( const Self& c) const { return !(*this == c); } + reference operator*() const { + CGAL_assertion( current != m_end); + return *current; + } + pointer operator->() const { + CGAL_assertion( current != m_end); + return &(*current); + } + Self& operator++() { + CGAL_assertion( current != m_end); + ++current; + if ( current == m_end) + current = m_begin; + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( current != m_end); + if ( current == m_begin) + current = m_end; + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + Self& operator+=( difference_type n) { + CGAL_assertion( current != m_end); + difference_type i = current - m_begin; + difference_type size = m_end - m_begin; + CGAL_assertion( i >= 0); + CGAL_assertion( size >= 0); + i = non_negative_mod( i + n, size); + CGAL_assertion( i >= 0); + CGAL_assertion( i < size); + current = m_begin + i; + return *this; + } + Self operator+( difference_type n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( difference_type n) { return operator+=( -n); } + Self operator-( difference_type n) const { + Self tmp = *this; + return tmp += -n; + } + difference_type operator-( const Self& i) const { + CGAL_assertion((m_begin == i.m_begin) && (m_end == i.m_end)); + return current - i.current; + } + reference operator[](difference_type n) const { + Self tmp = *this; + tmp += n; + return tmp.operator*(); + } + iterator begin() const { return m_begin;} + iterator end() const { return m_end;} + iterator current_iterator() const { return current;} + Self min_circulator() const { return Self( m_begin, m_end); } +}; + +template < class D, class I, class T, class Size, class Dist> inline +Circulator_from_iterator< I, T, Size, Dist> +operator+( D n, const + Circulator_from_iterator< I, T, Size, Dist>& circ) { + Circulator_from_iterator< I, T, Size, Dist> + tmp = circ; + return tmp += Dist(n); +} + +CGAL_END_NAMESPACE + +#endif // CGAL_CIRCULATOR_H // +// EOF // diff --git a/Packages/Circulator/include/CGAL/circulator_bases.h b/Packages/Circulator/include/CGAL/circulator_bases.h new file mode 100644 index 00000000000..8020600ff30 --- /dev/null +++ b/Packages/Circulator/include/CGAL/circulator_bases.h @@ -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 +// +// 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 +#define CGAL_PROTECT_CSTDDEF +#endif +#ifndef CGAL_PROTECT_ITERATOR +#include +#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 +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 +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 +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 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 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 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 // diff --git a/Packages/Circulator/include/CGAL/circulator_compat.h b/Packages/Circulator/include/CGAL/circulator_compat.h new file mode 100644 index 00000000000..a335d0a6e61 --- /dev/null +++ b/Packages/Circulator/include/CGAL/circulator_compat.h @@ -0,0 +1,3424 @@ +// ====================================================================== +// +// 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_compat.h +// package : Circulator (3.4) +// chapter : $CGAL_Chapter: Circulators $ +// source : circulator_compat.fw +// revision : $Revision$ +// revision_date : $Date$ +// author(s) : Lutz Kettner +// +// coordinator : INRIA, Sophia Antipolis +// +// Old Circulator File for Compatibility with pre iterator_traits. +// ====================================================================== + +#ifndef CGAL_CIRCULATOR_COMPAT_H +#define CGAL_CIRCULATOR_COMPAT_H 1 +// This file replaces circulator.h +#define CGAL_CIRCULATOR_H 1 + +#ifndef CGAL_BASIC_H +#include +#endif +#ifndef CGAL_PROTECT_CSTDDEF +#include +#define CGAL_PROTECT_CSTDDEF +#endif +#ifndef CGAL_PROTECT_FUNCTIONAL +#include +#define CGAL_PROTECT_FUNCTIONAL +#endif +#ifndef CGAL_PROTECT_ITERATOR +#include +#define CGAL_PROTECT_ITERATOR +#endif +#ifndef CGAL_CIRCULATOR_BASES_H +#include +#endif + +// CGAL defined Tags. +#ifndef CGAL_CFG_NO_ITERATOR_TRAITS +#define CGAL__CIRC_STL_ITERATOR_TRAITS +#endif // CGAL_CFG_NO_ITERATOR_TRAITS // + +#ifndef CGAL__CIRC_STL_ITERATOR_TRAITS + + // Try to figure out what STL is used. +# ifdef __GNUG__ +# if __GNUC__ == 2 && __GNUC_MINOR__ == 7 +# define CGAL__CIRC_STL_GCC +# else +# define CGAL__CIRC_STL_SGI_3_0 +# endif + +# else // __GNUG__ // + // Try to distinguish between HP and newest SGI STL (June 1997). + // CGAL standard multiple inclusion protection does not harm here. +#ifndef CGAL_PROTECT_LIST +#include +#define CGAL_PROTECT_LIST +#endif +# ifdef LIST_H +# ifdef __sgi + // Assume that SGI don't use HP STL any more. Then LIST_H + // indicates an earlier SGI STL delivered with the C++ + // compiler release 7.1. +# define CGAL__CIRC_STL_SGI_CC_1996 +# else // __sgi // + // On non SGI systems assume HP STL as default. +# define CGAL__CIRC_STL_HP +# endif // __sgi // +# else // LIST_H // +# ifdef __SGI_STL_LIST_H + // No else part. If its not the SGI STL, we don't know what + // it is. Check if partial specialization and iterator + // traits are supported. Check also for new 3.0 STL. +# ifdef __STL_CLASS_PARTIAL_SPECIALIZATION +# define CGAL__CIRC_STL_ITERATOR_TRAITS +# else // __STL_CLASS_PARTIAL_SPECIALIZATION // +# if defined( __SGI_STL_INTERNAL_ITERATOR_H) || \ + (defined( __SGI_STL_PORT) && __SGI_STL_PORT >= 0x2031) +# define CGAL__CIRC_STL_SGI_3_0 +# else +# define CGAL__CIRC_STL_SGI_JUNE_1997 +# endif // Release 3.0 // +# endif // __STL_CLASS_PARTIAL_SPECIALIZATION // +# endif // __SGI_STL_LIST_H // +# endif // LIST_H // +# endif // __GNUG__ // + +#endif + +#ifndef CGAL_NULL_TYPE +#if defined( __GNUG__ ) + // (__GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91)) +#define CGAL_NULL_TYPE const void* +#define CGAL_CIRC_NULL 0 +#else // __GNUG__ // +#define CGAL_NULL_TYPE int +#define CGAL_CIRC_NULL NULL +#endif // __GNUG__ // +#endif // CGAL_NULL_TYPE // + +CGAL_BEGIN_NAMESPACE + +template +struct _Circulator_traits { + typedef Iterator_tag category; +}; +CGAL_TEMPLATE_NULL +struct _Circulator_traits { + typedef Circulator_tag category; +}; +CGAL_TEMPLATE_NULL +struct _Circulator_traits { + typedef Circulator_tag category; +}; +CGAL_TEMPLATE_NULL +struct _Circulator_traits { + typedef Circulator_tag category; +}; + +template +struct _Circulator_size_traits { + typedef std::size_t size_type; +}; +#ifndef CGAL_CFG_NO_ITERATOR_TRAITS +template +struct _Circulator_size_traits { + typedef typename C::size_type size_type; +}; +template +struct _Circulator_size_traits { + typedef typename C::size_type size_type; +}; +template +struct _Circulator_size_traits { + typedef typename C::size_type size_type; +}; +#endif // CGAL_CFG_NO_ITERATOR_TRAITS // +#ifdef CGAL__CIRC_STL_ITERATOR_TRAITS +template +struct Circulator_traits { + typedef std::iterator_traits traits; + typedef typename traits::iterator_category iterator_category; + typedef _Circulator_traits< iterator_category> C_traits; + typedef typename C_traits::category category; +}; + +template +typename Circulator_traits::category +query_circulator_or_iterator( const C&) { + typedef typename Circulator_traits::category category; + return category(); +} + +template +struct _Iterator_from_circulator_traits {}; + +CGAL_TEMPLATE_NULL +struct _Iterator_from_circulator_traits< Forward_circulator_tag> { + typedef std::forward_iterator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct _Iterator_from_circulator_traits< + Bidirectional_circulator_tag> { + typedef std::bidirectional_iterator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct _Iterator_from_circulator_traits< + Random_access_circulator_tag> { + typedef std::random_access_iterator_tag iterator_category; +}; + +template +struct _Circulator_from_iterator_traits { +}; +CGAL_TEMPLATE_NULL +struct _Circulator_from_iterator_traits< std::forward_iterator_tag> { + typedef Forward_circulator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct _Circulator_from_iterator_traits< std::bidirectional_iterator_tag> { + typedef Bidirectional_circulator_tag iterator_category; +}; +CGAL_TEMPLATE_NULL +struct _Circulator_from_iterator_traits< std::random_access_iterator_tag> { + typedef Random_access_circulator_tag iterator_category; +}; +#else // CGAL__CIRC_STL_ITERATOR_TRAITS // +// No iterator traits. +// =================== +// Iterators +// --------- +template< class T, class D> inline +Iterator_tag +query_circulator_or_iterator( const std::input_iterator&){ + return Iterator_tag(); +} +inline +Iterator_tag +query_circulator_or_iterator( const std::output_iterator&){ + return Iterator_tag(); +} +template< class T, class D> inline +Iterator_tag +query_circulator_or_iterator( const std::forward_iterator&){ + return Iterator_tag(); +} +template< class T, class D> inline +Iterator_tag +query_circulator_or_iterator( const std::bidirectional_iterator&){ + return Iterator_tag(); +} +template< class T, class D> inline +Iterator_tag +query_circulator_or_iterator( const std::random_access_iterator&){ + return Iterator_tag(); +} +template< class T> inline +Iterator_tag +query_circulator_or_iterator( T*){ + return Iterator_tag(); +} +template< class T> inline +Iterator_tag +query_circulator_or_iterator( const T*){ + return Iterator_tag(); +} + +// Circulators +// ----------- +template< class T, class D, class S> inline +Circulator_tag +query_circulator_or_iterator( + const Forward_circulator_base&){ + return Circulator_tag(); +} +template< class T, class D, class S> inline +Circulator_tag +query_circulator_or_iterator( + const Bidirectional_circulator_base&){ + return Circulator_tag(); +} +template< class T, class D, class S> inline +Circulator_tag +query_circulator_or_iterator( + const Random_access_circulator_base&){ + return Circulator_tag(); +} + +// variant base classes +// -------------------- +template< class T, class D, class S> inline +Circulator_tag +query_circulator_or_iterator( + const Forward_circulator_ptrbase&){ + return Circulator_tag(); +} +template< class T, class D, class S> inline +Circulator_tag +query_circulator_or_iterator( + const Bidirectional_circulator_ptrbase&){ + return Circulator_tag(); +} +template< class T, class D, class S> inline +Circulator_tag +query_circulator_or_iterator( + const Random_access_circulator_ptrbase&){ + return Circulator_tag(); +} +// No iterator traits. +// =================== +// variant base classes +// -------------------- +// The normal base classes could be handled automatically through inheritance. + +template< class T, class D, class S> inline +Forward_circulator_tag +std::iterator_category( const Forward_circulator_ptrbase&){ + return Forward_circulator_tag(); +} +template< class T, class D, class S> inline +Bidirectional_circulator_tag +std::iterator_category( const Bidirectional_circulator_ptrbase&){ + return Bidirectional_circulator_tag(); +} +template< class T, class D, class S> inline +Random_access_circulator_tag +std::iterator_category( const Random_access_circulator_ptrbase&){ + return Random_access_circulator_tag(); +} + +template< class T, class D, class S> inline +Forward_circulator_tag +std::iterator_category( const Forward_circulator_base&){ + return Forward_circulator_tag(); +} +template< class T, class D, class S> inline +Bidirectional_circulator_tag +std::iterator_category( const Bidirectional_circulator_base&){ + return Bidirectional_circulator_tag(); +} +template< class T, class D, class S> inline +Random_access_circulator_tag +std::iterator_category( const Random_access_circulator_base&){ + return Random_access_circulator_tag(); +} +template inline +T* std::value_type( const Forward_circulator_ptrbase&) { + return (T*)(0); +} +template inline +T* std::value_type( const Bidirectional_circulator_ptrbase&) { + return (T*)(0); +} +template inline +T* std::value_type( const Random_access_circulator_ptrbase&) { + return (T*)(0); +} +template inline +Dist* std::distance_type( const Forward_circulator_ptrbase&) { + return (Dist*)(0); +} +template inline +Dist* std::distance_type( + const Bidirectional_circulator_ptrbase&) { + return (Dist*)(0); +} +template inline +Dist* std::distance_type( + const Random_access_circulator_ptrbase&) { + return (Dist*)(0); +} + +template inline +T* std::value_type( const Forward_circulator_base&) { + return (T*)(0); +} +template inline +T* std::value_type( const Bidirectional_circulator_base&) { + return (T*)(0); +} +template inline +T* std::value_type( const Random_access_circulator_base&) { + return (T*)(0); +} +template inline +Dist* std::distance_type( const Forward_circulator_base&) { + return (Dist*)(0); +} +template inline +Dist* std::distance_type( const Bidirectional_circulator_base&) { + return (Dist*)(0); +} +template inline +Dist* std::distance_type( const Random_access_circulator_base&) { + return (Dist*)(0); +} +#endif // CGAL__CIRC_STL_ITERATOR_TRAITS // +# ifndef CGAL__CIRC_STL_ITERATOR_TRAITS +# ifdef CGAL__CIRC_STL_SGI_3_0 +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG +template +struct __deque_iterator; +template inline +Iterator_tag +query_circulator_or_iterator( const __deque_iterator&){ + return Iterator_tag(); +} +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ +template +struct __deque_iterator; +template inline +Iterator_tag +query_circulator_or_iterator( const __deque_iterator&){ + return Iterator_tag(); +} +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +template +struct __hashtable_iterator; +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const __hashtable_iterator&){ + return Iterator_tag(); +} +template +struct __hashtable_const_iterator; +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const __hashtable_const_iterator&){ + return Iterator_tag(); +} + +template +struct __list_iterator; +template< class T, class Ref, class Ptr> inline +Iterator_tag +query_circulator_or_iterator( const __list_iterator&){ + return Iterator_tag(); +} + +template class __rope_iterator; +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( const __rope_iterator&){ + return Iterator_tag(); +} +template class __rope_const_iterator; +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( const __rope_const_iterator&){ + return Iterator_tag(); +} + +template +struct __slist_iterator; +template< class T, class Ref, class Ptr> inline +Iterator_tag +query_circulator_or_iterator( const __slist_iterator&){ + return Iterator_tag(); +} + +template +struct __rb_tree_iterator; +template< class V, class Ref, class Ptr> inline +Iterator_tag +query_circulator_or_iterator( const __rb_tree_iterator&) { + return Iterator_tag(); +} +# endif // CGAL__CIRC_STL_SGI_3_0 // +# ifdef CGAL__CIRC_STL_SGI_JUNE_1997 +#ifndef __STL_NON_TYPE_TMPL_PARAM_BUG +template +struct __deque_iterator; +template inline +Iterator_tag +query_circulator_or_iterator( const __deque_iterator&){ + return Iterator_tag(); +} +#else /* __STL_NON_TYPE_TMPL_PARAM_BUG */ +template +struct __deque_iterator; +template inline +Iterator_tag +query_circulator_or_iterator( const __deque_iterator&){ + return Iterator_tag(); +} +#endif /* __STL_NON_TYPE_TMPL_PARAM_BUG */ + +template +struct __hashtable_iterator; +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const __hashtable_iterator&){ + return Iterator_tag(); +} +template +struct __hashtable_const_iterator; +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const __hashtable_const_iterator&){ + return Iterator_tag(); +} + +template +struct __list_iterator; +template< class T, class Ref> inline +Iterator_tag +query_circulator_or_iterator( const __list_iterator&){ + return Iterator_tag(); +} + +template class __rope_iterator; +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( const __rope_iterator&){ + return Iterator_tag(); +} +template class __rope_const_iterator; +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( const __rope_const_iterator&){ + return Iterator_tag(); +} + +template +struct __slist_iterator; +template< class T, class Ref> inline +Iterator_tag +query_circulator_or_iterator( const __slist_iterator&){ + return Iterator_tag(); +} + +template +struct __rb_tree_iterator; +template< class V, class Ref> inline +Iterator_tag +query_circulator_or_iterator( const __rb_tree_iterator&) { + return Iterator_tag(); +} +# endif // CGAL__CIRC_STL_SGI_JUNE_1997 // +# ifdef CGAL__CIRC_STL_SGI_WWW_1996 +template +struct __deque_iterator; +template inline +Iterator_tag +query_circulator_or_iterator( const __deque_iterator&){ + return Iterator_tag(); +} +template +struct __deque_const_iterator; +template inline +Iterator_tag +query_circulator_or_iterator( const __deque_const_iterator&){ + return Iterator_tag(); +} + +template +struct __hashtable_iterator; +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const __hashtable_iterator&){ + return Iterator_tag(); +} +template +struct __hashtable_const_iterator; +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const __hashtable_const_iterator&){ + return Iterator_tag(); +} + +template +struct __list_iterator; +template< class T> inline +Iterator_tag +query_circulator_or_iterator( const __list_iterator&){ + return Iterator_tag(); +} +template +struct __list_const_iterator; +template< class T> inline +Iterator_tag +query_circulator_or_iterator( const __list_const_iterator&){ + return Iterator_tag(); +} + +template +struct __rb_tree_iterator; +template< class V> inline +Iterator_tag +query_circulator_or_iterator( const __rb_tree_iterator&) { + return Iterator_tag(); +} +template +struct __rb_tree_const_iterator; +template< class V> inline +Iterator_tag +query_circulator_or_iterator( const __rb_tree_const_iterator&) { + return Iterator_tag(); +} +# endif // CGAL__CIRC_STL_SGI_WWW_1996 // +# ifdef CGAL__CIRC_STL_SGI_CC_1996 +#ifdef DEQUE_H +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator(const typename deque::iterator&){ + return Iterator_tag(); +} +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( + const typename deque::const_iterator&){ + return Iterator_tag(); +} +#endif // DEQUE_H // + +#if defined(SGI_STL_HASHTABLE_H) +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const typename hashtable::iterator&){ + return Iterator_tag(); +} +template< class V, class K, class HF, class ExK, class EqK, class All> +inline +Iterator_tag +query_circulator_or_iterator( + const typename hashtable::const_iterator&){ + return Iterator_tag(); +} +#endif // SGI_STL_HASHTABLE_H // + +#ifdef LIST_H +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator(const typename std::list::iterator&){ + return Iterator_tag(); +} +template< class T, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( + const typename std::list::const_iterator&){ + return Iterator_tag(); +} +#endif // LIST_H // + +#if defined(TREE_H) +template< class K, class V, class KoV, class Cmp, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( + const typename rb_tree::iterator&){ + return Iterator_tag(); +} +template< class K, class V, class KoV, class Cmp, class Alloc> inline +Iterator_tag +query_circulator_or_iterator( + const typename rb_tree::const_iterator&){ + return Iterator_tag(); +} +#endif // TREE_H // +# endif // CGAL__CIRC_STL_SGI_CC_1996 // +# endif // CGAL__CIRC_STL_ITERATOR_TRAITS // +/* A function that asserts a specific compile time tag */ +/* forcing its two arguments to have equal type. */ +/* It is encapsulated with #ifdef since it will be defined also elsewhere. */ +#ifndef CGAL_ASSERT_COMPILE_TIME_TAG +#define CGAL_ASSERT_COMPILE_TIME_TAG 1 +template +struct _Assert_tag_class { + void match_compile_time_tag( const Base&) const {} +}; +template< class Tag, class Derived> +inline void Assert_compile_time_tag( const Tag&, const Derived& b) { + _Assert_tag_class x; + x.match_compile_time_tag(b); +} +#endif + +template inline +void Assert_circulator( const C &c) { + Assert_compile_time_tag(Circulator_tag(), query_circulator_or_iterator(c)); +} +template inline +void Assert_iterator( const I &i) { + Assert_compile_time_tag( Iterator_tag(), query_circulator_or_iterator(i)); +} +template inline +void Assert_input_category( const I &i) { + Assert_compile_time_tag( std::input_iterator_tag(), + std::iterator_category(i)); +} +template inline +void Assert_output_category( const I &i) { + Assert_compile_time_tag( std::output_iterator_tag(), + std::iterator_category(i)); +} +template inline +void Assert_forward_category( const IC &ic) { + Assert_compile_time_tag( std::forward_iterator_tag(), + std::iterator_category(ic)); +} +template inline +void Assert_bidirectional_category( const IC &ic) { + Assert_compile_time_tag( std::bidirectional_iterator_tag(), + std::iterator_category(ic)); +} +template inline +void Assert_random_access_category( const IC &ic) { + Assert_compile_time_tag( std::random_access_iterator_tag(), + std::iterator_category(ic)); +} + +// The assert at-least-category functions use the following +// functions to resolve properly. Note the proper order of the +// arguments: 1st is the to be type, 2nd is the actual type. +inline void _Has_to_be_at_least( std::input_iterator_tag, + std::input_iterator_tag){} +inline void _Has_to_be_at_least( std::input_iterator_tag, + std::forward_iterator_tag){} +inline void _Has_to_be_at_least( std::input_iterator_tag, + std::bidirectional_iterator_tag){} +inline void _Has_to_be_at_least( std::input_iterator_tag, + std::random_access_iterator_tag){} + +inline void _Has_to_be_at_least( std::output_iterator_tag, + std::output_iterator_tag){} +inline void _Has_to_be_at_least( std::output_iterator_tag, + std::forward_iterator_tag){} +inline void _Has_to_be_at_least( std::output_iterator_tag, + std::bidirectional_iterator_tag){} +inline void _Has_to_be_at_least( std::output_iterator_tag, + std::random_access_iterator_tag){} + +inline void _Has_to_be_at_least( std::forward_iterator_tag, + std::forward_iterator_tag){} +inline void _Has_to_be_at_least( std::forward_iterator_tag, + std::bidirectional_iterator_tag){} +inline void _Has_to_be_at_least( std::forward_iterator_tag, + std::random_access_iterator_tag){} + +inline void _Has_to_be_at_least( std::bidirectional_iterator_tag, + std::bidirectional_iterator_tag){} +inline void _Has_to_be_at_least( std::bidirectional_iterator_tag, + std::random_access_iterator_tag){} + +inline void _Has_to_be_at_least( std::random_access_iterator_tag, + std::random_access_iterator_tag){} + +// The is-at-least assertions. +template inline +void Assert_is_at_least_input_category( const I& i) { + _Has_to_be_at_least(std::input_iterator_tag(), std::iterator_category(i)); +} +template inline +void Assert_is_at_least_output_category( const I& i) { + _Has_to_be_at_least(std::output_iterator_tag(), + std::iterator_category(i)); +} +template inline +void Assert_is_at_least_forward_category( const IC& ic) { + _Has_to_be_at_least(std::forward_iterator_tag(), + std::iterator_category(ic)); +} +template inline +void Assert_is_at_least_bidirectional_category( const IC& ic) { + _Has_to_be_at_least(std::bidirectional_iterator_tag(), + std::iterator_category(ic)) ; +} +template inline +void Assert_is_at_least_random_access_category( const IC& ic) { + _Has_to_be_at_least(std::random_access_iterator_tag(), + std::iterator_category(ic)); +} + +template< class C> inline +bool _is_empty_range( const C& c1, const C&, Circulator_tag){ + return c1 == CGAL_CIRC_NULL; +} + +template< class I> inline +bool _is_empty_range( const I& i1, const I& i2, Iterator_tag){ + return i1 == i2; +} + +template< class IC> inline +bool is_empty_range( const IC& ic1, const IC& ic2){ + // is `true' if the range [`ic1, ic2') is empty, `false' otherwise. + // Precondition: `T' is either a circulator or an iterator type. The + // range [`ic1, ic2') is valid. + return _is_empty_range( ic1, ic2, query_circulator_or_iterator( ic1)); +} + +struct Circulator_or_iterator_tag {}; // any circulator or iterator. + +inline +Circulator_or_iterator_tag +check_circulator_or_iterator( Circulator_tag ){ + return Circulator_or_iterator_tag(); +} +inline +Circulator_or_iterator_tag +check_circulator_or_iterator( Iterator_tag ){ + return Circulator_or_iterator_tag(); +} + +template< class IC> inline +void Assert_circulator_or_iterator( const IC &ic){ + Assert_compile_time_tag( + Circulator_or_iterator_tag(), + check_circulator_or_iterator( + query_circulator_or_iterator( ic) + ) + ); +} + +#define CGAL_For_all( ic1, ic2) \ + for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range( ic1, ic2); \ + _circ_loop_flag; \ + _circ_loop_flag = ((++ic1) != (ic2)) ) + +#define CGAL_For_all_backwards( ic1, ic2) \ + for ( bool _circ_loop_flag = ! ::CGAL::is_empty_range( ic1, ic2); \ + _circ_loop_flag; \ + _circ_loop_flag = ((ic1) != (--ic2)) ) + +// Note: these macros are superfluous now. See the more natural macros above. +// (Note that the macros below avoids problems with dangling else's.) +#define CGAL__For_all_old( ic1, ic2, body) \ + if ( ::CGAL::is_empty_range( ic1, ic2)); \ + else { \ + do \ + body \ + while ((++ic1) != (ic2)); \ + } +#define CGAL__For_all_backwards_old( ic1, ic2, body) \ + if ( ::CGAL::is_empty_range( ic1, ic2)); \ + else { \ + do \ + body \ + while ((ic1) != (--ic2)); \ + } + +template +class Size_type_return_value_proxy { +public: + typedef typename T::size_type size_type; + size_type x; + Size_type_return_value_proxy( size_type _x) : x(_x) {} + operator size_type() const { return x; } +}; + +template inline +Size_type_return_value_proxy +_min_circulator_size( const C& c) { + Assert_circulator(c); + Assert_random_access_category(c); + typedef typename C::size_type size_type; + size_type n = 0; + if ( c != CGAL_CIRC_NULL) { + n = (c-1) - c + 1; + CGAL_assertion(n > 0); + } + return n; +} + +template +Size_type_return_value_proxy +_circulator_size( const C& c, Forward_circulator_tag) { + // Simply count. + if ( c == CGAL_CIRC_NULL) + return 0; + typedef typename C::size_type size_type; + size_type n = 0; + C d = c; + do { + ++n; + ++d; + } while( c != d); + return n; +} +template inline +Size_type_return_value_proxy +_circulator_size(const C& c, Bidirectional_circulator_tag) { + return _circulator_size( c, Forward_circulator_tag()); +} +template inline +Size_type_return_value_proxy +_circulator_size(const C& c, Random_access_circulator_tag) { + return _min_circulator_size( c.min_circulator()); +} + +template inline +Size_type_return_value_proxy +circulator_size(const C& c) { + return _circulator_size( c, std::iterator_category(c)); +} +template +class Difference_type_return_value_proxy { +public: + typedef typename T::difference_type difference_type; + difference_type x; + Difference_type_return_value_proxy( difference_type _x) : x(_x) {} + operator difference_type() const { return x; } +}; + +template +Difference_type_return_value_proxy +_circulator_distance( C c, const C& d, Forward_circulator_tag) { + // Simply count. + if ( c == CGAL_CIRC_NULL) + return 0; + typedef typename C::difference_type difference_type; + difference_type n = 0; + do { + ++n; + } while( ++c != d); + return n; +} +template inline +Difference_type_return_value_proxy +_circulator_distance(const C& c, const C& d, Bidirectional_circulator_tag){ + return _circulator_distance( c, d, Forward_circulator_tag()); +} +template inline +Difference_type_return_value_proxy +_circulator_distance(const C& c, const C& d, Random_access_circulator_tag){ + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + if ( d - c > 0) + return (d - c); + return difference_type(size_type(_min_circulator_size( + c.min_circulator()))) - (c-d); +} + +template inline +Difference_type_return_value_proxy +circulator_distance(const C& c, const C& d) { + return _circulator_distance( c, d, std::iterator_category(c)); +} +template inline +#ifdef CGAL_CFG_NO_ITERATOR_TRAITS +std::ptrdiff_t +#else // CGAL_CFG_NO_ITERATOR_TRAITS // +typename std::iterator_traits::difference_type +#endif // CGAL_CFG_NO_ITERATOR_TRAITS // +_iterator_distance(const C& c1, const C& c2, Circulator_tag) { + return circulator_distance( c1, c2); +} + +template inline +#ifdef CGAL_CFG_NO_ITERATOR_TRAITS +std::ptrdiff_t +#else // CGAL_CFG_NO_ITERATOR_TRAITS // +typename std::iterator_traits::difference_type +#endif // CGAL_CFG_NO_ITERATOR_TRAITS // +_iterator_distance(const I& i1, const I& i2, Iterator_tag) { + #ifdef CGAL_CFG_NO_ITERATOR_TRAITS + std::ptrdiff_t dist = 0; + std::distance( i1, i2, dist); + return dist; + #else + return std::distance( i1, i2); + #endif // CGAL_CFG_NO_ITERATOR_TRAITS // +} + +template inline +#ifdef CGAL_CFG_NO_ITERATOR_TRAITS +std::ptrdiff_t +#else // CGAL_CFG_NO_ITERATOR_TRAITS // +typename std::iterator_traits::difference_type +#endif // CGAL_CFG_NO_ITERATOR_TRAITS // +iterator_distance(const IC& ic1, const IC& ic2) { + return _iterator_distance( ic1, ic2, + query_circulator_or_iterator(ic1)); +} +template inline +C _get_min_circulator( C c, Forward_circulator_tag) { return c; } +template inline +C _get_min_circulator( C c, Bidirectional_circulator_tag) { return c; } +template inline +C _get_min_circulator( C c, Random_access_circulator_tag) { + return c.min_circulator(); +} +template inline +C get_min_circulator( C c) { + return _get_min_circulator( c, std::iterator_category(c)); +} +template inline +I non_negative_mod(I n, U m) { + CGAL_assertion( m > 0); + #if (-1 % 3) > 0 + n = n % m; + #else + if (n < 0) + n = - (( - n - 1) % m) + m - 1; + else + n = n % m; + #endif + CGAL_assertion( n >= 0); + return n; +} + +template < class C, class Ref, class Ptr> +class Forward_iterator_from_circulator { +private: + const C* anchor; + C current; + int winding; +public: +// +// TYPES + + typedef C Circulator; + typedef Forward_iterator_from_circulator Self; + typedef std::forward_iterator_tag iterator_category; + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef Ref reference; + typedef Ptr pointer; + +// +// CREATION + + Forward_iterator_from_circulator() : anchor(0), winding(0) {} + + Forward_iterator_from_circulator( const C* circ, int n) + : anchor( circ), current( *circ), winding(n) {} + +// +// OPERATIONS + + bool operator==( const Self& i) const { + CGAL_assertion( anchor == i.anchor); // same anchor? + return ( current == i.current) && ( winding == i.winding); + } + bool operator!=( const Self& i) const { + return !(*this == i); + } + Ref operator*() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ref(*current); + } + Ptr operator->() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ptr(current.operator->()); + } + Self& operator++() { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( current == *anchor) + ++winding; + ++current; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + Circulator current_circulator() const { return current;} +}; + +template < class C, class Ref, class Ptr> +class Bidirectional_iterator_from_circulator { +private: + const C* anchor; + C current; + int winding; +public: +// +// TYPES + + typedef C Circulator; + typedef Bidirectional_iterator_from_circulator Self; + typedef std::bidirectional_iterator_tag iterator_category; + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef Ref reference; + typedef Ptr pointer; + +// +// CREATION + + Bidirectional_iterator_from_circulator() : anchor(0), winding(0) {} + + Bidirectional_iterator_from_circulator( const C* circ, int n) + : anchor( circ), current( *circ), winding(n) {} + +// +// OPERATIONS + + bool operator==( const Self& i) const { + CGAL_assertion( anchor == i.anchor); // same anchor? + return ( current == i.current) && ( winding == i.winding); + } + bool operator!=( const Self& i) const { + return !(*this == i); + } + Ref operator*() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ref(*current); + } + Ptr operator->() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ptr(current.operator->()); + } + Self& operator++() { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( current == *anchor) + ++winding; + ++current; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + + Self& operator--() { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + --current; + if ( current == *anchor) + --winding; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + Circulator current_circulator() const { return current;} +}; + +template < class C, class Ref, class Ptr> +class Random_access_iterator_from_circulator { +private: + // The anchor is normalized to be a minimal circulator. + const C* anchor; + C current; + int winding; +public: +// +// TYPES + + typedef C Circulator; + typedef Random_access_iterator_from_circulator Self; + typedef std::random_access_iterator_tag iterator_category; + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef Ref reference; + typedef Ptr pointer; + +// +// CREATION + + Random_access_iterator_from_circulator() : anchor(0), winding(0) {} + + Random_access_iterator_from_circulator( const C* circ, int n) + : anchor( circ), current( *circ), winding(n) {} + +// +// OPERATIONS + + bool operator==( const Self& i) const { + CGAL_assertion( anchor == i.anchor); // same anchor? + return ( current == i.current) && ( winding == i.winding); + } + bool operator!=( const Self& i) const { + return !(*this == i); + } + Ref operator*() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ref(*current); + } + Ptr operator->() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ptr(current.operator->()); + } + Self& operator++() { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + ++current; + if ( current == *anchor) + ++winding; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + + Self& operator--() { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( current == *anchor) + --winding; + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + + Self& operator+=( typename C::difference_type n) { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( n < 0 && current == *anchor) // We are leaving the anchor. + --winding; + current += n; + if ( n > 0 && current == *anchor) // Back again at the anchor. + ++winding; + return *this; + } + Self operator+( typename C::difference_type n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( typename C::difference_type n) { + return operator+=( -n); + } + Self operator-( typename C::difference_type n) const { + Self tmp = *this; + return tmp += -n; + } + typename C::difference_type operator-( const Self& i) const; + + Ref operator[](typename C::difference_type n) const { + Self tmp = *this; + tmp += n; + return tmp.operator*(); + } + bool operator<( const Self& i) const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + CGAL_assertion( anchor == i.anchor); + return ( (winding < i.winding) + || ( (winding == i.winding) + && (current - *anchor) < (i.current - *anchor) + ) + ); + } + bool operator>( const Self& i) const { + return i < *this; + } + bool operator<=( const Self& i) const { + return !(i < *this); + } + bool operator>=( const Self& i) const { + return !(*this < i); + } + Circulator current_circulator() const { return current;} +}; + +template < class Dist, class C, class Ref, class Ptr> +Random_access_iterator_from_circulator +operator+( Dist n, + const Random_access_iterator_from_circulator& + circ) { + Random_access_iterator_from_circulator tmp = circ; + return tmp += n; +} + +template < class C, class Ref, class Ptr> +typename C::difference_type +Random_access_iterator_from_circulator:: +operator-( const Random_access_iterator_from_circulator& + i) const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + CGAL_assertion( anchor == i.anchor); + if ( winding != i.winding) { + typename C::difference_type s = _min_circulator_size( *anchor); + return (current - *anchor) - (i.current - *anchor) + + s * (winding - i.winding); + } + return (current - *anchor) - (i.current - *anchor); +} + + +template < class C > +class Forward_container_from_circulator { +private: + C anchor; +public: + +// DEFINITION +// +// The adaptor Forward_container_from_circulator is a class that +// converts any circulator type `C' to a kind of containerclass, i.e. a +// class that provides an iterator and a const iterator type and two +// member functions -- begin() and end() -- that return the appropriate +// forward iterators. In 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. +// +// For Forward_container_from_circulator the circulator has to +// fulfill at least the requirements for a forward circulator. The similar +// adaptor `Bidirectional_container_from_circulator' requires a +// bidirectional circulator to provide bidirectional iterators and the +// adaptor `Random_access_container_from_circulator' requires a +// random access circulator to provide random access iterators. In this +// case the adaptor implements a total ordering relation that is currently +// not required for random access circulators. The total order is based on +// the difference value from all circulators to the circulator given at +// construction time. The difference value is a consistent ordering as +// stated in the requirements for random access circulators. +// +// PARAMETERS +// +// `C' is the appropriate circulator type. +// +// CREATION +// +// New creation variable is: `adaptor' + + Forward_container_from_circulator() {} + // the resulting iterators will have a singular value. + + Forward_container_from_circulator(const C& c) : anchor(c) {} + // the resulting iterators will have a singular value if the + // circulator `c' is singular. + +// +// TYPES + +typedef C Circulator; + +typedef typename C::value_type value_type; +typedef typename C::difference_type difference_type; +typedef typename C::size_type size_type; +typedef value_type& reference; +typedef const value_type& const_reference; +typedef value_type* pointer; +typedef const value_type* const_pointer; + +typedef Forward_iterator_from_circulator + iterator; +typedef Forward_iterator_from_circulator const_iterator; + +// +// OPERATIONS + + iterator begin() { + // the start iterator. + return iterator( &anchor, 0); + } + + const_iterator begin() const { + // the start const iterator. + return const_iterator( &anchor, 0); + } + + iterator end() { + // the past-the-end iterator. + return anchor == CGAL_CIRC_NULL ? iterator( &anchor, 0) + : iterator( &anchor, 1); + } + const_iterator end() const { + // the past-the-end const iterator. + return anchor == CGAL_CIRC_NULL ? const_iterator( &anchor, 0) + : const_iterator( &anchor, 1); + } + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline difference_type* distance_type(const iterator&) { + return (difference_type*)(0); + } + friend inline value_type* value_type(const iterator&) { + return (value_type*)(0); + } + friend inline std::forward_iterator_tag + iterator_category(iterator) { + return std::forward_iterator_tag(); + } + friend inline CGAL_Iterator_tag + CGAL_query_circulator_or_iterator(iterator) { + return CGAL_Iterator_tag(); + } + + friend inline difference_type* distance_type(const const_iterator&) { + return (difference_type*)(0); + } + friend inline value_type* value_type(const const_iterator&) { + return (value_type*)(0); + } + friend inline std::forward_iterator_tag + iterator_category(const_iterator) { + return std::forward_iterator_tag(); + } + friend inline CGAL_Iterator_tag + CGAL_query_circulator_or_iterator( const_iterator) { + return CGAL_Iterator_tag(); + } + #endif +}; + + +template < class C > +class Bidirectional_container_from_circulator { +private: + C anchor; +public: +// +// CREATION + + Bidirectional_container_from_circulator() {} + // the resulting iterators will have a singular value. + + Bidirectional_container_from_circulator(const C& c) : anchor(c) {} + // the resulting iterators will have a singular value if the + // circulator `c' is singular. + +// +// TYPES + +typedef C Circulator; + +typedef typename C::value_type value_type; +typedef typename C::difference_type difference_type; +typedef typename C::size_type size_type; +typedef value_type& reference; +typedef const value_type& const_reference; +typedef value_type* pointer; +typedef const value_type* const_pointer; + +typedef Bidirectional_iterator_from_circulator + iterator; +typedef Bidirectional_iterator_from_circulator const_iterator; + +// +// OPERATIONS + + iterator begin() { + // the start iterator. + return iterator( &anchor, 0); + } + + const_iterator begin() const { + // the start const iterator. + return const_iterator( &anchor, 0); + } + + iterator end() { + // the past-the-end iterator. + return anchor == CGAL_CIRC_NULL ? iterator( &anchor, 0) + : iterator( &anchor, 1); + } + const_iterator end() const { + // the past-the-end const iterator. + return anchor == CGAL_CIRC_NULL ? const_iterator( &anchor, 0) + : const_iterator( &anchor, 1); + } + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline difference_type* distance_type(const iterator&) { + return (difference_type*)(0); + } + friend inline value_type* value_type(const iterator&) { + return (value_type*)(0); + } + friend inline std::bidirectional_iterator_tag + iterator_category(iterator) { + return std::bidirectional_iterator_tag(); + } + friend inline CGAL_Iterator_tag + CGAL_query_circulator_or_iterator(iterator) { + return CGAL_Iterator_tag(); + } + + friend inline difference_type* distance_type(const const_iterator&) { + return (difference_type*)(0); + } + friend inline value_type* value_type(const const_iterator&) { + return (value_type*)(0); + } + friend inline std::bidirectional_iterator_tag + iterator_category(const_iterator) { + return std::bidirectional_iterator_tag(); + } + friend inline CGAL_Iterator_tag + CGAL_query_circulator_or_iterator( const_iterator) { + return CGAL_Iterator_tag(); + } + #endif +}; + + +template < class C > +class Random_access_container_from_circulator { +private: + C anchor; +public: +// +// CREATION + + Random_access_container_from_circulator() {} + // the resulting iterators will have a singular value. + + Random_access_container_from_circulator(const C& c) + // The anchor is normalized to be a minimal circulator. + : anchor(c.min_circulator()) {} + // the resulting iterators will have a singular value if the + // circulator `c' is singular. + +// +// TYPES + +typedef C Circulator; + +typedef typename C::value_type value_type; +typedef typename C::difference_type difference_type; +typedef typename C::size_type size_type; +typedef value_type& reference; +typedef const value_type& const_reference; +typedef value_type* pointer; +typedef const value_type* const_pointer; + +typedef Random_access_iterator_from_circulator + iterator; +typedef Random_access_iterator_from_circulator const_iterator; + +// +// OPERATIONS + + iterator begin() { + // the start iterator. + return iterator( &anchor, 0); + } + + const_iterator begin() const { + // the start const iterator. + return const_iterator( &anchor, 0); + } + + iterator end() { + // the past-the-end iterator. + return anchor == CGAL_CIRC_NULL ? iterator( &anchor, 0) + : iterator( &anchor, 1); + } + const_iterator end() const { + // the past-the-end const iterator. + return anchor == CGAL_CIRC_NULL ? const_iterator( &anchor, 0) + : const_iterator( &anchor, 1); + } + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline difference_type* distance_type(const iterator&) { + return (difference_type*)(0); + } + friend inline value_type* value_type(const iterator&) { + return (value_type*)(0); + } + friend inline std::random_access_iterator_tag + iterator_category(iterator) { + return std::random_access_iterator_tag(); + } + friend inline CGAL_Iterator_tag + CGAL_query_circulator_or_iterator(iterator) { + return CGAL_Iterator_tag(); + } + + friend inline difference_type* distance_type(const const_iterator&) { + return (difference_type*)(0); + } + friend inline value_type* value_type(const const_iterator&) { + return (value_type*)(0); + } + friend inline std::random_access_iterator_tag + iterator_category(const_iterator) { + return std::random_access_iterator_tag(); + } + friend inline CGAL_Iterator_tag + CGAL_query_circulator_or_iterator( const_iterator) { + return CGAL_Iterator_tag(); + } + #endif +}; + +#ifdef CGAL__CIRC_STL_ITERATOR_TRAITS + +template < class C, class Ref, class Ptr> +class Iterator_from_circulator { +private: + // The anchor is normalized to be a minimal circulator. + const C* anchor; + C current; + int winding; + + typedef std::iterator_traits Itraits; + typedef typename Itraits::iterator_category Iter_cat; + typedef _Iterator_from_circulator_traits ICtraits; + +public: +// +// TYPES + + typedef C Circulator; + typedef Iterator_from_circulator Self; + + typedef typename ICtraits::iterator_category iterator_category; + + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + typedef typename C::reference reference; + typedef typename C::pointer pointer; + +// +// CREATION + + Iterator_from_circulator() : anchor(0), winding(0) {} + + Iterator_from_circulator( const C* circ, int n) + : anchor( circ), current( *circ), winding(n) {} + +// +// OPERATIONS + + bool operator==( const Self& i) const { + CGAL_assertion( anchor == i.anchor); // same anchor? + return ( current == i.current) && ( winding == i.winding); + } + bool operator!=( const Self& i) const { + return !(*this == i); + } + Ref operator*() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ref(*current); + } + Ptr operator->() const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + return Ptr(current.operator->()); + } + Self& operator++() { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + ++current; + if ( current == *anchor) + ++winding; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( current == *anchor) + --winding; + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + Self& operator+=( difference_type n) { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + if ( n < 0 && current == *anchor) // We are leaving the anchor. + --winding; + current += n; + if ( n > 0 && current == *anchor) // Back again at the anchor. + ++winding; + return *this; + } + Self operator+( difference_type n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( difference_type n) { + return operator+=( -n); + } + Self operator-( difference_type n) const { + Self tmp = *this; + return tmp += -n; + } + difference_type operator-( const Self& i) const; + + Ref operator[](difference_type n) const { + Self tmp = *this; + tmp += n; + return tmp.operator*(); + } + bool operator<( const Self& i) const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + CGAL_assertion( anchor == i.anchor); + return ( (winding < i.winding) + || ( (winding == i.winding) + && (current - *anchor) < (i.current - *anchor) + ) + ); + } + bool operator>( const Self& i) const { + return i < *this; + } + bool operator<=( const Self& i) const { + return !(i < *this); + } + bool operator>=( const Self& i) const { + return !(*this < i); + } + Circulator current_circulator() const { return current;} +}; + +template < class Dist, class C, class Ref, class Ptr> +Iterator_from_circulator +operator+( Dist n, + const Iterator_from_circulator& circ) { + Iterator_from_circulator tmp = circ; + return tmp += n; +} + +template < class C, class Ref, class Ptr> +typename C::difference_type +Iterator_from_circulator:: +operator-( const Iterator_from_circulator& i) const { + CGAL_assertion( anchor != CGAL_CIRC_NULL); + CGAL_assertion( current != CGAL_CIRC_NULL); + CGAL_assertion( anchor == i.anchor); + if ( winding != i.winding) { + difference_type s = _min_circulator_size( *anchor); + return (current - *anchor) - (i.current - *anchor) + + s * (winding - i.winding); + } + return (current - *anchor) - (i.current - *anchor); +} + + +template < class C > +class Container_from_circulator { +private: + C anchor; +public: +// +// CREATION + + Container_from_circulator() {} + // the resulting iterators will have a singular value. + + Container_from_circulator(const C& c) + // The anchor is normalized to be a minimal circulator. + : anchor(get_min_circulator(c)) {} + // the resulting iterators will have a singular value if the + // circulator `c' is singular. + +// +// TYPES + +typedef C Circulator; + +typedef typename C::value_type value_type; +typedef value_type& reference; +typedef const value_type& const_reference; +typedef value_type* pointer; +typedef const value_type* const_pointer; +typedef typename C::size_type size_type; +typedef typename C::difference_type difference_type; + +typedef Iterator_from_circulator< C, reference, pointer> + iterator; +typedef Iterator_from_circulator< C, const_reference, const_pointer> + const_iterator; +// +// OPERATIONS + + iterator begin() { + // the start iterator. + return iterator( &anchor, 0); + } + + const_iterator begin() const { + // the start const iterator. + return const_iterator( &anchor, 0); + } + + iterator end() { + // the past-the-end iterator. + return anchor == CGAL_CIRC_NULL ? iterator( &anchor, 0) + : iterator( &anchor, 1); + } + const_iterator end() const { + // the past-the-end const iterator. + return anchor == CGAL_CIRC_NULL ? const_iterator( &anchor, 0) + : const_iterator( &anchor, 1); + } +}; +#endif // CGAL__CIRC_STL_ITERATOR_TRAITS // +template < class C> +class Forward_circulator_from_container + : public Forward_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type> { +private: + typename C::iterator i; +public: + +// DEFINITION +// +// The adaptor Forward_circulator_from_container is a class that +// provides a forward circulator for a container C as specified by the +// STL. The iterators belonging to the container C are supposed to be at +// least forward iterators. The adaptor for bidirectional circulators is +// `Bidirectional_circulator_from_container' and +// `Random_access_circulator_from_container' for random access +// circulators. Appropriate const circulators are also available. +// +// PARAMETERS +// +// `C' is the container type. The container is supposed to conform to the +// STL requirements for container (i.e. to have a `begin()' and an `end()' +// iterator as well as the local types `value_type', `size_type()', and +// `difference_type'). +// +// CREATION + + Forward_circulator_from_container() {} + + Forward_circulator_from_container( C* c) + : Forward_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>(c), + i(c->begin()) {} + + Forward_circulator_from_container( C* c, typename C::iterator _i) + : Forward_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>(c), + i(_i) {} + +// +// TYPES + + typedef C Container; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::value_type value_type; + typedef typename C::reference reference; + typedef value_type* pointer; + typedef typename C::size_type size_type; + typedef typename C::difference_type difference_type; + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (_ptr == NULL) + || (((C*)_ptr)->begin()==((C*)_ptr)->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Forward_circulator_from_container + & c) const { + return i == c.i; + } + bool operator!=( const Forward_circulator_from_container + & c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + return &(*i); + } + Forward_circulator_from_container& + operator++() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + ++i; + if ( i == ((C*)_ptr)->end()) + i = ((C*)_ptr)->begin(); + return *this; + } + Forward_circulator_from_container + operator++(int) { + Forward_circulator_from_container tmp= *this; + ++*this; + return tmp; + } + iterator current_iterator() const { return i;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline typename C::difference_type* distance_type( + const + Forward_circulator_from_container&) { + return (typename C::difference_type*)(0); + } + friend inline typename C::value_type* value_type( + const + Forward_circulator_from_container&) { + return (typename C::value_type*)(0); + } + friend inline Forward_circulator_tag iterator_category( + Forward_circulator_from_container) { + return Forward_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Forward_circulator_from_container) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class C> +class Forward_const_circulator_from_container + : public Forward_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type> { +private: + typename C::const_iterator i; +public: +// +// CREATION + + Forward_const_circulator_from_container() {} + + Forward_const_circulator_from_container( const C* c) + : Forward_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>((void*)c), i(c->begin()) {} + + Forward_const_circulator_from_container( const C* c, + typename C::const_iterator _i) + : Forward_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>((void*)c), + i(_i) {} + +// +// TYPES + + typedef C Container; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::value_type value_type; + typedef typename C::const_reference reference; + typedef const value_type* pointer; + typedef typename C::size_type size_type; + typedef typename C::difference_type difference_type; + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (_ptr == NULL) + || (((const C*)_ptr)->begin() + ==((const C*)_ptr)->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( + const Forward_const_circulator_from_container + & c) const { + return i == c.i; + } + bool operator!=( const Forward_const_circulator_from_container + & c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + return &(*i); + } + Forward_const_circulator_from_container& + operator++() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + ++i; + if ( i == ((const C*)_ptr)->end()) + i = ((const C*)_ptr)->begin(); + return *this; + } + Forward_const_circulator_from_container + operator++(int) { + Forward_const_circulator_from_container + tmp= *this; + ++*this; + return tmp; + } + const_iterator current_iterator() const { return i;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline typename C::difference_type* distance_type( + const + Forward_const_circulator_from_container&) { + return (typename C::difference_type*)(0); + } + friend inline typename C::value_type* value_type( + const + Forward_const_circulator_from_container&) { + return (typename C::value_type*)(0); + } + friend inline Forward_circulator_tag iterator_category( + Forward_const_circulator_from_container) { + return Forward_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Forward_const_circulator_from_container) { + return CGAL_Circulator_tag(); + } + #endif +}; + + +template < class C> +class Bidirectional_circulator_from_container + : public Bidirectional_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type> { +private: + typename C::iterator i; +public: +// +// CREATION + + Bidirectional_circulator_from_container() {} + + Bidirectional_circulator_from_container( C* c) + : Bidirectional_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>(c), + i(c->begin()) {} + + Bidirectional_circulator_from_container( C* c, + typename C::iterator _i) + : Bidirectional_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>(c), + i(_i) {} + +// +// TYPES + + typedef C Container; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::value_type value_type; + typedef typename C::reference reference; + typedef value_type* pointer; + typedef typename C::size_type size_type; + typedef typename C::difference_type difference_type; + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (_ptr == NULL) + || (((C*)_ptr)->begin()==((C*)_ptr)->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Bidirectional_circulator_from_container + & c) const { + return i == c.i; + } + bool operator!=( const Bidirectional_circulator_from_container + & c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + return &(*i); + } + Bidirectional_circulator_from_container& + operator++() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + ++i; + if ( i == ((C*)_ptr)->end()) + i = ((C*)_ptr)->begin(); + return *this; + } + Bidirectional_circulator_from_container + operator++(int) { + Bidirectional_circulator_from_container tmp= *this; + ++*this; + return tmp; + } + Bidirectional_circulator_from_container& + operator--() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + if ( i == ((C*)_ptr)->begin()) + i = ((C*)_ptr)->end(); + --i; + return *this; + } + Bidirectional_circulator_from_container + operator--(int) { + Bidirectional_circulator_from_container tmp = *this; + --*this; + return tmp; + } + iterator current_iterator() const { return i;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline typename C::difference_type* distance_type( + const + Bidirectional_circulator_from_container&) { + return (typename C::difference_type*)(0); + } + friend inline typename C::value_type* value_type( + const + Bidirectional_circulator_from_container&) { + return (typename C::value_type*)(0); + } + friend inline Bidirectional_circulator_tag iterator_category( + Bidirectional_circulator_from_container) { + return Bidirectional_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Bidirectional_circulator_from_container) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class C> +class Bidirectional_const_circulator_from_container + : public Bidirectional_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type> { +private: + typename C::const_iterator i; +public: +// +// CREATION + + Bidirectional_const_circulator_from_container() {} + + Bidirectional_const_circulator_from_container( const C* c) + : Bidirectional_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>((void*)c), i(c->begin()) {} + + Bidirectional_const_circulator_from_container( const C* c, + typename C::const_iterator _i) + : Bidirectional_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>((void*)c), + i(_i) {} + +// +// TYPES + + typedef C Container; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::value_type value_type; + typedef typename C::const_reference reference; + typedef const value_type* pointer; + typedef typename C::size_type size_type; + typedef typename C::difference_type difference_type; + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (_ptr == NULL) + || (((const C*)_ptr)->begin() + ==((const C*)_ptr)->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( + const Bidirectional_const_circulator_from_container + & c) const { + return i == c.i; + } + bool operator!=(const Bidirectional_const_circulator_from_container + & c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + return &(*i); + } + Bidirectional_const_circulator_from_container& + operator++() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + ++i; + if ( i == ((const C*)_ptr)->end()) + i = ((const C*)_ptr)->begin(); + return *this; + } + Bidirectional_const_circulator_from_container + operator++(int) { + Bidirectional_const_circulator_from_container + tmp= *this; + ++*this; + return tmp; + } + Bidirectional_const_circulator_from_container& + operator--() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + if ( i == ((const C*)_ptr)->begin()) + i = ((const C*)_ptr)->end(); + --i; + return *this; + } + Bidirectional_const_circulator_from_container + operator--(int) { + Bidirectional_const_circulator_from_container + tmp = *this; + --*this; + return tmp; + } + const_iterator current_iterator() const { return i;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline typename C::difference_type* distance_type( + const + Bidirectional_const_circulator_from_container&) { + return (typename C::difference_type*)(0); + } + friend inline typename C::value_type* value_type( + const + Bidirectional_const_circulator_from_container&) { + return (typename C::value_type*)(0); + } + friend inline Bidirectional_circulator_tag iterator_category( + Bidirectional_const_circulator_from_container) { + return Bidirectional_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Bidirectional_const_circulator_from_container) { + return CGAL_Circulator_tag(); + } + #endif +}; + + +template < class C> +class Random_access_circulator_from_container + : public Random_access_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type> { +private: + typename C::iterator i; +public: +// +// CREATION + + Random_access_circulator_from_container() {} + + Random_access_circulator_from_container( C* c) + : Random_access_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>(c), + i(c->begin()) {} + + Random_access_circulator_from_container( C* c, + typename C::iterator _i) + : Random_access_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>(c), + i(_i) {} + +// +// TYPES + + typedef C Container; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::value_type value_type; + typedef typename C::reference reference; + typedef value_type* pointer; + typedef typename C::size_type size_type; + typedef typename C::difference_type difference_type; + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (_ptr == NULL) + || (((C*)_ptr)->begin()==((C*)_ptr)->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Random_access_circulator_from_container + & c) const { + return i == c.i; + } + bool operator!=( const Random_access_circulator_from_container + & c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + return &(*i); + } + Random_access_circulator_from_container& + operator++() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + ++i; + if ( i == ((C*)_ptr)->end()) + i = ((C*)_ptr)->begin(); + return *this; + } + Random_access_circulator_from_container + operator++(int) { + Random_access_circulator_from_container tmp= *this; + ++*this; + return tmp; + } + + Random_access_circulator_from_container& + operator--() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + if ( i == ((C*)_ptr)->begin()) + i = ((C*)_ptr)->end(); + --i; + return *this; + } + Random_access_circulator_from_container + operator--(int) { + Random_access_circulator_from_container tmp = *this; + --*this; + return tmp; + } + + Random_access_circulator_from_container& + operator+=( difference_type n); + + Random_access_circulator_from_container + operator+( difference_type n) const { + Random_access_circulator_from_container tmp = *this; + return tmp += n; + } + Random_access_circulator_from_container& + operator-=( difference_type n) { + return operator+=( -n); + } + Random_access_circulator_from_container + operator-( difference_type n) const { + Random_access_circulator_from_container tmp = *this; + return tmp += -n; + } + difference_type + operator-( const Random_access_circulator_from_container< + C>& c) const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( c._ptr != NULL); + return i - c.i; + } + reference operator[](difference_type n) const { + Random_access_circulator_from_container tmp = *this; + tmp += n; + return tmp.operator*(); + } + + friend inline + Random_access_circulator_from_container + operator+( difference_type n, const + Random_access_circulator_from_container& c) { + Random_access_circulator_from_container tmp = c; + return tmp += n; + } + iterator current_iterator() const { return i;} + + Random_access_circulator_from_container + min_circulator() const { + return Random_access_circulator_from_container((C*)_ptr); + } + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline typename C::difference_type* distance_type( + const + Random_access_circulator_from_container&) { + return (typename C::difference_type*)(0); + } + friend inline typename C::value_type* value_type( + const + Random_access_circulator_from_container&) { + return (typename C::value_type*)(0); + } + friend inline Random_access_circulator_tag iterator_category( + Random_access_circulator_from_container) { + return Random_access_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Random_access_circulator_from_container) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class C> +Random_access_circulator_from_container& +Random_access_circulator_from_container:: +operator+=( typename C::difference_type n) { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((C*)_ptr)->end()); + + typename C::difference_type j = i - ((C*)_ptr)->begin(); + typename C::difference_type size = ((C*)_ptr)->size(); + CGAL_assertion( j >= 0); + CGAL_assertion( size >= 0); + j = non_negative_mod( j + n, size); + CGAL_assertion( j >= 0); + CGAL_assertion( j < size); + i = ((C*)_ptr)->begin() + j; + return *this; +} + + +template < class C> +class Random_access_const_circulator_from_container + : public Random_access_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type> { +private: + typename C::const_iterator i; +public: +// +// CREATION + + Random_access_const_circulator_from_container() {} + + Random_access_const_circulator_from_container( const C* c) + : Random_access_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>((void*)c), i(c->begin()) {} + + Random_access_const_circulator_from_container( const C* c, + typename C::const_iterator _i) + : Random_access_circulator_ptrbase< + typename C::value_type, typename C::difference_type, + typename C::size_type>((void*)c), i(_i) {} + +// +// TYPES + + typedef C Container; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::value_type value_type; + typedef typename C::const_reference reference; + typedef const value_type* pointer; + typedef typename C::size_type size_type; + typedef typename C::difference_type difference_type; + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + return (_ptr == NULL) + || (((const C*)_ptr)->begin() + ==((const C*)_ptr)->end()); + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( + const Random_access_const_circulator_from_container + & c) const { + return i == c.i; + } + bool operator!=(const Random_access_const_circulator_from_container + & c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + return *i; + } + pointer operator->() const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + return &(*i); + } + Random_access_const_circulator_from_container& + operator++() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + ++i; + if ( i == ((const C*)_ptr)->end()) + i = ((const C*)_ptr)->begin(); + return *this; + } + Random_access_const_circulator_from_container + operator++(int) { + Random_access_const_circulator_from_container + tmp= *this; + ++*this; + return tmp; + } + + Random_access_const_circulator_from_container& + operator--() { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + if ( i == ((const C*)_ptr)->begin()) + i = ((const C*)_ptr)->end(); + --i; + return *this; + } + Random_access_const_circulator_from_container + operator--(int) { + Random_access_const_circulator_from_container + tmp = *this; + --*this; + return tmp; + } + + Random_access_const_circulator_from_container& + operator+=( difference_type n); + + Random_access_const_circulator_from_container + operator+( difference_type n) const { + Random_access_const_circulator_from_container + tmp = *this; + return tmp += n; + } + Random_access_const_circulator_from_container& + operator-=( difference_type n) { + return operator+=( -n); + } + Random_access_const_circulator_from_container + operator-( difference_type n) const { + Random_access_const_circulator_from_container + tmp = *this; + return tmp += -n; + } + difference_type + operator-( const Random_access_const_circulator_from_container< + C>& c) const { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( c._ptr != NULL); + return i - c.i; + } + reference operator[](difference_type n) const { + Random_access_const_circulator_from_container + tmp = *this; + tmp += n; + return tmp.operator*(); + } + + friend inline + Random_access_const_circulator_from_container + operator+( difference_type n, const + Random_access_const_circulator_from_container< + C>& c) { + Random_access_const_circulator_from_container + tmp = c; + return tmp += n; + } + const_iterator current_iterator() const { return i;} + + Random_access_const_circulator_from_container + min_circulator() const { + return Random_access_const_circulator_from_container + ((const C*)_ptr); + } + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline typename C::difference_type* distance_type( + const + Random_access_const_circulator_from_container&) { + return (typename C::difference_type*)(0); + } + friend inline typename C::value_type* value_type( + const + Random_access_const_circulator_from_container&) { + return (typename C::value_type*)(0); + } + friend inline Random_access_circulator_tag iterator_category( + Random_access_const_circulator_from_container) { + return Random_access_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Random_access_const_circulator_from_container) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class C> +Random_access_const_circulator_from_container& +Random_access_const_circulator_from_container:: +operator+=( typename C::difference_type n) { + CGAL_assertion( _ptr != NULL); + CGAL_assertion( i != ((const C*)_ptr)->end()); + + typename C::difference_type j = i - ((const C*)_ptr) + ->begin(); + typename C::difference_type size = ((const C*)_ptr)->size(); + CGAL_assertion( j >= 0); + CGAL_assertion( size >= 0); + j = non_negative_mod( j + n, size); + CGAL_assertion( j >= 0); + CGAL_assertion( j < size); + i = ((const C*)_ptr)->begin() + j; + return *this; +} +template < class I, class T, class Size, class Dist> +class Forward_circulator_from_iterator + : public Forward_circulator_base { +private: + I _begin; + I _end; + I current; +public: + +// DEFINITION +// +// The adaptor Forward_circulator_from_iterator< I, T, Size, Dist> +// is a class that converts two iterators, a begin and a past-the-end +// value, to a forward circulator. The iterators are supposed to be at +// least forward iterators. The adaptor for bidirectional circulators is +// `Bidirectional_circulator_from_iterator< I, T, Size, Dist>' and +// for random access circulators it is +// `Random_access_circulator_from_iterator< I, T, Size, Dist>'. +// Appropriate const circulators are also available. +// +// PARAMETERS +// +// `I' is the appropriate iterator type, `T' its value type, `Size' the +// unsigned integral value to hold the possible number of items in a +// sequence, and `Dist' is a signed integral value, the distance type +// between two iterators of the same sequence. +// +// +// TYPES + + typedef I iterator; + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef Size size_type; + typedef Dist difference_type; + + typedef Forward_circulator_from_iterator Self; + +// CREATION +// +// New creation variable is: `adaptor' + + Forward_circulator_from_iterator() + : _begin(I()), _end(I()), current(I()) {} + // a circulator `adaptor' with a singular value. + + Forward_circulator_from_iterator( const I& begin, const I& end) + : _begin( begin), _end( end), current( begin) {} + // a circulator `adaptor' initialized to refer to the element + // `*begin' in a range [`begin' ,`end' ). The circulator `adaptor' + // contains a singular value if `begin==end'. + + Forward_circulator_from_iterator( const I& begin, const I& end, + const I& cur) + : _begin( begin), _end( end), current( cur) {} + + Forward_circulator_from_iterator( const Self& c, const I& cur) + : _begin( c._begin), _end( c._end), current( cur) {} +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + CGAL_assertion((_end == _begin) || (current != _end)); + return _end == _begin; + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Self& c) const { + // CGAL_assertion((_begin == c._begin) && (_end == c._end)); + return current == c.current; + } + bool operator!=( const Self& c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( current != _end); + return *current; + } + pointer operator->() const { + CGAL_assertion( current != _end); + return &(*current); + } + Self& operator++() { + CGAL_assertion( current != _end); + ++current; + if ( current == _end) + current = _begin; + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + iterator current_iterator() const { return current;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline Dist* distance_type( + const + Forward_circulator_from_iterator&) { + return ( Dist*)(0); + } + friend inline T* value_type( + const + Forward_circulator_from_iterator&) { + return (T*)(0); + } + friend inline Forward_circulator_tag iterator_category( + Forward_circulator_from_iterator) { + return Forward_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Forward_circulator_from_iterator) { + return CGAL_Circulator_tag(); + } + #endif +}; + + +template < class I, class T, class Size, class Dist > +class Forward_const_circulator_from_iterator + : public Forward_circulator_base { +private: + I _begin; + I _end; + I current; +public: +// +// TYPES + + typedef I iterator; + typedef T value_type; + typedef const T& reference; + typedef const T* pointer; + typedef Size size_type; + typedef Dist difference_type; + + typedef Forward_const_circulator_from_iterator Self; + +// +// CREATION + + Forward_const_circulator_from_iterator() + : _begin(I()), _end(I()), current(I()) {} + + Forward_const_circulator_from_iterator( const I& begin, + const I& end) + : _begin( begin), _end( end), current( begin) {} + + Forward_const_circulator_from_iterator( const I& begin, + const I& end, + const I& cur) + : _begin( begin), _end( end), current( cur) {} + + Forward_const_circulator_from_iterator( const Self& c, + const I& cur) + : _begin( c._begin), _end( c._end), current( cur) {} + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + CGAL_assertion((_end == _begin) || (current != _end)); + return _end == _begin; + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Self& c) const { + // CGAL_assertion((_begin == c._begin) && (_end == c._end)); + return current == c.current; + } + bool operator!=( const Self& c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( current != _end); + return *current; + } + pointer operator->() const { + CGAL_assertion( current != _end); + return &(*current); + } + Self& operator++() { + CGAL_assertion( current != _end); + ++current; + if ( current == _end) + current = _begin; + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + iterator current_iterator() const { return current;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline Dist* distance_type( + const + Forward_const_circulator_from_iterator&) { + return ( Dist*)(0); + } + friend inline T* value_type( + const + Forward_const_circulator_from_iterator&) { + return (T*)(0); + } + friend inline Forward_circulator_tag iterator_category( + Forward_const_circulator_from_iterator) { + return Forward_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Forward_const_circulator_from_iterator) { + return CGAL_Circulator_tag(); + } + #endif +}; + + +template < class I, class T, class Size, class Dist > +class Bidirectional_circulator_from_iterator + : public Bidirectional_circulator_base { +private: + I _begin; + I _end; + I current; +public: +// +// TYPES + + typedef I iterator; + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef Size size_type; + typedef Dist difference_type; + + typedef Bidirectional_circulator_from_iterator Self; +// +// CREATION + + Bidirectional_circulator_from_iterator() + : _begin(I()), _end(I()), current(I()) {} + + Bidirectional_circulator_from_iterator( const I& begin, + const I& end) + : _begin( begin), _end( end), current( begin) {} + + Bidirectional_circulator_from_iterator( const I& begin, + const I& end, + const I& cur) + : _begin( begin), _end( end), current( cur) {} + + Bidirectional_circulator_from_iterator( const Self& c, + const I& cur) + : _begin( c._begin), _end( c._end), current( cur) {} +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + CGAL_assertion((_end == _begin) || (current != _end)); + return _end == _begin; + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Self& c) const { + // CGAL_assertion((_begin == c._begin) && (_end == c._end)); + return current == c.current; + } + bool operator!=( const Self& c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( current != _end); + return *current; + } + pointer operator->() const { + CGAL_assertion( current != _end); + return &(*current); + } + Self& operator++() { + CGAL_assertion( current != _end); + ++current; + if ( current == _end) + current = _begin; + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( current != _end); + if ( current == _begin) + current = _end; + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + iterator current_iterator() const { return current;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline Dist* distance_type( + const + Bidirectional_circulator_from_iterator&) { + return ( Dist*)(0); + } + friend inline T* value_type( + const + Bidirectional_circulator_from_iterator&) { + return (T*)(0); + } + friend inline Bidirectional_circulator_tag iterator_category( + Bidirectional_circulator_from_iterator) { + return Bidirectional_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Bidirectional_circulator_from_iterator) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class I, class T, class Size, class Dist > +class Bidirectional_const_circulator_from_iterator + : public Bidirectional_circulator_base { +private: + I _begin; + I _end; + I current; +public: +// +// TYPES + + typedef I iterator; + typedef T value_type; + typedef const T& reference; + typedef const T* pointer; + typedef Size size_type; + typedef Dist difference_type; + + typedef Bidirectional_const_circulator_from_iterator + Self; +// +// CREATION + + Bidirectional_const_circulator_from_iterator() + : _begin(I()), _end(I()), current(I()) {} + + Bidirectional_const_circulator_from_iterator( const I& begin, + const I& end) + : _begin( begin), _end( end), current( begin) {} + + Bidirectional_const_circulator_from_iterator( const I& begin, + const I& end, + const I& cur) + : _begin( begin), _end( end), current( cur) {} + + Bidirectional_const_circulator_from_iterator( const Self& c, + const I& cur) + : _begin( c._begin), _end( c._end), current( cur) {} +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + CGAL_assertion((_end == _begin) || (current != _end)); + return _end == _begin; + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Self& c) const { + // CGAL_assertion((_begin == c._begin) && (_end == c._end)); + return current == c.current; + } + bool operator!=( const Self& c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( current != _end); + return *current; + } + pointer operator->() const { + CGAL_assertion( current != _end); + return &(*current); + } + Self& operator++() { + CGAL_assertion( current != _end); + ++current; + if ( current == _end) + current = _begin; + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( current != _end); + if ( current == _begin) + current = _end; + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + iterator current_iterator() const { return current;} + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline Dist* distance_type( + const + Bidirectional_const_circulator_from_iterator&) { + return ( Dist*)(0); + } + friend inline T* value_type( + const + Bidirectional_const_circulator_from_iterator&) { + return (T*)(0); + } + friend inline Bidirectional_circulator_tag iterator_category( + Bidirectional_const_circulator_from_iterator) { + return Bidirectional_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Bidirectional_const_circulator_from_iterator) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class I, class T, class Size, class Dist > +class Random_access_circulator_from_iterator + : public Random_access_circulator_base { +private: + I _begin; + I _end; + I current; +public: +// +// TYPES + + typedef I iterator; + typedef T value_type; + typedef T& reference; + typedef T* pointer; + typedef Size size_type; + typedef Dist difference_type; + + typedef Random_access_circulator_from_iterator Self; +// +// CREATION + + Random_access_circulator_from_iterator() + : _begin(I()), _end(I()), current(I()) {} + + Random_access_circulator_from_iterator( const I& begin, + const I& end) + : _begin( begin), _end( end), current( begin) {} + + Random_access_circulator_from_iterator( const I& begin, + const I& end, + const I& cur) + : _begin( begin), _end( end), current( cur) {} + + Random_access_circulator_from_iterator( const Self& c, + const I& cur) + : _begin( c._begin), _end( c._end), current( cur) {} + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + CGAL_assertion((_end == _begin) || (current != _end)); + return _end == _begin; + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Self& c) const { + // CGAL_assertion((_begin == c._begin) && (_end == c._end)); + return current == c.current; + } + bool operator!=( const Self& c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( current != _end); + return *current; + } + pointer operator->() const { + CGAL_assertion( current != _end); + return &(*current); + } + Self& operator++() { + CGAL_assertion( current != _end); + ++current; + if ( current == _end) + current = _begin; + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( current != _end); + if ( current == _begin) + current = _end; + --current; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + Self& operator+=( Dist n); + + Self operator+( Dist n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( Dist n) { + return operator+=( -n); + } + Self operator-( Dist n) const { + Self tmp = *this; + return tmp += -n; + } + Dist operator-( const Self& i) const { + CGAL_assertion((_begin == i._begin) && (_end == i._end)); + return current - i.current; + } + reference operator[](Dist n) const { + Self tmp = *this; + tmp += n; + return tmp.operator*(); + } + iterator current_iterator() const { return current;} + + Self min_circulator() const { + return Self( _begin, _end); + } + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline Dist* distance_type( + const + Random_access_circulator_from_iterator&) { + return ( Dist*)(0); + } + friend inline T* value_type( + const + Random_access_circulator_from_iterator&) { + return (T*)(0); + } + friend inline Random_access_circulator_tag iterator_category( + Random_access_circulator_from_iterator) { + return Random_access_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Random_access_circulator_from_iterator) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class D, class I, class T, class Size, class Dist> inline +Random_access_circulator_from_iterator< I, T, Size, Dist> +operator+( D n, const + Random_access_circulator_from_iterator< I, T, Size, Dist>& circ) { + Random_access_circulator_from_iterator< I, T, Size, Dist> + tmp = circ; + return tmp += Dist(n); +} + +template < class I, class T, class Size, class Dist> +Random_access_circulator_from_iterator< I, T, Size, Dist>& +Random_access_circulator_from_iterator< I, T, Size, Dist>:: +operator+=( Dist n) { + CGAL_assertion( current != _end); + + Dist i = current - _begin; + Dist size = _end - _begin; + CGAL_assertion( i >= 0); + CGAL_assertion( size >= 0); + i = non_negative_mod( i + n, size); + CGAL_assertion( i >= 0); + CGAL_assertion( i < size); + current = _begin + i; + return *this; +} + + +template < class I, class T, class Size, class Dist > +class Random_access_const_circulator_from_iterator + : public Random_access_circulator_base { +private: + I _begin; + I _end; + I current; +public: +// +// TYPES + + typedef I iterator; + typedef T value_type; + typedef const T& reference; + typedef const T* pointer; + typedef Size size_type; + typedef Dist difference_type; + + typedef Random_access_const_circulator_from_iterator + Self; +// +// CREATION + + Random_access_const_circulator_from_iterator() + : _begin(I()), _end(I()), current(I()) {} + + Random_access_const_circulator_from_iterator( const I& begin, + const I& end) + : _begin( begin), _end( end), current( begin) {} + + Random_access_const_circulator_from_iterator( const I& begin, + const I& end, + const I& cur) + : _begin( begin), _end( end), current( cur) {} + + Random_access_const_circulator_from_iterator( const Self& c, + const I& cur) + : _begin( c._begin), _end( c._end), current( cur) {} + +// +// OPERATIONS + + bool operator==( CGAL_NULL_TYPE p) const { + CGAL_assertion( p == CGAL_CIRC_NULL); + CGAL_assertion((_end == _begin) || (current != _end)); + return _end == _begin; + } + bool operator!=( CGAL_NULL_TYPE p) const { + return !(*this == p); + } + bool operator==( const Self& c) const { + // CGAL_assertion((_begin == c._begin) && (_end == c._end)); + return current == c.current; + } + bool operator!=( const Self& c) const { + return !(*this == c); + } + reference operator*() const { + CGAL_assertion( current != _end); + return *current; + } + pointer operator->() const { + CGAL_assertion( current != _end); + return &(*current); + } + Self& operator++() { + CGAL_assertion( current != _end); + ++current; + if ( current == _end) + current = _begin; + return *this; + } + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } + Self& operator--() { + CGAL_assertion( current != _end); + if ( current == _begin) + current = _end; + --current; + return *this; + } + Self + operator--(int) { + Self tmp = *this; + --*this; + return tmp; + } + Self& operator+=( Dist n); + + Self + operator+( Dist n) const { + Self tmp = *this; + return tmp += n; + } + Self& operator-=( Dist n) { + return operator+=( -n); + } + Self operator-( Dist n) const { + Self tmp = *this; + return tmp += -n; + } + Dist operator-( const Self& i) const { + CGAL_assertion((_begin == i._begin) && (_end == i._end)); + return current - i.current; + } + reference operator[](Dist n) const { + Self tmp = *this; + tmp += n; + return tmp.operator*(); + } + iterator current_iterator() const { return current;} + + Self min_circulator() const { + return Self( _begin, _end); + } + #if defined( __GNUG__ ) && defined( CGAL__CIRC_STL_GCC ) + friend inline Dist* distance_type( + const + Random_access_const_circulator_from_iterator&) { + return ( Dist*)(0); + } + friend inline T* value_type( + const + Random_access_const_circulator_from_iterator&) { + return (T*)(0); + } + friend inline Random_access_circulator_tag iterator_category( + Random_access_const_circulator_from_iterator) { + return Random_access_circulator_tag(); + } + friend inline CGAL_Circulator_tag CGAL_query_circulator_or_iterator( + Random_access_const_circulator_from_iterator) { + return CGAL_Circulator_tag(); + } + #endif +}; + +template < class D, class I, class T, class Size, class Dist> inline +Random_access_const_circulator_from_iterator< I, T, Size, Dist> +operator+( D n, const + Random_access_const_circulator_from_iterator< I, T, Size, Dist>& + circ) { + Random_access_const_circulator_from_iterator< I, T, Size, Dist> + tmp = circ; + return tmp += Dist(n); +} + +template < class I, class T, class Size, class Dist> +Random_access_const_circulator_from_iterator< I, T, Size, Dist>& +Random_access_const_circulator_from_iterator< I, T, Size, Dist>:: +operator+=( Dist n) { + CGAL_assertion( current != _end); + + Dist i = current - _begin; + Dist size = _end - _begin; + CGAL_assertion( i >= 0); + CGAL_assertion( size >= 0); + i = non_negative_mod( i + n, size); + CGAL_assertion( i >= 0); + CGAL_assertion( i < size); + current = _begin + i; + return *this; +} + +CGAL_END_NAMESPACE + +#endif // CGAL_CIRCULATOR_COMPAT_H // +// EOF // diff --git a/Packages/Circulator/include/CGAL/circulator_impl.h b/Packages/Circulator/include/CGAL/circulator_impl.h new file mode 100644 index 00000000000..fa79d381361 --- /dev/null +++ b/Packages/Circulator/include/CGAL/circulator_impl.h @@ -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 +// +// 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 +#endif + +CGAL_BEGIN_NAMESPACE + +template < class S> +class Forward_circulator_over_struct + : public Forward_circulator_ptrbase{ +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 Self; + typedef Forward_circulator_ptrbase 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( 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{ +public: + + typedef Forward_const_circulator_over_struct 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((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{ +public: + + typedef Bidirectional_circulator_over_struct Self; + typedef Bidirectional_circulator_ptrbase 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( 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{ +public: + + typedef Bidirectional_const_circulator_over_struct 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( + (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{ +public: + typedef Forward_circulator_over_class 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' 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' provides a bidirectional +// circulator for it. In addition, adaptors for const circulators are +// provided with the names `Forward_const_circulator_over_class' +// and `Bidirectional_const_circulator_over_class'. 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( 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{ +public: + typedef Forward_const_circulator_over_class Self; + + Forward_const_circulator_over_class() {} + // a circulator `circ' with singular value. + + Forward_const_circulator_over_class( const C* ptr) + : Forward_circulator_ptrbase + ((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{ +public: + typedef Bidirectional_circulator_over_class Self; + + Bidirectional_circulator_over_class() {} + // a circulator `circ' with singular value. + + Bidirectional_circulator_over_class( C* ptr) + : Bidirectional_circulator_ptrbase + (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{ +public: + typedef Bidirectional_const_circulator_over_class Self; +// +// CREATION + + Bidirectional_const_circulator_over_class() {} + // a circulator `circ' with singular value. + + Bidirectional_const_circulator_over_class( const C* ptr) + : Bidirectional_circulator_ptrbase( + (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{ + 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 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( &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 { + U _size; + U _i; +public: + +// TYPES + + typedef A Array; + typedef Const_circulator_over_array 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( + (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& 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 // diff --git a/Packages/Circulator/long_description.txt b/Packages/Circulator/long_description.txt new file mode 100644 index 00000000000..bbfb9ffec62 --- /dev/null +++ b/Packages/Circulator/long_description.txt @@ -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 diff --git a/Packages/Circulator/submission_info b/Packages/Circulator/submission_info new file mode 100644 index 00000000000..a5ea2de1e4b --- /dev/null +++ b/Packages/Circulator/submission_info @@ -0,0 +1,2 @@ +Submitted by: kettner@inf.ethz.ch. +URL: http://www.inf.ethz.ch/personal/kettner/CGAL/Circulator/Circulator.tar.gz. diff --git a/Packages/Circulator/test/Circulator/cgal_test b/Packages/Circulator/test/Circulator/cgal_test new file mode 100755 index 00000000000..69c1f54da4a --- /dev/null +++ b/Packages/Circulator/test/Circulator/cgal_test @@ -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 +#---------------------------------------------------------------------# + +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 + diff --git a/Packages/Circulator/test/Circulator/makefile b/Packages/Circulator/test/Circulator/makefile new file mode 100644 index 00000000000..3c9d20cd9aa --- /dev/null +++ b/Packages/Circulator/test/Circulator/makefile @@ -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 /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) $< + diff --git a/Packages/Circulator/test/Circulator/test_circ1.C b/Packages/Circulator/test/Circulator/test_circ1.C new file mode 100644 index 00000000000..b281a8a4de6 --- /dev/null +++ b/Packages/Circulator/test/Circulator/test_circ1.C @@ -0,0 +1,5025 @@ +// ============================================================================ +// +// 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 : $CGAL_Revision: $ +// release_date : $CGAL_Date: $ +// +// file : test_circ1.C +// chapter : $CGAL_Chapter: Circulators $ +// package : $CGAL_Package: Circulator 3.4 (02 Sep 1999) $ +// source : circulator.fw +// revision : $Revision$ +// revision_date : $Date$ +// author(s) : Lutz Kettner +// +// coordinator : INRIA, Sophia Antipolis +// +// Test circulator support and adaptor between circulator and iterator. +// ============================================================================ + + +#ifndef CGAL_BASIC_H +#include +#endif // CGAL_BASIC_H +#ifndef CGAL_PROTECT_CSTDDEF +#include +#define CGAL_PROTECT_CSTDDEF +#endif +#ifndef CGAL_PROTECT_ITERATOR +#include +#define CGAL_PROTECT_ITERATOR +#endif +#ifndef CGAL_PROTECT_LIST +#include +#define CGAL_PROTECT_LIST +#endif +#ifndef CGAL_PROTECT_VECTOR +#include +#define CGAL_PROTECT_VECTOR +#endif +#ifndef CGAL_CIRCULATOR_H +#include +#endif // CGAL_CIRCULATOR_H +// needed for test data structures +#ifndef CGAL_CIRCULATOR_IMPL_H +#include +#endif // CGAL_CIRCULATOR_IMPL_H + +using namespace CGAL; + +// Global data structures. +std::list L; +std::vector V; +// int* C_array; // Gnu gcov produces a core here! + +// Workaround +int* new_C_array() { + int* p = new int[5]; + for ( int i = 1; i <= 5; i++) { + p[i-1] = i; + } + return p; +} + +// Build a simple 'n'-element circular structure using struct's. +struct Node { + int key; + Node* next; + Node* prev; + Node() : key(0), next(this), prev( this) {} + Node( int n) : key(n), next(this), prev( this) {} + Node( Node* _nx, Node* _pv, int n) + : key(n), next(_nx), prev( _pv) {} +}; +Node* new_node( Node* _nx, Node* _pv, int n) { + return new Node( _nx, _pv, n); +} +void append_node( Node* p, int n) { + Node* q = new_node( p, p->prev, n); + p->prev->next = q; + p->prev = q; +} +Node* generate_nodes( int n) { + CGAL_assertion( n > 0); + Node* p = new Node(1); + for ( int i = 2; i <= n; i++) + append_node( p, i); + return p; +} +void delete_nodes( Node* p) { + Node* end = p; + Node* q = p; + p = p->next; + while ( p != end) { + delete q; + q = p; + p = p->next; + } + delete q; +} + +typedef CGAL::Forward_circulator_over_struct< Node> + Struct_circulator; +typedef CGAL::Forward_const_circulator_over_struct< Node> + Struct_const_circulator; +typedef CGAL::Bidirectional_circulator_over_struct< Node> + Struct_bi_circulator; +typedef CGAL::Bidirectional_const_circulator_over_struct< Node> + Struct_bi_const_circulator; + +// Build a simple 'n'-element circular structure using struct's. +class CNode { + CNode* _next; + CNode* _prev; + public: + int key; + CNode* next() { return _next;} + const CNode* next() const { return _next;} + CNode* prev() { return _prev;} + const CNode* prev() const { return _prev;} + CNode() : _next(this), _prev( this), key(0) {} + CNode( int n) : _next(this), _prev( this), key(n) {} + CNode( CNode* _nx, CNode* _pv, int n) + : _next(_nx), _prev( _pv), key(n) {} + friend CNode* new_cnode( CNode* _nx, CNode* _pv, int n); + friend void append_cnode( CNode* p, int n); + friend void delete_cnodes( CNode* p); +}; +CNode* new_cnode( CNode* _nx, CNode* _pv, int n) { + return new CNode( _nx, _pv, n); +} +void append_cnode( CNode* p, int n) { + CNode* q = new_cnode( p, p->_prev, n); + p->_prev->_next = q; + p->_prev = q; +} +CNode* generate_cnodes( int n) { + CGAL_assertion( n > 0); + CNode* p = new CNode(1); + for ( int i = 2; i <= n; i++) + append_cnode( p, i); + return p; +} +void delete_cnodes( CNode* p) { + CNode* end = p; + CNode* q = p; + p = p->_next; + while ( p != end) { + delete q; + q = p; + p = p->_next; + } + delete q; +} + +typedef CGAL::Forward_circulator_over_class< CNode> + Class_circulator; +typedef CGAL::Forward_const_circulator_over_class< CNode> + Class_const_circulator; +typedef CGAL::Bidirectional_circulator_over_class< CNode> + Class_bi_circulator; +typedef CGAL::Bidirectional_const_circulator_over_class< CNode> + Class_bi_const_circulator; + + +void init_global_data() { + // C_array = new int[5]; + for ( int i = 1; i <= 5; i++) { + L.push_back(i); + V.push_back(i); + // C_array[i-1] = i; + } +} + +void clean_global_data() { + //delete[] C_array; +} + +// Test value type and distance type. +int test_value_type( int*) { return 1;} +int test_value_type( Node*) { return 1;} +int test_value_type( CNode*) { return 1;} +int test_value_type( char*) { return 2;} +int test_value_type( double*) { return 3;} + +int test_difference_type( std::ptrdiff_t*) { return 1;} +int test_difference_type( char*) { return 2;} +int test_difference_type( double*) { return 3;} +template< class T> inline +int foo3( T t, Forward_circulator_tag) { + Assert_circulator( t); + Assert_forward_category( t); + return 1; +} + +template< class T> inline +int foo3( T t, Bidirectional_circulator_tag) { + Assert_circulator( t); + Assert_bidirectional_category( t); + return 2; +} + +template< class T> inline +int foo3( T t, Random_access_circulator_tag) { + Assert_circulator( t); + Assert_random_access_category( t); + return 3; +} + +template< class T> inline +int foo3( T t) { return -1; } // never used + +template< class T> inline +int foo2( T t, Circulator_tag) { + Assert_circulator( t); + typedef std::iterator_traits Traits; + typedef typename Traits::iterator_category iterator_category; + return foo3( t, iterator_category()); +} + +template< class T> inline +int foo2( T t, Iterator_tag) { + Assert_iterator( t); + return 4; +} + +template< class T> inline +int foo2( T t) { return -1; } // never used + +template< class T> inline +int foo( T t) { return foo2( t, query_circulator_or_iterator( t));} + +int bar( std::size_t) { return 1;} +int bar( std::ptrdiff_t) { return 2;} +int bar( char) { return 3;} +int bar( double) { return 4;} + +void test_tags() { + { + std::list l; + CGAL_assertion( 4 == foo( l.begin())); + CGAL_assertion( 4 == foo( l.end())); + std::vector v; + CGAL_assertion( 4 == foo( v.begin())); + CGAL_assertion( 4 == foo( v.end())); + + int* p = NULL; + CGAL_assertion( 4 == foo( p)); + { + typedef Forward_circulator_base + FC; + typedef Bidirectional_circulator_base + BC; + typedef Random_access_circulator_base + RC; + + FC f_c = FC(); + BC b_c = BC(); + RC r_c = RC(); + CGAL_assertion( 1 == foo( f_c)); + CGAL_assertion( 2 == foo( b_c)); + CGAL_assertion( 3 == foo( r_c)); + CGAL_assertion( 3 == bar( std::iterator_traits::value_type())); + CGAL_assertion( 4 == bar( std::iterator_traits::value_type())); + CGAL_assertion( 1 == bar( std::iterator_traits::value_type())); + CGAL_assertion( 2 == bar( std::iterator_traits:: + difference_type())); + CGAL_assertion( 3 == bar( std::iterator_traits:: + difference_type())); + CGAL_assertion( 3 == bar( std::iterator_traits:: + difference_type())); + } + { + typedef Forward_circulator_ptrbase + FC; + typedef Bidirectional_circulator_ptrbase + BC; + typedef Random_access_circulator_ptrbase RC; + + FC f_c = FC(); + BC b_c = BC(); + RC r_c = RC(); + CGAL_assertion( 1 == foo( f_c)); + CGAL_assertion( 2 == foo( b_c)); + CGAL_assertion( 3 == foo( r_c)); + CGAL_assertion( 3 == bar( std::iterator_traits::value_type())); + CGAL_assertion( 4 == bar( std::iterator_traits::value_type())); + CGAL_assertion( 1 == bar( std::iterator_traits::value_type())); + CGAL_assertion( 2 == bar( std::iterator_traits:: + difference_type())); + CGAL_assertion( 3 == bar( std::iterator_traits:: + difference_type())); + CGAL_assertion( 3 == bar( std::iterator_traits:: + difference_type())); + } + // a bit more complicated cases. + typedef Random_access_circulator_from_iterator< + std::vector::iterator, + int, + std::vector::size_type, + std::vector::difference_type + > Circulator; + typedef Random_access_container_from_circulator Container; + typedef Container::iterator Iterator; + Circulator ci( v.begin(), v.end()); + Container Co( ci); + CGAL_assertion( 3 == foo( ci)); + CGAL_assertion( 4 == foo( Co.begin())); + CGAL_assertion( 4 == foo( Co.end())); + } +} +void test_functions_for_circulators() { + Node* data_struct = generate_nodes( 5); + Struct_circulator start1(data_struct); + Struct_const_circulator start2(data_struct); + Struct_bi_circulator start3(data_struct); + Struct_bi_const_circulator start4(data_struct); + CGAL_assertion( circulator_size(start1) == 5); + CGAL_assertion( circulator_size(start2) == 5); + CGAL_assertion( circulator_size(start3) == 5); + CGAL_assertion( circulator_size(start4) == 5); + Struct_circulator start1a(data_struct); + Struct_const_circulator start2a(data_struct); + Struct_bi_circulator start3a(data_struct); + Struct_bi_const_circulator start4a(data_struct); + CGAL_assertion( circulator_distance(start1, start1a) == 5); + CGAL_assertion( circulator_distance(start2, start2a) == 5); + CGAL_assertion( circulator_distance(start3, start3a) == 5); + CGAL_assertion( circulator_distance(start4, start4a) == 5); + CGAL_assertion( iterator_distance(start1, start1a) == 5); + CGAL_assertion( iterator_distance(start2, start2a) == 5); + CGAL_assertion( iterator_distance(start3, start3a) == 5); + CGAL_assertion( iterator_distance(start4, start4a) == 5); + ++ start1a; + ++ start2a; + ++ start3a; + ++ start4a; + CGAL_assertion( circulator_distance(start1, start1a) == 1); + CGAL_assertion( circulator_distance(start2, start2a) == 1); + CGAL_assertion( circulator_distance(start3, start3a) == 1); + CGAL_assertion( circulator_distance(start4, start4a) == 1); + CGAL_assertion( iterator_distance(start1, start1a) == 1); + CGAL_assertion( iterator_distance(start2, start2a) == 1); + CGAL_assertion( iterator_distance(start3, start3a) == 1); + CGAL_assertion( iterator_distance(start4, start4a) == 1); + ++ start1a; + ++ start2a; + ++ start1a; + ++ start2a; + ++ start1a; + ++ start2a; + -- start3a; + -- start4a; + -- start3a; + -- start4a; + CGAL_assertion( circulator_distance(start1, start1a) == 4); + CGAL_assertion( circulator_distance(start2, start2a) == 4); + CGAL_assertion( circulator_distance(start3, start3a) == 4); + CGAL_assertion( circulator_distance(start4, start4a) == 4); + CGAL_assertion( iterator_distance(start1, start1a) == 4); + CGAL_assertion( iterator_distance(start2, start2a) == 4); + CGAL_assertion( iterator_distance(start3, start3a) == 4); + CGAL_assertion( iterator_distance(start4, start4a) == 4); + delete_nodes(data_struct); + std::list l; + CGAL_assertion( iterator_distance(l.begin(), l.end()) == 0); + l.push_back(3); + CGAL_assertion( iterator_distance(l.begin(), l.end()) == 1); + int* my_C_array = new_C_array(); + CGAL_assertion( iterator_distance(my_C_array, my_C_array+5) == 5); + typedef Random_access_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator1; + Circulator1 c1( my_C_array, my_C_array+5); + CGAL_assertion( circulator_size(c1) == 5); + Circulator1 c3 = c1; + ++c3; + CGAL_assertion( c1 == c3.min_circulator()); + --c3; + --c3; + CGAL_assertion( c1 == c3.min_circulator()); + --c3; + CGAL_assertion( c1 == c3.min_circulator()); + typedef Random_access_const_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator2; + Circulator2 c2( my_C_array, my_C_array+5); + CGAL_assertion( circulator_size(c2) == 5); + c3 = c1; + Circulator2 c4(c2); + CGAL_assertion( circulator_distance(c1,c3) == 5); + CGAL_assertion( circulator_distance(c2,c4) == 5); + c3 ++; + c4 ++; + CGAL_assertion( circulator_distance(c1,c3) == 1); + CGAL_assertion( circulator_distance(c2,c4) == 1); + c3 --; + c4 --; + c3 --; + c4 --; + CGAL_assertion( circulator_distance(c1,c3) == 4); + CGAL_assertion( circulator_distance(c2,c4) == 4); + delete[] my_C_array; + CGAL_assertion( 2 == non_negative_mod( -4, 3)); + CGAL_assertion( 0 == non_negative_mod( -3, 3)); + CGAL_assertion( 1 == non_negative_mod( -2, 3)); + CGAL_assertion( 2 == non_negative_mod( -1, 3)); + CGAL_assertion( 0 == non_negative_mod( 0, 3)); + CGAL_assertion( 1 == non_negative_mod( 1, 3)); + CGAL_assertion( 2 == non_negative_mod( 2, 3)); + CGAL_assertion( 0 == non_negative_mod( 3, 3)); + CGAL_assertion( 1 == non_negative_mod( 4, 3)); +} +void test_iterator_and_circulators() { + std::vector v; + CGAL_assertion( is_empty_range( v.begin(), v.end())); + typedef Random_access_circulator_from_iterator< + std::vector::iterator, + int, + std::vector::size_type, + std::vector::difference_type + > Circulator; + Circulator c( v.begin(), v.end()); + CGAL_assertion( is_empty_range( c, c)); + v.push_back( 5); + CGAL_assertion( is_empty_range( v.begin(), v.begin())); + CGAL_assertion( ! is_empty_range( v.begin(), v.end())); + Circulator d( v.begin(), v.end()); + CGAL_assertion( ! is_empty_range( d, d)); + std::vector::iterator i = v.begin(); + int j = 0; + { + CGAL_assertion( v.size() == 1); + CGAL_For_all( i, v.end()) { + CGAL_assertion( *i == 5); + j++; + } + CGAL_assertion( j == 1); + }{ + CGAL_For_all( d, d) { + CGAL_assertion( *d == 5); + j++; + } + CGAL_assertion( j == 2); + }{ + CGAL_For_all_backwards( d, d) { + CGAL_assertion( *d == 5); + j++; + } + CGAL_assertion( j == 3); + } +} +void test_container_from_circulator() { + Node* data_struct = generate_nodes( 5); + { + Struct_circulator start(data_struct); + typedef Forward_container_from_circulator + Container; + Container X; + CGAL_assertion( X.begin() == X.end()); + Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + Container C( start); + typedef Container::iterator Iterator; + Iterator begin = C.begin(); + Iterator end = C.end(); + Assert_forward_category(begin); + Assert_forward_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Iterator i = begin; + (*i++).key = 4; + CGAL_assertion( 4 == (*begin).key); + CGAL_assertion( 2 == (*i).key); + (*i++).key = 3; + CGAL_assertion( 3 == (*i).key); + (*++i).key = 7; + CGAL_assertion( 7 == (*i).key); + + // Check the setting and reset these elements + // to their original values. + i = begin; + CGAL_assertion( 4 == (*i).key); + (*i).key = 1; + i++; + CGAL_assertion( 3 == (*i).key); + (*i++).key = 2; + CGAL_assertion( 3 == (*i).key); + i++; + CGAL_assertion( 7 == (*i).key); + (*i).key = 4; + + // Check the resetting. + i = begin; + int k = 1; + do { + CGAL_assertion( k == (*i).key); + ++i; + ++k; + } while (i != end); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + begin++; + CGAL_assertion( (*(begin.current_circulator())).key == 2); + } + { + Struct_const_circulator start(data_struct); + typedef Forward_container_from_circulator + Container; + const Container X; + CGAL_assertion( X.begin() == X.end()); + const Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + const Container C( start); + typedef Container::const_iterator Const_iterator; + Const_iterator begin = C.begin(); + Const_iterator end = C.end(); + Assert_forward_category(begin); + Assert_forward_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Const_iterator z = Const_iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Const_iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Const_iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Const_iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + begin++; + CGAL_assertion( (*(begin.current_circulator())).key == 2); + } + { + Struct_bi_circulator start(data_struct); + typedef Bidirectional_container_from_circulator< + Struct_bi_circulator> Container; + Container X; + CGAL_assertion( X.begin() == X.end()); + Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + Container C( start); + typedef Container::iterator Iterator; + Iterator begin = C.begin(); + Iterator end = C.end(); + Assert_bidirectional_category(begin); + Assert_bidirectional_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Iterator i = begin; + (*i++).key = 4; + CGAL_assertion( 4 == (*begin).key); + CGAL_assertion( 2 == (*i).key); + (*i++).key = 3; + CGAL_assertion( 3 == (*i).key); + (*++i).key = 7; + CGAL_assertion( 7 == (*i).key); + + // Check the setting and reset these elements + // to their original values. + i = begin; + CGAL_assertion( 4 == (*i).key); + (*i).key = 1; + i++; + CGAL_assertion( 3 == (*i).key); + (*i++).key = 2; + CGAL_assertion( 3 == (*i).key); + i++; + CGAL_assertion( 7 == (*i).key); + (*i).key = 4; + + // Check the resetting. + i = begin; + int k = 1; + do { + CGAL_assertion( k == (*i).key); + ++i; + ++k; + } while (i != end); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Iterator i = end; + int su = 0; + int k = 5; + do { + Iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + begin++; + CGAL_assertion( (*(begin.current_circulator())).key == 2); + } + { + Struct_bi_const_circulator start(data_struct); + typedef Bidirectional_container_from_circulator< + Struct_bi_const_circulator> Container; + const Container X; + CGAL_assertion( X.begin() == X.end()); + const Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + const Container C( start); + typedef Container::const_iterator Const_iterator; + Const_iterator begin = C.begin(); + Const_iterator end = C.end(); + Assert_bidirectional_category(begin); + Assert_bidirectional_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Const_iterator z = Const_iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Const_iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Const_iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Const_iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Const_iterator i = end; + int su = 0; + int k = 5; + do { + Const_iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Const_iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + begin++; + CGAL_assertion( (*(begin.current_circulator())).key == 2); + } + int* my_C_array = new_C_array(); + { + typedef Random_access_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + typedef Random_access_container_from_circulator + Container; + Container X; + CGAL_assertion( X.begin() == X.end()); + Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + Container C( c); + typedef Container::iterator Iterator; + Iterator begin = C.begin(); + Iterator end = C.end(); + Assert_random_access_category(begin); + Assert_random_access_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Iterator i = begin; + (*i++) = 4; + CGAL_assertion( 4 == (*begin)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = begin; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = begin; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != end); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Iterator i = end; + int su = 0; + int k = 5; + do { + Iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Iterator i = end; + int su = 0; + int k = 5; + do { + Iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(begin); + CGAL::Assert_is_at_least_random_access_category(end); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == begin[k]); + } + int su = begin[0] + + begin[1] + + begin[2] + + begin[3] + + begin[4]; + CGAL_assertion( su == 15); + + // Jump around. + Iterator i = begin; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == begin); + Iterator j = i + 3; + CGAL_assertion( 4 == (*j)); + Iterator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == end); + Iterator ij = jj - 5; + CGAL_assertion( ij == begin); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + Iterator i = begin; + i[2] = 18; + i[4] = 9; + i[3] = 12; + CGAL_assertion( i[2] == 18); + CGAL_assertion( i[4] == 9); + CGAL_assertion( i[3] == 12); + i[2] = 3; + i[3] = 4; + i[4] = 5; + // Check the resetting. + i = begin; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != end); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + { // Open own scope to hide local variables. + CGAL_assertion( end - begin == 5); + CGAL_assertion( begin - end == -5); + // Relational operator. + Iterator i = begin; + ++i; + Iterator j = i; + ++j; + CGAL_assertion( begin < i); + CGAL_assertion( i < j); + CGAL_assertion( j < end); + CGAL_assertion( j > i); + CGAL_assertion( i <= j); + CGAL_assertion( j >= i); + CGAL_assertion( i <= i); + CGAL_assertion( i >= i); + + CGAL_assertion( !( i >= j)); + CGAL_assertion( !( j <= i)); + CGAL_assertion( !( i > j)); + CGAL_assertion( !( j < i)); + CGAL_assertion( !( i > i)); + CGAL_assertion( !( i < i)); + } + begin++; + CGAL_assertion( (*(begin.current_circulator())) == 2); + } + { + typedef Random_access_const_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + typedef Random_access_container_from_circulator + Container; + const Container X; + CGAL_assertion( X.begin() == X.end()); + const Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + const Container C( c); + typedef Container::const_iterator Const_iterator; + Const_iterator begin = C.begin(); + Const_iterator end = C.end(); + Assert_random_access_category(begin); + Assert_random_access_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Const_iterator z = Const_iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Const_iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Const_iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Const_iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Const_iterator i = end; + int su = 0; + int k = 5; + do { + Const_iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Const_iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(begin); + CGAL::Assert_is_at_least_random_access_category(end); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == begin[k]); + } + int su = begin[0] + + begin[1] + + begin[2] + + begin[3] + + begin[4]; + CGAL_assertion( su == 15); + + // Jump around. + Const_iterator i = begin; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == begin); + Const_iterator j = i + 3; + CGAL_assertion( 4 == (*j)); + Const_iterator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == end); + Const_iterator ij = jj - 5; + CGAL_assertion( ij == begin); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + { // Open own scope to hide local variables. + CGAL_assertion( end - begin == 5); + CGAL_assertion( begin - end == -5); + // Relational operator. + Const_iterator i = begin; + ++i; + Const_iterator j = i; + ++j; + CGAL_assertion( begin < i); + CGAL_assertion( i < j); + CGAL_assertion( j < end); + CGAL_assertion( j > i); + CGAL_assertion( i <= j); + CGAL_assertion( j >= i); + CGAL_assertion( i <= i); + CGAL_assertion( i >= i); + + CGAL_assertion( !( i >= j)); + CGAL_assertion( !( j <= i)); + CGAL_assertion( !( i > j)); + CGAL_assertion( !( j < i)); + CGAL_assertion( !( i > i)); + CGAL_assertion( !( i < i)); + } + begin++; + CGAL_assertion( (*(begin.current_circulator())) == 2); + } + { + Struct_bi_circulator start(data_struct); + typedef Container_from_circulator< Struct_bi_circulator> Container; + Container X; + CGAL_assertion( X.begin() == X.end()); + Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + Container C( start); + typedef Container::iterator Iterator; + Iterator begin = C.begin(); + Iterator end = C.end(); + Assert_bidirectional_category(begin); + Assert_bidirectional_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Iterator i = begin; + (*i++).key = 4; + CGAL_assertion( 4 == (*begin).key); + CGAL_assertion( 2 == (*i).key); + (*i++).key = 3; + CGAL_assertion( 3 == (*i).key); + (*++i).key = 7; + CGAL_assertion( 7 == (*i).key); + + // Check the setting and reset these elements + // to their original values. + i = begin; + CGAL_assertion( 4 == (*i).key); + (*i).key = 1; + i++; + CGAL_assertion( 3 == (*i).key); + (*i++).key = 2; + CGAL_assertion( 3 == (*i).key); + i++; + CGAL_assertion( 7 == (*i).key); + (*i).key = 4; + + // Check the resetting. + i = begin; + int k = 1; + do { + CGAL_assertion( k == (*i).key); + ++i; + ++k; + } while (i != end); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Iterator i = end; + int su = 0; + int k = 5; + do { + Iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + begin++; + CGAL_assertion( (*(begin.current_circulator())).key == 2); + } + { + Struct_bi_const_circulator start(data_struct); + typedef Container_from_circulator< + Struct_bi_const_circulator> Container; + const Container X; + CGAL_assertion( X.begin() == X.end()); + const Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + const Container C( start); + typedef Container::const_iterator Const_iterator; + Const_iterator begin = C.begin(); + Const_iterator end = C.end(); + Assert_bidirectional_category(begin); + Assert_bidirectional_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Const_iterator z = Const_iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Const_iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Const_iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Const_iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Const_iterator i = end; + int su = 0; + int k = 5; + do { + Const_iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Const_iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + begin++; + CGAL_assertion( (*(begin.current_circulator())).key == 2); + } + { + typedef Random_access_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + typedef Container_from_circulator + Container; + Container X; + CGAL_assertion( X.begin() == X.end()); + Container Y(X); + CGAL_assertion( Y.begin() == Y.end()); + Container C( c); + typedef Container::iterator Iterator; + Iterator begin = C.begin(); + Iterator end = C.end(); + Assert_random_access_category(begin); + Assert_random_access_category(end); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Iterator i = begin; + (*i++) = 4; + CGAL_assertion( 4 == (*begin)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = begin; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = begin; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != end); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Iterator i = end; + int su = 0; + int k = 5; + do { + Iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(begin); + CGAL::Assert_circulator_or_iterator(end); + CGAL::Assert_is_at_least_forward_category(begin); + CGAL::Assert_is_at_least_forward_category(end); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Iterator z = Iterator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Iterator i = begin; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, end)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = ++i; + CGAL_assertion( i == j); + if ( i != end) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != end); // Inequality and equality checked. + } + CGAL_assertion( i == end); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = begin; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, end)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Iterator j = i++; + CGAL_assertion( i != j); + if ( i != end) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != end); + } + CGAL_assertion( i == end); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(begin); + CGAL::Assert_is_at_least_bidirectional_category(end); + // Loop backwards and pre-decrement. + Iterator i = end; + int su = 0; + int k = 5; + do { + Iterator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + + // Assignment. + i = end; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Iterator j = i--; + CGAL_assertion( i != j); + if ( j != end) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != begin); + CGAL_assertion( i == begin); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(begin); + CGAL::Assert_is_at_least_random_access_category(end); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == begin[k]); + } + int su = begin[0] + + begin[1] + + begin[2] + + begin[3] + + begin[4]; + CGAL_assertion( su == 15); + + // Jump around. + Iterator i = begin; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == begin); + Iterator j = i + 3; + CGAL_assertion( 4 == (*j)); + Iterator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == end); + Iterator ij = jj - 5; + CGAL_assertion( ij == begin); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + Iterator i = begin; + i[2] = 18; + i[4] = 9; + i[3] = 12; + CGAL_assertion( i[2] == 18); + CGAL_assertion( i[4] == 9); + CGAL_assertion( i[3] == 12); + i[2] = 3; + i[3] = 4; + i[4] = 5; + // Check the resetting. + i = begin; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != end); + } + CGAL::Assert_iterator( begin); + CGAL::Assert_iterator( end); + { // Open own scope to hide local variables. + CGAL_assertion( end - begin == 5); + CGAL_assertion( begin - end == -5); + // Relational operator. + Iterator i = begin; + ++i; + Iterator j = i; + ++j; + CGAL_assertion( begin < i); + CGAL_assertion( i < j); + CGAL_assertion( j < end); + CGAL_assertion( j > i); + CGAL_assertion( i <= j); + CGAL_assertion( j >= i); + CGAL_assertion( i <= i); + CGAL_assertion( i >= i); + + CGAL_assertion( !( i >= j)); + CGAL_assertion( !( j <= i)); + CGAL_assertion( !( i > j)); + CGAL_assertion( !( j < i)); + CGAL_assertion( !( i > i)); + CGAL_assertion( !( i < i)); + } + begin++; + CGAL_assertion( (*(begin.current_circulator())) == 2); + } + delete_nodes(data_struct); + delete[] my_C_array; +} +#ifndef CGAL_PROTECT_ALGORITHM +#include +#define CGAL_PROTECT_ALGORITHM +#endif + +void test_circulator_from_iterator() { + int* my_C_array = new_C_array(); + { + typedef Forward_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + Assert_forward_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Circulator i = c; + (*i++) = 4; + CGAL_assertion( 4 == (*c)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = c; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Forward_const_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + Assert_forward_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Bidirectional_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + Assert_bidirectional_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Circulator i = c; + (*i++) = 4; + CGAL_assertion( 4 == (*c)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = c; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Bidirectional_const_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + Assert_bidirectional_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Random_access_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + Assert_random_access_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Circulator i = c; + (*i++) = 4; + CGAL_assertion( 4 == (*c)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = c; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(c); + CGAL::Assert_is_at_least_random_access_category(c); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == c[k]); + } + int su = c[0] + + c[1] + + c[2] + + c[3] + + c[4]; + CGAL_assertion( su == 15); + + // Jump around. + Circulator i = c; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == c); + Circulator j = i + 3; + CGAL_assertion( 4 == (*j)); + Circulator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == c); + Circulator ij = jj - 5; + CGAL_assertion( ij == c); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + Circulator i = c; + i[2] = 18; + i[4] = 9; + i[3] = 12; + CGAL_assertion( i[2] == 18); + CGAL_assertion( i[4] == 9); + CGAL_assertion( i[3] == 12); + i[2] = 3; + i[3] = 4; + i[4] = 5; + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + Circulator::difference_type d = c - c; + CGAL_assertion( d == 0); + d = c - c; + CGAL_assertion( d == 0); + Circulator i = c + 1; + CGAL_assertion( c - i == 1 || c - i == -1); + CGAL_assertion( i - c == 1 || i - c == -1); + // Check minimal circulator properties. + i = i.min_circulator(); + Circulator j = i; + CGAL_assertion( j - i == 0); + j++; + CGAL_assertion( j - i == 1); + j++; + CGAL_assertion( j - i == 2); + j++; + CGAL_assertion( j - i == 3); + j++; + CGAL_assertion( j - i == 4); + j++; + CGAL_assertion( j - i == 0); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Random_access_const_circulator_from_iterator< + int*, int, std::size_t, std::ptrdiff_t> Circulator; + Circulator c( my_C_array, my_C_array+5); + Assert_random_access_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(c); + CGAL::Assert_is_at_least_random_access_category(c); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == c[k]); + } + int su = c[0] + + c[1] + + c[2] + + c[3] + + c[4]; + CGAL_assertion( su == 15); + + // Jump around. + Circulator i = c; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == c); + Circulator j = i + 3; + CGAL_assertion( 4 == (*j)); + Circulator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == c); + Circulator ij = jj - 5; + CGAL_assertion( ij == c); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + Circulator::difference_type d = c - c; + CGAL_assertion( d == 0); + d = c - c; + CGAL_assertion( d == 0); + Circulator i = c + 1; + CGAL_assertion( c - i == 1 || c - i == -1); + CGAL_assertion( i - c == 1 || i - c == -1); + // Check minimal circulator properties. + i = i.min_circulator(); + Circulator j = i; + CGAL_assertion( j - i == 0); + j++; + CGAL_assertion( j - i == 1); + j++; + CGAL_assertion( j - i == 2); + j++; + CGAL_assertion( j - i == 3); + j++; + CGAL_assertion( j - i == 4); + j++; + CGAL_assertion( j - i == 0); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + } + delete[] my_C_array; + { + // the example program `circulator_prog1.C' + typedef Random_access_circulator_from_iterator< + std::vector::iterator, + std::vector::value_type, + std::vector::size_type, + std::vector::difference_type + > Circulator; + typedef Random_access_container_from_circulator + Container; + std::vector W; + W.push_back(5); + W.push_back(2); + W.push_back(9); + Circulator ci( W.begin(), W.end()); + Container Co( ci); + std::sort( Co.begin(), Co.end()); + CGAL_assertion( W.begin()[0] == 2); + CGAL_assertion( W.begin()[1] == 5); + CGAL_assertion( W.begin()[2] == 9); + } +} +#ifndef CGAL_PROTECT_ALGORITHM +#include +#define CGAL_PROTECT_ALGORITHM +#endif + +void test_circulator_from_container() { + { + typedef Forward_circulator_from_container< std::vector > + Circulator; + Circulator c( &V); + Assert_forward_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Circulator i = c; + (*i++) = 4; + CGAL_assertion( 4 == (*c)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = c; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Forward_const_circulator_from_container > + Circulator; + Circulator c( &V); + Assert_forward_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Bidirectional_circulator_from_container< std::vector > + Circulator; + Circulator c( &V); + Assert_bidirectional_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Circulator i = c; + (*i++) = 4; + CGAL_assertion( 4 == (*c)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = c; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef + Bidirectional_const_circulator_from_container > + Circulator; + Circulator c( &V); + Assert_bidirectional_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef Random_access_circulator_from_container< std::vector > + Circulator; + Circulator c( &V); + Assert_random_access_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Circulator i = c; + (*i++) = 4; + CGAL_assertion( 4 == (*c)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = c; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(c); + CGAL::Assert_is_at_least_random_access_category(c); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == c[k]); + } + int su = c[0] + + c[1] + + c[2] + + c[3] + + c[4]; + CGAL_assertion( su == 15); + + // Jump around. + Circulator i = c; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == c); + Circulator j = i + 3; + CGAL_assertion( 4 == (*j)); + Circulator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == c); + Circulator ij = jj - 5; + CGAL_assertion( ij == c); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + Circulator i = c; + i[2] = 18; + i[4] = 9; + i[3] = 12; + CGAL_assertion( i[2] == 18); + CGAL_assertion( i[4] == 9); + CGAL_assertion( i[3] == 12); + i[2] = 3; + i[3] = 4; + i[4] = 5; + // Check the resetting. + i = c; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != c); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + Circulator::difference_type d = c - c; + CGAL_assertion( d == 0); + d = c - c; + CGAL_assertion( d == 0); + Circulator i = c + 1; + CGAL_assertion( c - i == 1 || c - i == -1); + CGAL_assertion( i - c == 1 || i - c == -1); + // Check minimal circulator properties. + i = i.min_circulator(); + Circulator j = i; + CGAL_assertion( j - i == 0); + j++; + CGAL_assertion( j - i == 1); + j++; + CGAL_assertion( j - i == 2); + j++; + CGAL_assertion( j - i == 3); + j++; + CGAL_assertion( j - i == 4); + j++; + CGAL_assertion( j - i == 0); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + typedef + Random_access_const_circulator_from_container > + Circulator; + Circulator c( &V); + Assert_random_access_category(c); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_circulator_or_iterator(c); + CGAL::Assert_is_at_least_forward_category(c); + CGAL::Assert_is_at_least_forward_category(c); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = c; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, c)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != c) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != c); // Inequality and equality checked. + } + CGAL_assertion( i == c); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, c)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != c) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != c); + } + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(c); + CGAL::Assert_is_at_least_bidirectional_category(c); + // Loop backwards and pre-decrement. + Circulator i = c; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + + // Assignment. + i = c; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != c) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != c); + CGAL_assertion( i == c); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(c); + CGAL::Assert_is_at_least_random_access_category(c); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == c[k]); + } + int su = c[0] + + c[1] + + c[2] + + c[3] + + c[4]; + CGAL_assertion( su == 15); + + // Jump around. + Circulator i = c; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == c); + Circulator j = i + 3; + CGAL_assertion( 4 == (*j)); + Circulator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == c); + Circulator ij = jj - 5; + CGAL_assertion( ij == c); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( c); + CGAL::Assert_circulator( c); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = c; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == c); + CGAL_assertion( i == c); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = c; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + Circulator::difference_type d = c - c; + CGAL_assertion( d == 0); + d = c - c; + CGAL_assertion( d == 0); + Circulator i = c + 1; + CGAL_assertion( c - i == 1 || c - i == -1); + CGAL_assertion( i - c == 1 || i - c == -1); + // Check minimal circulator properties. + i = i.min_circulator(); + Circulator j = i; + CGAL_assertion( j - i == 0); + j++; + CGAL_assertion( j - i == 1); + j++; + CGAL_assertion( j - i == 2); + j++; + CGAL_assertion( j - i == 3); + j++; + CGAL_assertion( j - i == 4); + j++; + CGAL_assertion( j - i == 0); + } + c++; + CGAL_assertion( (*(c.current_iterator())) == 2); + }{ + // the example program `circulator_prog2.C'. + typedef Random_access_circulator_from_container< std::vector > + Circulator; + typedef Random_access_container_from_circulator + Container; + typedef Container::iterator Iterator; + + std::vector 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(); + CGAL_assertion( *i == 2); + i++; + CGAL_assertion( *i == 5); + i++; + CGAL_assertion( *i == 9); + i++; + CGAL_assertion( i == container.end()); + }{ + // An example program applying sort() through two adaptors. + typedef Random_access_circulator_from_container< std::vector > + Circulator; + typedef Random_access_container_from_circulator + Container; + std::vector 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()); + CGAL_assertion( v.begin()[0] == 2); + CGAL_assertion( v.begin()[1] == 5); + CGAL_assertion( v.begin()[2] == 9); + } +} + + +int main(){ + init_global_data(); + test_tags(); + test_iterator_and_circulators(); + test_functions_for_circulators(); + + test_container_from_circulator(); + test_circulator_from_iterator(); + test_circulator_from_container(); + clean_global_data(); + return 0; +} +// EOF // diff --git a/Packages/Circulator/test/Circulator/test_circ2.C b/Packages/Circulator/test/Circulator/test_circ2.C new file mode 100644 index 00000000000..a7ad549198c --- /dev/null +++ b/Packages/Circulator/test/Circulator/test_circ2.C @@ -0,0 +1,2198 @@ +// ============================================================================ +// +// 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 : $CGAL_Revision: $ +// release_date : $CGAL_Date: $ +// +// file : test_circ2.C +// chapter : $CGAL_Chapter: Circulators $ +// package : $CGAL_Package: Circulator 3.4 (02 Sep 1999) $ +// source : circulator.fw +// revision : $Revision$ +// revision_date : $Date$ +// author(s) : Lutz Kettner +// +// coordinator : INRIA, Sophia Antipolis +// +// Test support to build own circulators. +// ============================================================================ + + +#ifndef CGAL_BASIC_H +#include +#endif // CGAL_BASIC_H +#ifndef CGAL_PROTECT_CSTDDEF +#include +#define CGAL_PROTECT_CSTDDEF +#endif +#ifndef CGAL_PROTECT_ITERATOR +#include +#define CGAL_PROTECT_ITERATOR +#endif +#ifndef CGAL_PROTECT_LIST +#include +#define CGAL_PROTECT_LIST +#endif +#ifndef CGAL_PROTECT_VECTOR +#include +#define CGAL_PROTECT_VECTOR +#endif +#ifndef CGAL_CIRCULATOR_IMPL_H +#include +#endif // CGAL_CIRCULATOR_IMPL_H + +using namespace CGAL; + +// Global data structures. +std::list L; +std::vector V; +// int* C_array; // Gnu gcov produces a core here! + +// Workaround +int* new_C_array() { + int* p = new int[5]; + for ( int i = 1; i <= 5; i++) { + p[i-1] = i; + } + return p; +} + +// Build a simple 'n'-element circular structure using struct's. +struct Node { + int key; + Node* next; + Node* prev; + Node() : key(0), next(this), prev( this) {} + Node( int n) : key(n), next(this), prev( this) {} + Node( Node* _nx, Node* _pv, int n) + : key(n), next(_nx), prev( _pv) {} +}; +Node* new_node( Node* _nx, Node* _pv, int n) { + return new Node( _nx, _pv, n); +} +void append_node( Node* p, int n) { + Node* q = new_node( p, p->prev, n); + p->prev->next = q; + p->prev = q; +} +Node* generate_nodes( int n) { + CGAL_assertion( n > 0); + Node* p = new Node(1); + for ( int i = 2; i <= n; i++) + append_node( p, i); + return p; +} +void delete_nodes( Node* p) { + Node* end = p; + Node* q = p; + p = p->next; + while ( p != end) { + delete q; + q = p; + p = p->next; + } + delete q; +} + +typedef CGAL::Forward_circulator_over_struct< Node> + Struct_circulator; +typedef CGAL::Forward_const_circulator_over_struct< Node> + Struct_const_circulator; +typedef CGAL::Bidirectional_circulator_over_struct< Node> + Struct_bi_circulator; +typedef CGAL::Bidirectional_const_circulator_over_struct< Node> + Struct_bi_const_circulator; + +// Build a simple 'n'-element circular structure using struct's. +class CNode { + CNode* _next; + CNode* _prev; + public: + int key; + CNode* next() { return _next;} + const CNode* next() const { return _next;} + CNode* prev() { return _prev;} + const CNode* prev() const { return _prev;} + CNode() : _next(this), _prev( this), key(0) {} + CNode( int n) : _next(this), _prev( this), key(n) {} + CNode( CNode* _nx, CNode* _pv, int n) + : _next(_nx), _prev( _pv), key(n) {} + friend CNode* new_cnode( CNode* _nx, CNode* _pv, int n); + friend void append_cnode( CNode* p, int n); + friend void delete_cnodes( CNode* p); +}; +CNode* new_cnode( CNode* _nx, CNode* _pv, int n) { + return new CNode( _nx, _pv, n); +} +void append_cnode( CNode* p, int n) { + CNode* q = new_cnode( p, p->_prev, n); + p->_prev->_next = q; + p->_prev = q; +} +CNode* generate_cnodes( int n) { + CGAL_assertion( n > 0); + CNode* p = new CNode(1); + for ( int i = 2; i <= n; i++) + append_cnode( p, i); + return p; +} +void delete_cnodes( CNode* p) { + CNode* end = p; + CNode* q = p; + p = p->_next; + while ( p != end) { + delete q; + q = p; + p = p->_next; + } + delete q; +} + +typedef CGAL::Forward_circulator_over_class< CNode> + Class_circulator; +typedef CGAL::Forward_const_circulator_over_class< CNode> + Class_const_circulator; +typedef CGAL::Bidirectional_circulator_over_class< CNode> + Class_bi_circulator; +typedef CGAL::Bidirectional_const_circulator_over_class< CNode> + Class_bi_const_circulator; + + +void init_global_data() { + // C_array = new int[5]; + for ( int i = 1; i <= 5; i++) { + L.push_back(i); + V.push_back(i); + // C_array[i-1] = i; + } +} + +void clean_global_data() { + //delete[] C_array; +} + +// Test value type and distance type. +int test_value_type( int*) { return 1;} +int test_value_type( Node*) { return 1;} +int test_value_type( CNode*) { return 1;} +int test_value_type( char*) { return 2;} +int test_value_type( double*) { return 3;} + +int test_difference_type( std::ptrdiff_t*) { return 1;} +int test_difference_type( char*) { return 2;} +int test_difference_type( double*) { return 3;} +void test_struct(){ + Node* data_struct = generate_nodes( 5); + { + Struct_circulator start(data_struct); + Assert_forward_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Struct_circulator z = Struct_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Struct_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Struct_circulator i = start; + (*i++).key = 4; + CGAL_assertion( 4 == (*start).key); + CGAL_assertion( 2 == (*i).key); + (*i++).key = 3; + CGAL_assertion( 3 == (*i).key); + (*++i).key = 7; + CGAL_assertion( 7 == (*i).key); + + // Check the setting and reset these elements + // to their original values. + i = start; + CGAL_assertion( 4 == (*i).key); + (*i).key = 1; + i++; + CGAL_assertion( 3 == (*i).key); + (*i++).key = 2; + CGAL_assertion( 3 == (*i).key); + i++; + CGAL_assertion( 7 == (*i).key); + (*i).key = 4; + + // Check the resetting. + i = start; + int k = 1; + do { + CGAL_assertion( k == (*i).key); + ++i; + ++k; + } while (i != start); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Struct_circulator::value_type k1; + k1.key = 1; + Struct_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Struct_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Struct_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Struct_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Struct_circulator z = Struct_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Struct_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Struct_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + }{ + Struct_const_circulator start(data_struct); + Assert_forward_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Struct_const_circulator z = Struct_const_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Struct_const_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_const_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_const_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Struct_const_circulator::value_type k1; + k1.key = 1; + Struct_const_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Struct_const_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Struct_const_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Struct_const_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Struct_const_circulator z = Struct_const_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Struct_const_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Struct_const_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + }{ + Struct_bi_circulator start(data_struct); + Assert_bidirectional_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Struct_bi_circulator z = Struct_bi_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Struct_bi_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_bi_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_bi_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Struct_bi_circulator i = start; + (*i++).key = 4; + CGAL_assertion( 4 == (*start).key); + CGAL_assertion( 2 == (*i).key); + (*i++).key = 3; + CGAL_assertion( 3 == (*i).key); + (*++i).key = 7; + CGAL_assertion( 7 == (*i).key); + + // Check the setting and reset these elements + // to their original values. + i = start; + CGAL_assertion( 4 == (*i).key); + (*i).key = 1; + i++; + CGAL_assertion( 3 == (*i).key); + (*i++).key = 2; + CGAL_assertion( 3 == (*i).key); + i++; + CGAL_assertion( 7 == (*i).key); + (*i).key = 4; + + // Check the resetting. + i = start; + int k = 1; + do { + CGAL_assertion( k == (*i).key); + ++i; + ++k; + } while (i != start); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Struct_bi_circulator z = Struct_bi_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Struct_bi_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_bi_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_bi_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(start); + CGAL::Assert_is_at_least_bidirectional_category(start); + // Loop backwards and pre-decrement. + Struct_bi_circulator i = start; + int su = 0; + int k = 5; + do { + Struct_bi_circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Struct_bi_circulator j = i--; + CGAL_assertion( i != j); + if ( j != start) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Struct_bi_circulator::value_type k1; + k1.key = 1; + Struct_bi_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Struct_bi_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Struct_bi_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Struct_bi_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Struct_bi_circulator z = Struct_bi_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Struct_bi_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Struct_bi_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Struct_bi_circulator i = start; + ++i; + Struct_bi_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + }{ + Struct_bi_const_circulator start(data_struct); + Assert_bidirectional_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Struct_bi_const_circulator z = Struct_bi_const_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Struct_bi_const_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_bi_const_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Struct_bi_const_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(start); + CGAL::Assert_is_at_least_bidirectional_category(start); + // Loop backwards and pre-decrement. + Struct_bi_const_circulator i = start; + int su = 0; + int k = 5; + do { + Struct_bi_const_circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Struct_bi_const_circulator j = i--; + CGAL_assertion( i != j); + if ( j != start) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Struct_bi_const_circulator::value_type k1; + k1.key = 1; + Struct_bi_const_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Struct_bi_const_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Struct_bi_const_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Struct_bi_const_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Struct_bi_const_circulator z = Struct_bi_const_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Struct_bi_const_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Struct_bi_const_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Struct_bi_const_circulator i = start; + ++i; + Struct_bi_const_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + } + delete_nodes(data_struct); +} +void test_class(){ + CNode* data_struct = generate_cnodes( 5); + { + Class_circulator start(data_struct); + Assert_forward_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Class_circulator z = Class_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Class_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Class_circulator i = start; + (*i++).key = 4; + CGAL_assertion( 4 == (*start).key); + CGAL_assertion( 2 == (*i).key); + (*i++).key = 3; + CGAL_assertion( 3 == (*i).key); + (*++i).key = 7; + CGAL_assertion( 7 == (*i).key); + + // Check the setting and reset these elements + // to their original values. + i = start; + CGAL_assertion( 4 == (*i).key); + (*i).key = 1; + i++; + CGAL_assertion( 3 == (*i).key); + (*i++).key = 2; + CGAL_assertion( 3 == (*i).key); + i++; + CGAL_assertion( 7 == (*i).key); + (*i).key = 4; + + // Check the resetting. + i = start; + int k = 1; + do { + CGAL_assertion( k == (*i).key); + ++i; + ++k; + } while (i != start); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Class_circulator::value_type k1; + k1.key = 1; + Class_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Class_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Class_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Class_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Class_circulator z = Class_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Class_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Class_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + }{ + Class_const_circulator start(data_struct); + Assert_forward_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Class_const_circulator z = Class_const_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Class_const_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_const_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_const_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Class_const_circulator::value_type k1; + k1.key = 1; + Class_const_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Class_const_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Class_const_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Class_const_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Class_const_circulator z = Class_const_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Class_const_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Class_const_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + }{ + Class_bi_circulator start(data_struct); + Assert_bidirectional_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Class_bi_circulator z = Class_bi_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Class_bi_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_bi_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_bi_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Class_bi_circulator i = start; + (*i++).key = 4; + CGAL_assertion( 4 == (*start).key); + CGAL_assertion( 2 == (*i).key); + (*i++).key = 3; + CGAL_assertion( 3 == (*i).key); + (*++i).key = 7; + CGAL_assertion( 7 == (*i).key); + + // Check the setting and reset these elements + // to their original values. + i = start; + CGAL_assertion( 4 == (*i).key); + (*i).key = 1; + i++; + CGAL_assertion( 3 == (*i).key); + (*i++).key = 2; + CGAL_assertion( 3 == (*i).key); + i++; + CGAL_assertion( 7 == (*i).key); + (*i).key = 4; + + // Check the resetting. + i = start; + int k = 1; + do { + CGAL_assertion( k == (*i).key); + ++i; + ++k; + } while (i != start); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Class_bi_circulator z = Class_bi_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Class_bi_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_bi_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_bi_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(start); + CGAL::Assert_is_at_least_bidirectional_category(start); + // Loop backwards and pre-decrement. + Class_bi_circulator i = start; + int su = 0; + int k = 5; + do { + Class_bi_circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Class_bi_circulator j = i--; + CGAL_assertion( i != j); + if ( j != start) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Class_bi_circulator::value_type k1; + k1.key = 1; + Class_bi_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Class_bi_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Class_bi_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Class_bi_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Class_bi_circulator z = Class_bi_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Class_bi_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Class_bi_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Class_bi_circulator i = start; + ++i; + Class_bi_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + }{ + Class_bi_const_circulator start(data_struct); + Assert_bidirectional_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Class_bi_const_circulator z = Class_bi_const_circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Class_bi_const_circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_bi_const_circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i).key); + su += (*i).key; + ++k; + Class_bi_const_circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i).key == (*j).key + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(start); + CGAL::Assert_is_at_least_bidirectional_category(start); + // Loop backwards and pre-decrement. + Class_bi_const_circulator i = start; + int su = 0; + int k = 5; + do { + Class_bi_const_circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i).key == (*j).key); + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Class_bi_const_circulator j = i--; + CGAL_assertion( i != j); + if ( j != start) { + CGAL_assertion( (*i).key == (*j).key - 1); + } + CGAL_assertion( k == (*i).key); + su += (*i).key; + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Class_bi_const_circulator::value_type k1; + k1.key = 1; + Class_bi_const_circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2.key == 1); + Class_bi_const_circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1).key == 1); + k1.key = 3; + CGAL_assertion( k1.key == 3); + CGAL_assertion( k2.key == 3); + CGAL_assertion( (*p1).key == 3); + k1.key = 6; + CGAL_assertion( k1.key == 6); + CGAL_assertion( k2.key == 6); + CGAL_assertion( (*p1).key == 6); + Class_bi_const_circulator::size_type s = 5; + CGAL_assertion( s == 5); + Class_bi_const_circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Class_bi_const_circulator z = Class_bi_const_circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Class_bi_const_circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Class_bi_const_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Class_bi_const_circulator i = start; + ++i; + Class_bi_const_circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + } + delete_cnodes(data_struct); +} +void test_array() { + { + typedef Circulator_over_array< + std::vector, + std::vector::value_type, + std::vector::size_type, + std::vector::difference_type + > Circulator; + Circulator start( V, V.size()); + Assert_random_access_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Change three elements and check post-/pre-increment. + Circulator i = start; + (*i++) = 4; + CGAL_assertion( 4 == (*start)); + CGAL_assertion( 2 == (*i)); + (*i++) = 3; + CGAL_assertion( 3 == (*i)); + (*++i) = 7; + CGAL_assertion( 7 == (*i)); + + // Check the setting and reset these elements + // to their original values. + i = start; + CGAL_assertion( 4 == (*i)); + (*i) = 1; + i++; + CGAL_assertion( 3 == (*i)); + (*i++) = 2; + CGAL_assertion( 3 == (*i)); + i++; + CGAL_assertion( 7 == (*i)); + (*i) = 4; + + // Check the resetting. + i = start; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != start); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(start); + CGAL::Assert_is_at_least_bidirectional_category(start); + // Loop backwards and pre-decrement. + Circulator i = start; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != start) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(start); + CGAL::Assert_is_at_least_bidirectional_category(start); + // Loop backwards and pre-decrement. + Circulator i = start; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != start) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(start); + CGAL::Assert_is_at_least_random_access_category(start); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == start[k]); + } + int su = start[0] + + start[1] + + start[2] + + start[3] + + start[4]; + CGAL_assertion( su == 15); + + // Jump around. + Circulator i = start; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == start); + Circulator j = i + 3; + CGAL_assertion( 4 == (*j)); + Circulator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == start); + Circulator ij = jj - 5; + CGAL_assertion( ij == start); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + Circulator i = start; + i[2] = 18; + i[4] = 9; + i[3] = 12; + CGAL_assertion( i[2] == 18); + CGAL_assertion( i[4] == 9); + CGAL_assertion( i[3] == 12); + i[2] = 3; + i[3] = 4; + i[4] = 5; + // Check the resetting. + i = start; + int k = 1; + do { + CGAL_assertion( k == (*i)); + ++i; + ++k; + } while (i != start); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = start; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + Circulator::difference_type d = start - start; + CGAL_assertion( d == 0); + d = start - start; + CGAL_assertion( d == 0); + Circulator i = start + 1; + CGAL_assertion( start - i == 1 || start - i == -1); + CGAL_assertion( i - start == 1 || i - start == -1); + // Check minimal circulator properties. + i = i.min_circulator(); + Circulator j = i; + CGAL_assertion( j - i == 0); + j++; + CGAL_assertion( j - i == 1); + j++; + CGAL_assertion( j - i == 2); + j++; + CGAL_assertion( j - i == 3); + j++; + CGAL_assertion( j - i == 4); + j++; + CGAL_assertion( j - i == 0); + } + }{ + typedef Const_circulator_over_array< + std::vector, + std::vector::value_type, + std::vector::size_type, + std::vector::difference_type + > Circulator; + const std::vector& W = V; + Circulator start( W, W.size()); + Assert_random_access_category(start); + { // Open own scope to hide local variables. + // Check generally correct parameter properties. + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_circulator_or_iterator(start); + CGAL::Assert_is_at_least_forward_category(start); + CGAL::Assert_is_at_least_forward_category(start); + typedef std::iterator_traits I_Traits; + typedef I_Traits::value_type I_value_type; + typedef I_Traits::difference_type I_difference_type; + CGAL_assertion(1==test_value_type( (I_value_type*)(0))); + CGAL_assertion(1==test_difference_type( (I_difference_type*)(0))); + + // Default constructor. + Circulator z = Circulator(); + CGAL::Assert_circulator_or_iterator(z); + // Copy constructor. + Circulator i = start; + + // Check general support for circulators and iterators. + CGAL_assertion( CGAL::is_empty_range( z, z)); + CGAL_assertion( ! CGAL::is_empty_range( i, start)); + + int su = 0; + int k = 1; + // Check general loop, pre-increment, dereference. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = ++i; + CGAL_assertion( i == j); + if ( i != start) { + CGAL_assertion( (*i) == (*j)); + } + } while (i != start); // Inequality and equality checked. + } + CGAL_assertion( i == start); // Equality checked. + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 1; + // Loop with post increment. + if (! CGAL::is_empty_range( i, start)) { // superfluous + do { + CGAL_assertion( k == (*i)); + su += (*i); + ++k; + Circulator j = i++; + CGAL_assertion( i != j); + if ( i != start) { + CGAL_assertion( (*i) == (*j) + 1); + } + } while (i != start); + } + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_bidirectional_category(start); + CGAL::Assert_is_at_least_bidirectional_category(start); + // Loop backwards and pre-decrement. + Circulator i = start; + int su = 0; + int k = 5; + do { + Circulator j = --i; + CGAL_assertion( i == j); + CGAL_assertion( (*i) == (*j)); + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + + // Assignment. + i = start; + su = 0; + k = 5; + // Loop with post-decrement. + do { + Circulator j = i--; + CGAL_assertion( i != j); + if ( j != start) { + CGAL_assertion( (*i) == (*j) - 1); + } + CGAL_assertion( k == (*i)); + su += (*i); + --k; + } while (i != start); + CGAL_assertion( i == start); + CGAL_assertion( su == 15); + } + { // Open own scope to hide local variables. + CGAL::Assert_is_at_least_random_access_category(start); + CGAL::Assert_is_at_least_random_access_category(start); + // Random access. + int k; + for( k = 0; k < 5; k++) { + CGAL_assertion( 1+k == start[k]); + } + int su = start[0] + + start[1] + + start[2] + + start[3] + + start[4]; + CGAL_assertion( su == 15); + + // Jump around. + Circulator i = start; + i += 3; + CGAL_assertion( 4 == (*i)); + i -= 2; + CGAL_assertion( 2 == (*i)); + i += 3; + CGAL_assertion( 5 == (*i)); + i -= 4; + CGAL_assertion( 1 == (*i)); + CGAL_assertion( i == start); + Circulator j = i + 3; + CGAL_assertion( 4 == (*j)); + Circulator jj = j - 2; + CGAL_assertion( 2 == (*jj)); + jj = 4 + jj; + CGAL_assertion( jj == start); + Circulator ij = jj - 5; + CGAL_assertion( ij == start); + + // Difference test. + CGAL_assertion( jj - i == 5 || jj - i == 0); + CGAL_assertion( i + (j-i) == j); + CGAL_assertion( (j-i) + i == j); + } + { // Open own scope to hide local variables. + CGAL::Assert_circulator( start); + CGAL::Assert_circulator( start); + + // Check the local type parameters. + Circulator::value_type k1; + k1 = 1; + Circulator::reference k2 = k1; + (void)k2; + CGAL_assertion( k2 == 1); + Circulator::pointer p1 = &k1; + (void)p1; + CGAL_assertion( (*p1) == 1); + k1 = 3; + CGAL_assertion( k1 == 3); + CGAL_assertion( k2 == 3); + CGAL_assertion( (*p1) == 3); + k1 = 6; + CGAL_assertion( k1 == 6); + CGAL_assertion( k2 == 6); + CGAL_assertion( (*p1) == 6); + Circulator::size_type s = 5; + CGAL_assertion( s == 5); + Circulator::difference_type d = -5; + CGAL_assertion( d == -5); + + // Check tests for empty data structures. + Circulator z = Circulator(); + CGAL_assertion( z == CGAL_CIRC_NULL); + CGAL_assertion( ! (z != CGAL_CIRC_NULL)); + Circulator i = start; + CGAL_assertion( ! (i == CGAL_CIRC_NULL)); + CGAL_assertion( i != CGAL_CIRC_NULL); + CGAL_assertion( i == start); + CGAL_assertion( i == start); + // Do I reach myself. + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + ++i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + // Do I reach myself backwards. + Circulator i = start; + ++i; + Circulator j = i; + int k = 0; + do { + CGAL_assertion( k < 5); + ++k; + --i; + } while( i != j); + CGAL_assertion( k == 5); + } + { // Open own scope to hide local variables. + Circulator::difference_type d = start - start; + CGAL_assertion( d == 0); + d = start - start; + CGAL_assertion( d == 0); + Circulator i = start + 1; + CGAL_assertion( start - i == 1 || start - i == -1); + CGAL_assertion( i - start == 1 || i - start == -1); + // Check minimal circulator properties. + i = i.min_circulator(); + Circulator j = i; + CGAL_assertion( j - i == 0); + j++; + CGAL_assertion( j - i == 1); + j++; + CGAL_assertion( j - i == 2); + j++; + CGAL_assertion( j - i == 3); + j++; + CGAL_assertion( j - i == 4); + j++; + CGAL_assertion( j - i == 0); + } + } +} + + +int main(){ + init_global_data(); + test_struct(); + test_class(); + test_array(); + clean_global_data(); + return 0; +} +// EOF // diff --git a/Packages/Circulator/version b/Packages/Circulator/version new file mode 100644 index 00000000000..22e4017bf14 --- /dev/null +++ b/Packages/Circulator/version @@ -0,0 +1 @@ +3.4 (02 Sep 1999)