% ============================================================================= % The CGAL Developers' Manual % Chapter: Iterators and Circulators (and Handles) % ----------------------------------------------------------------------------- % file : iterators_and_circulators.tex % authors: Mariette Yvinec % ----------------------------------------------------------------------------- % $Revision$ % $Date$ % ============================================================================= \chapter{Iterators and Circulators (and Handles)} \label{chap:iterators_and_circulators} \ccIndexMainItemBegin{iterators} \ccIndexMainItemBegin{circulators} \ccIndexMainItemBegin{\stl} \ccChapterRelease{Chapter Version: 1.0} \\ \ccChapterAuthor{Mariette Yvinec ({\tt yvinec@sophia.inria.fr})} \ccAnchor{http://www.cgal.org/Manual/doc_html/use_of_stl/Chapter_Iterator.html}{Iterators} \ccIndexMainItemDef{iterators} are a generalization of pointers that allow a programmer to work with different data structures (containers) in a uniform manner. An iterator is the glue that allows one to write a single implementation of an algorithm that will work for data contained in an array, a list or some other container -- even a container that did not yet exist when the algorithm was implemented. The concept of an iterator is one of the major tools of the genericity in \stl. Iterators are used almost everywhere in the \stl\ to achieve the communication between containers and algorithms. Iterators are widely used in \cgal\ too. \cgal\ extends the idea of the iterator, which works for linear data structures, to circular data structures by defining the concept of a circulator. \ccAnchor{http://www.cgal.org/Manual/doc_html/use_of_stl/Chapter_Circulator_stl.html}{Circulators} \ccIndexMainItemDef{circulators} are quite similar to iterators, with the major difference being the absence of a past-the-end position in a sequence. Note that circulators are NOT part of the \stl, but of \cgal. \ccIndexMainItemBegin{handles} In \cgal, we also define the concept of a handle, \ccIndexMainItemDef{handles} which bahaves roughly like a pointer to an object without an increment or decrement operation. More details about handles and their requirements can be found in the \ccAnchor{http://www.cgal.org/Manual/doc_html/frameset/fsSupport.html}{\cgal\ Support Library Reference Manual}. Section~\ref{sec:handle_vs_it_vs_circ} below discusses when handles should be used in your code. \ccIndexMainItemEnd{handles} The concept of iterators is relatively well described in textbooks such as Stroustrup's {\em The C++ Programming Langage} \cite{Stroustrup97} and Austern's {\em Generic Programming and the \stl} \cite{Austern98} and in the \ccAnchor{http://www.cgal.org/Manual/doc_html/frameset/fsUseOfSTL.html}{Use of \stl\ and \stl\ Extensions in \cgal\ } manual (which also discusses the circulator concept). Thus we will not give a full description of this concept here but only a few hints about how to use and write iterators (and circulators) in \cgal. Developers should consult the above-mentioned references to become familiar with the iterator and circulator concepts in general and, in particular, iterator and circulator ranges, dereferencable and past-the-end values, mutable and constant iterators and circulators, and the different categories (forward, bidirectional, random-access, \etc) of iterators and circulators. \section{Iterator and circulator traits} \label{sec:iterator_traits} \ccIndexMainItemBegin{iterator traits} The algorithms working with iterators and/or circulators often need to refer to types associated with the iterator or circulator (\eg, the type of the object referred to by the iterator or the type of the distance between two circulators). These types are usually declared in the iterator or circulator classes. However, for pointer classes, which can be valid models of the iterator and circulator concepts, this not possible. Thus iterator traits have been introduced to resolve this problem. An algorithm using an iterator of the type \ccc{Iter} will find the relevant types in an instantiation of a small templated class \ccc{iterator_traits}. There is a general templated version of \ccc{iterator_traits} that looks like: \begin{verbatim} template struct iterator_traits { typedef typename Iter::iterator_category iterator_category ; typedef typename Iter::value_type value_type; typedef typename Iter::difference_type difference_type; typedef typename Iter::pointer pointer; typedef typename Iter::reference reference; }; \end{verbatim} and a partial specialization of \ccc{iterator_traits} classes for pointers: \ccIndexSubitem{iterator traits}{for pointers} \begin{verbatim} template struct iterator_traits { typedef random_access_iterator iterator_category ; typedef T value_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef T& reference; }; \end{verbatim} Iterators traits are not fully supported by compilers, such as MS Visual \CC, that do not allow partial specialization \ccIndexSubitem{partial specialization}{for iterator traits} This means that, when using these compilers, the class \ccc{iterator_traits} has to be be explicitely instantiated whenever \ccc{} is a C pointer. \cgal\ provides these instantiations for pointers to the most commonly used primitive data types, number types and \cgal\ kernel types (\ccc{CGAL::Point_2}, \ccc{CGAL::Segment_2}, \etc). For other types, the user must provide the relevant iterator traits. This can be done by using the macro \texttt{CGAL\_\-DEFINE\_\-ITERATOR\_\-TRAITS\_\-POINTER\_\-SPEC(T)}. \index{CGAL_DEFINE_ITERATOR_TRAITS_POINTER_SPEC macro@\texttt{CGAL\_DEFINE\_ITERATOR\_TRAITS\_POINTER\_SPEC} macro} Take care that this macro is used only once for a particular type \ccc{T}; otherwise you will get complaints about multiple definitions of a class. If the parameter to this macro is a templated class with more than one template parameter such as this: \begin{center} \verb|CGAL::PointH2< CGAL::Quotient, int >| \end{center} the compiler may not be able to parse this properly as a single argument for the macro. It will instead read the comma as a separator for the arguments of the macro and thus assume you have provided more arguments than are necessary for this one-argument macro. However, this is easily gotten around by first using a typedef as follows: \begin{verbatim} typedef CGAL::PointH2< CGAL::Quotient, int > Blah; CGAL_DEFINE_ITERATOR_TRAITS_POINTER_SPEC(Blah) \end{verbatim} The only currently supported compiler (as of release 2.3) that does not support partial specialization is MS Visual \CC 6.0. Thus this macro is defined to have an effect only when using this compiler. For all other compilers, it simply does nothing and thus can be safely left in the code, unprotected by checks for this compiler. %The example program \texttt{examples/Getting\_started/advanced\_hull.C} %contains an example of the use of this macro.\\ \ccIndexMainItemEnd{iterator traits} \section{Input and output iterators} \label{sec:input_and_output_iterators} \ccIndexSubitemBegin{iterators}{input} \ccIndexSubitemBegin{iterators}{output} {\bf Operator * for input and output iterators} \ccIndexSubsubitemBegin{iterators}{input}{dereferencing} \ccIndexSubsubitemBegin{iterators}{output}{dereferencing} The operator * of input and output iterators has a restricted semantics. Input iterators are designed for input operations, and it is not required that the value type \ccc{T} of an input iterator \ccc{it} be assignable. Thus, while assignments of the type \ccc{t = *it} are the usual way to get values from the input iterators, statements like \ccc{*it = ...} are likely to be illegal. On the other hand, output iterators are designed for write operations, and the only legal use of the operator * of an output iterator \ccc{it} is in the assignement \ccc{ *it = ....}. The code of a standard copy function of the \stl\ provides an example of both of these operations: \lcRawHtml{} \begin{verbatim} template< class InputIterator, class OutputIterator> OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result) { while (first != last) { *result = *first; ++first; ++result; } return result; } \end{verbatim} \lcRawHtml{} The first two arguments of \ccc{copy} are of type \ccc{InputIterator} (meaning any type that fulfills the requirements for an input iteraor) while the third one is of type \ccc{OutputIterator}. If these types were exchanged, then the statement \ccc{*result = *first;} might not be valid. \ccIndexSubsubitemEnd{iterators}{input}{dereferencing} \ccIndexSubsubitemEnd{iterators}{output}{dereferencing} {\bf Stream iterators} \ccIndexSubitemBegin{iterators}{stream} \stl\ provides a special type of input iterator called \ccc{istream_iterator}, \ccIndexMainItem{\ccFont istream_iterator} which is designed to be bound to an object of the class \ccc{istream} and provides a way to read a sequence of values from the input stream to which it is bound. For example, the following code reads numbers of type \ccc{double} from the standard input stream \ccc{cin} and computes their sum. \begin{verbatim} istream_iterator it(cin); istream_iterator end(); double sum=0.0; while(it != end) { sum += *it; ++it; } cout << sum << endl; \end{verbatim} In a similar fashion, \stl\ provides the type \ccc{ostream_iterator}, \ccIndexMainItem{\ccFont ostream_iterator} which is designed to be bound to an object of the class \ccc{ostream} and used to output values to the output stream to which it is bound. \ccIndexSubitem{\ccFont ostream_iterator}{extension} \cgal\ provides extensions of the classes \ccc{istream_iterator} and \ccc{ostream_iterator}. The class \ccc{CGAL::Ostream_iterator} is an output iterator adaptator for the stream class \ccc{Stream} and value \ccIndexSubitem{adaptor}{output iterator} type \ccc{T}. It provides output iterators that can be used to ouput values of type \ccc{T} to objects of the class \ccc{Stream}. For example, the following code fragment inserts a list of segments into a window stream (\ie, it draws the segments in the window) using the standard copy function: \begin{verbatim} typedef CGAL::Cartesian K; typedef K::Segment_2 Segment; std::vector segments; CGAL::Window_stream W( 400, 400); int main (int argc, char** argv) { // initialize segments std::copy( segments.begin(), segments.end(), CGAL::Ostream_iterator< Segment, CGAL::Window_stream>( W)); } \end{verbatim} \ccIndexSubitem{\ccFont istream_iterator}{extension} \ccIndexSubitem{adaptor}{input iterator} Likewise, the class \ccc{CGAL::Istream_iterator} is an input iterator adaptor for the stream class \ccc{Stream} and value type \ccc{T}. These adaptors are particularly useful for stream classes that are similar to but not derived from \ccc{std::istream} and \ccc{std::ostream}. The only requirements of the stream classes are that they define \ccc{operator>>} (for \ccc{Istream_iterator}) and \ccc{operator<<} (for \ccc{Ostream_iterator}). \ccIndexSubitemEnd{iterators}{stream} {\bf Insert iterators} \ccIndexSubitemBegin{iterators}{insert} \ccIndexSubitem{iterators}{output} Insert iterators are output iterators that can be used to insert items into containers.\ccIndexSubitem{containers}{insertion into} With regular iterator classes, the code given above for the \ccAnchor{#copy_function}{\ccc{copy} function} of \stl, causes the range \ccc{[first,last)} to be copied into an existing range starting with \ccc{result}. No memory allocation is involved and the existing range is overwritten. With an insert iterator supplied as the third argument, the same code will cause elements to be inserted into the container with which the output iterator is associated. That is, new memory may be allocated for these inserted elements. The \stl\ provides three kinds of insert iterators: \ccc{insert_iterator}s, \ccc{back_insert_iterator}s and \ccc{front_insert_iterator}s. The \ccc{back_inserter_iterator}s are used to insert elements at the end of a container by using the \ccc{push_back} member function of the container. Similarly, \ccc{front_insert_iterator}s are used to insert elements at the beginning of a container by using the container's \ccc{push_front} function. The general \ccc{insert_iterator} is used to insert elements at any point in a container, by using the container's \ccc{insert} member function and a provided location of the insertion. \ccIndexSubitem{containers}{insertion into} For convenience, \stl\ provides the templated functions (or adaptors) \ccc{front_inserter}, \ccIndexMainItem{\ccFont front_inserter} \ccc{back_inserter} \ccIndexMainItem{\ccFont back_inserter} \ccIndexSubitem{adaptor}{for insert iterators} and \ccc{inserter} to get inserters from containers. \ccIndexMainItem{\ccFont inserter} \ccIndexSubitem{containers}{insertion adaptors} \begin{verbatim} template insert_iterators inserter(Container& c, Iterator it); template back_insert_iterators back_inserter(Container& c); template front_insert_iterators front_inserter(Container& c); \end{verbatim} Thus, the \ccc{inserter} adaptor can be called for any container that has an \ccc{insert} member function, and \ccc{back_inserter} (resp. \ccc{front_inserter}) can be called for any container that has a \ccc{push_back} (resp. \ccc{push_front}) member function. Some versions of \stl\ (in particular, the one of KCC and Borland) also require that containers define a \ccc{value_type} and a \ccc{const_reference} type. The following code will insert 200 copies of the value 7 at the end of \ccc{vec}. \begin{verbatim} void g(vector& vec) { fill_n(std::back_inserter(vec),200,7); } \end{verbatim} and this code will insert the points contained in the vector \ccc{vertices} into a Delaunay triangulation data structure: \begin{verbatim} typedef CGAL::Cartesian K; typedef CGAL::Triangulation_euclidean_traits_2 Gt; typedef CGAL::Triangulation_vertex_base_2 Vb; typedef CGAL::Triangulation_face_base_2 Fb; typedef CGAL::Triangulation_default_data_structure_2 Tds; typedef CGAL::Delaunay_triangulation_2 DT; DT triangulation; std::copy( vertices.begin(), vertices.end(), std::back_inserter( triangulation )); \end{verbatim} \ccIndexSubitemEnd{iterators}{insert} \ccIndexSubitemEnd{iterators}{input} \ccIndexSubitemEnd{iterators}{output} \ccIndexMainItemEnd{iterators} \ccIndexMainItemEnd{circulators} \ccIndexMainItemEnd{\stl} %\section{Handles} %\label{sec:handles} %\ccIndexMainItemBegin{handles} % %The concept of an iterator is actually a generalization of the concept %of a handle, which is defined in \cgal\ (but not in \stl). A handle %behaves roughly like a pointer to an object without an increment or %decrement operation. The requirements for handles are detailed in %the \ccAnchor{http://www.cgal.org/Manual/doc_html/support_lib/contents}{\cgal\ Support Library Reference Manual}. %\ccIndexMainItemEnd{handles} \section{Writing code with and for iterators, circulators, and handles} Because you should write generic code for \cgal, algorithms that require a sequence of data for input should be written to take an iterator (or circulator) range as input instead of, say, a particular container. Similarly, algorithms that compute a sequence of data as output should place the output data into an output iterator range. Both of these points are illustrated by the prototype of the following function that computes the convex hull of a set of points in two dimensions: \ccFunction{template OutputIterator convex_hull_points_2(InputIterator first, InputIterator beyond, OutputIterator result, const Traits & ch_traits );} {generates the counterclockwise sequence of extreme points of the points in the range [\ccc{first},\ccc{beyond}). The resulting sequence is placed starting at position \ccc{result}, and the past-the-end iterator for the resulting sequence is returned. It is not specified at which point the cyclic sequence of extreme points is cut into a linear sequence.} \ccIndexSubitem{containers}{writing} Also, when writing container classes, you should be sure to provide iterators and/or circulators for the containers and design the interfaces so they can be used with generic algorithms from the \stl\ and other \cgal\ algorithm. Here we give a few more details about how to accomplish these goals. \subsection{Handle, iterator, or circulator?} \label{sec:handle_vs_it_vs_circ} \ccIndexSubitem{handles}{when to use} \ccIndexSubitem{iterators}{when to use} \ccIndexSubitem{circulators}{when to use} Handles are indirect references that do not move, so whenever you need a pointer-like reference to a single element of a data structure, and it is not necessary to iterate (or circulate), use a handle. In contrast, iterators should be used when you want to move (that is, iterate) over a linear sequences of elements. When the sequence is circular, prefer a circulator over an iterator. \subsection{Writing functions for iterators AND circulators} \label{sec:it_and_circ_code} \ccIndexSubitem{iterators}{writing code for} \ccIndexSubitem{circulators}{writing code for} To make your code as generic as possible, you should, where appropriate, write functions that can accept either a circulator range or an iterator range to delimit the input values. Since empty circulator ranges are represented differently than empty iterator ranges, the following function is defined in \texttt{} so the test for an empty range can be done generically: \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. } One would use this function in conjunction with a \ccc{do-while} loop as follows: \begin{verbatim} if ( ! CGAL::is_empty_range( i, j) ) { do { // ... } while ( ++i != j ) } \end{verbatim} The following two macros are also defined as a generic means for iterating over either a linear or circular sequence: \ccStyle{CGAL_For_all( ic1, ic2)} \ccIndexMainItem[C]{CGAL_For_all} \ccStyle{CGAL_For_all_backwards( ic1, ic2)} \ccIndexMainItem[C]{CGAL_For_all_backwards} See the \ccAnchor{http://www.cgal.org/Manual/doc_html/support_lib/Circulator/Chapter_circulator.html}{Circulator documentation} in the Support Library Reference Manual for more information and examples. \subsection{Writing an iterator for your container} \label{sec:class_iterator} \ccIndexSubitemBegin{iterators}{writing} \ccIndexSubitemBegin{containers}{iterators for} Every container class in \cgal\ should strive to be a model for the \stl\ concept of a container. As for all concepts, this means that certain types and functions are provided, as detailed, for example in \cite{Austern98}. For the purposes of this discussion, the relevant types are: \begin{tabbing} \lcTex{constxiteratorxxxxxxxx\=\kill} \ccStyle{iterator} \> type of iterator \\ \ccStyle{const_iterator} \> iterator type for container with constant elements \end{tabbing} and the relevant functions are: \ccSetThreeColumns{const_iterator}{begin();}{} \ccFunction{iterator begin();}{beginning of container} \ccFunction{const_iterator begin();}{beginning of container with constant elements} \ccFunction{iterator end();}{past-the-end value for container} \ccFunction{const_iterator end();}{past-the-end value for container with constant elements} Variations on the above names are possible when, for example, the container contains more than one thing that can be iterated over. See Section~\ref{sec:naming_scheme} for more details about the naming conventions for iterators and their access functions. \ccIndexSubitemEnd{containers}{iterators for} \ccIndexSubitemEnd{iterators}{writing} \subsection{Writing a circulator for your container} \label{sec:class_circulator} \ccIndexSubitemBegin{circulators}{writing} \ccIndexSubitemBegin{containers}{circulators for} When a container represents a circular data structure (\ie, one without a defined beginning or end), one should provide circulators for the data elements in addition to (or, where appropriate, instead of) the iterators. This means that the following types should be defined: \begin{tabbing} \lcTex{constxcirculatorxxxxxxxx\=\kill} \ccStyle{circulator} \> type of circulator \\ \ccStyle{const_circulator} \> circulator type for container with constant elements \end{tabbing} as well as two access functions, one for each of the two types, with names that end in the suffix \ccc{_circulator} (Section~\ref{sec:naming_scheme}). \ccIndexSubitemEnd{containers}{circulators for} \ccIndexSubitemEnd{circulators}{writing} \InternalOnly{ \section{Requirements and recommendations} \label{it_and_circ:it_and_circ_req_and_rec} \noindent Requirements: \begin{itemize} \item All container classes should provide iterator types and access functions. \item All container classes that represent circular data structures should provide circulator types and access functions. \ccIndexSubitem{containers}{types} \item Take care that decrement of the past-the-end value is, in accordance with the standard, a legal operation for a bidirectionnal iterator. \ccIndexSubitem{iterators}{bidirectional} \ccIndexSubsubitem{iterators}{past-the-end value}{decrement of} This can, for example, be used to get the last element of a sequence. \end{itemize} \noindent Recommendations: \begin{itemize} \item Be aware that postincrement (respectively, postdecrement) is more expensive than preincrement (predecrement) since the iterator or circulator value must be copied in the former case. \ccIndexSubitem{iterators}{post- vs. preincrement} \ccIndexSubitem{circulators}{post- vs. preincrement} \item Remember that iterators and circulators are intended to be lightweight objects. That is, copying them should require only constant time. \ccIndexMainItemDef{lightweight objects} \ccIndexSubitem{iterators}{as lightweight objects} \ccIndexSubitem{circulators}{as lightweight objects} \item When writing a container-like structure, provide \ccc{push_back}, \ccc{push_front}, and \ccc{insert} member functions so all insert iterators can be used with your container. \ccIndexSubitem{containers}{member functions} \end{itemize} }