diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 39b67eac647f7d328252f72a4ccb7e0f8b4d714c..4786fce2d429aa6afe49d3c9d1e2d51611a736ff 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,15 @@ +2002-02-08 Phil Edwards <pme@gcc.gnu.org> + + * docs/doxygen/TODO: Update. + * docs/doxygen/doxygroups.cc: Tweak __gnu_cxx description. + * docs/doxygen/mainpage.html: Add TODO list link. + * docs/doxygen/user.cfg.in: Add @doctodo hook. + * docs/doxygen/tables.html: New file, emoty structure only. + + * include/bits/stl_iterator.h: Doxygenate just about everything. + * include/bits/stl_iterator_base_funcs.h: Ditto, clean up spaces. + * include/bits/stl_iterator_base_types.h: Add notes. + 2002-02-07 Stephan Buys <sbproxy@icon.co.za> * include/bits/stl_map.h: Tweak doxygen markup. diff --git a/libstdc++-v3/docs/doxygen/TODO b/libstdc++-v3/docs/doxygen/TODO index da2f25ab5e7978dd718860387dd3bfb199daf30c..375cd5fc785bac947fc0df34bc04b9b7dcdf3f69 100644 --- a/libstdc++-v3/docs/doxygen/TODO +++ b/libstdc++-v3/docs/doxygen/TODO @@ -7,6 +7,13 @@ documented in the course of doing other headers. "Untouched" means I've deliberately skipped it for various reasons, or haven't gotten to it yet. It /will/ be done (by somebody, eventually.) +If you document an area and need to skip (for whatever reason) a non-trivial +entity (i.e., one that should be documented), go ahead and add the comment +markup, and use the homegrown @doctodo tag. See include/bits/stl_iterator.h +for examples of this. Doing so will at least cause doxygen to consider the +entitiy as documented and include it in the output. It will also add the +entity to the generated TODO page. + Area Still needs to be doxygen-documented ----------------------------------------------------------- @@ -18,7 +25,8 @@ c20 Note A c21 Untouched, Note B c22 Untouched c23 See doxygroups.cc and Note B. -c24 Untouched +c24 stl_iterator.h (__normal_iterator, other small TODO bits) + stream iterators c25 stl_algo.h (lots of stuff) c26 <complex>, <valarray>, stl_numeric.h[26.4], Note A c27 Untouched @@ -40,8 +48,7 @@ do not have the C code (to which the doxygen comments would be attached), this would need to be done in entirely separate files, a la doxygroups.cc. B) Huge chunks of containers and strings are described in common "Tables" -in the standard. How to reproduce this information? I suspect we should -simply write some HTML tables (say, one <table> per Table per file), and +in the standard. These are being pseudo-duplicated in tables.html. We can use doxygen hooks like @pre and @see to reference the tables. Then the individual classes would do like the standard does, and only document members for which additional info is available. diff --git a/libstdc++-v3/docs/doxygen/doxygroups.cc b/libstdc++-v3/docs/doxygen/doxygroups.cc index d2bda88f8ecdc32a58247eacc7debd086a44b4d7..8af04b1ea54087194e52a679c9d244038d24d7e1 100644 --- a/libstdc++-v3/docs/doxygen/doxygroups.cc +++ b/libstdc++-v3/docs/doxygen/doxygroups.cc @@ -13,14 +13,17 @@ * @brief Everything defined by the ISO C++ Standard is within namespace std. */ /** @namespace __gnu_cxx - * @brief Non-standard things. + * @brief This namespace serves two purposes. * - * This namespace is used for + * This namespace is used for two things: * - sequestering internal (implementation-only) names away from the - * global namespace - * - GNU extensions + * global namespace; these are details of the implementation and should + * not be touched by users + * - GNU extensions for public use * - * This is still fluid and changing rapidly. + * This is still fluid and changing rapidly. Currently the rule is: if an + * entitity is found in the user-level documentation, it falls into the + * second category. */ // // // // // // // // // // // // // // // // // // // // // // // // diff --git a/libstdc++-v3/docs/doxygen/mainpage.html b/libstdc++-v3/docs/doxygen/mainpage.html index d7b1c436d29b5a3a55bb022770a00f576a3e9890..88ea279331fa6575d7bd62d24fcb9f3230b7abea 100644 --- a/libstdc++-v3/docs/doxygen/mainpage.html +++ b/libstdc++-v3/docs/doxygen/mainpage.html @@ -25,7 +25,7 @@ <h2> Documentation Overview </h2> -<p class="smallertext">Generated 2002-02-04.</p> +<p class="smallertext">Generated 2002-02-08.</p> <p>There are two types of documentation for libstdc++-v3. One is the distribution documentation, which can be read online at @@ -97,6 +97,7 @@ href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/C++STYLE">C++STYLE</a>. <li><a href="namespacemembers.html">Namespace Members</a> <li><a href="functions.html">Compound Members</a> <li><a href="globals.html">File Members</a> + <li><a href="todo.html">TODO List</a> (This is incomplete... how ironic.) </ul> </p> diff --git a/libstdc++-v3/docs/doxygen/tables.html b/libstdc++-v3/docs/doxygen/tables.html new file mode 100644 index 0000000000000000000000000000000000000000..d38e461c537db28f37a05c80d9aa8da114dcf24d --- /dev/null +++ b/libstdc++-v3/docs/doxygen/tables.html @@ -0,0 +1,260 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> +<head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> +<title>Tables</title> +<link href="style.css" rel="stylesheet" type="text/css"> +</head> + +<body bgcolor="#ffffff"> +<!-- + Tables can be jumped to with their number, e.g., "tables.html#67". +--> + +<h1>Tables</h1> + +<p>Most of the requirements on containers are presented in the ISO standard + in the form of tables. In order to avoid massive duplication of effort, + we follow the standard's lead and present the information here. + Individual classes will only document their departures from these tables + (removed functions, additional functions, changes, etc). +</p> + +<p>The numbers are the same as those used in the standard. +</p> + +<hr /> + +<a name="65"><p> +<table cellpadding="3" cellspacing="5" align="center" rules="rows" border="3" + cols="3" title="Table 65"> +<caption><h2>Table 65 --- Container Requirements</h2></caption> +<tr><th colspan="4"> +Anything calling itself a container must meet these minimum requirements. +</th></tr> +<tr> +<td><strong>expression</strong></td> +<td><strong>result type</strong></td> +<td><strong>notes</strong></td> +<td><strong>complexity</strong></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> +</table title="Table 65"></p></a> + + +<a name="66"><p> +<table cellpadding="3" cellspacing="5" align="center" rules="rows" border="3" + cols="3" title="Table 66"> +<caption><h2>Table 66 --- Reversible Container Requirements</h2></caption> +<tr><th colspan="4"> +If a container's iterator is bidirectional or random-access, then the +container also meets these requirements. +Foo, bar, and baz are such containers. +</th></tr> +<tr> +<td><strong>expression</strong></td> +<td><strong>result type</strong></td> +<td><strong>notes</strong></td> +<td><strong>complexity</strong></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> +</table title="Table 66"></p></a> + + +<a name="67"><p> +<table cellpadding="3" cellspacing="5" align="center" rules="rows" border="3" + cols="3" title="Table 67"> +<caption><h2>Table 67 --- Sequence Requirements</h2></caption> +<tr><th colspan="4"> +These are in addition to the requirements of <a href="#65">containers</a>. +Foo, bar, and baz are such containers. +</th></tr> +<tr> +<td><strong>expression</strong></td> +<td><strong>result type</strong></td> +<td><strong>notes</strong></td> +<td><strong>complexity</strong></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> +</table title="Table 67"></p></a> + + +<a name="68"><p> +<table cellpadding="3" cellspacing="5" align="center" rules="rows" border="3" + cols="3" title="Table 68"> +<caption><h2>Table 68 --- Optional Sequence Operations</h2></caption> +<tr><th colspan="4"> +These operations are only included in containers when the operation can be +done in constant time. +Foo, bar, and baz are such containers. +</th></tr> +<tr> +<td><strong>expression</strong></td> +<td><strong>result type</strong></td> +<td><strong>notes</strong></td> +<td><strong>complexity</strong></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> +</table title="Table 68"></p></a> + + +<a name="69"><p> +<table cellpadding="3" cellspacing="5" align="center" rules="rows" border="3" + cols="3" title="Table 69"> +<caption><h2>Table 69 --- Associative Container Requirements</h2></caption> +<tr><th colspan="4"> +These are in addition to the requirements of <a href="#65">containers</a>. +</th></tr> +<tr> +<td><strong>expression</strong></td> +<td><strong>result type</strong></td> +<td><strong>notes</strong></td> +<td><strong>complexity</strong></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> + +<tr> +<td></td> +<td></td> +<td></td> +<td></td> +</tr> +</table title="Table 69"></p></a> + + +<hr /> +<p class="smallertext"><em> +See <a href="mainpage.html">mainpage.html</a> for copying conditions. +</em></p> + + +</body> +</html> + diff --git a/libstdc++-v3/docs/doxygen/user.cfg.in b/libstdc++-v3/docs/doxygen/user.cfg.in index 430194b5579cfc4390969db2bed3c6dc2cf1756d..2a1a4c639f23540b0f5240f4a511ba73be4da258 100644 --- a/libstdc++-v3/docs/doxygen/user.cfg.in +++ b/libstdc++-v3/docs/doxygen/user.cfg.in @@ -201,7 +201,7 @@ TAB_SIZE = 4 # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. -GENERATE_TODOLIST = NO +GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test @@ -223,7 +223,8 @@ GENERATE_BUGLIST = YES # You can put \n's in the value part of an alias to insert newlines. ALIASES = "maint=@if maint" \ - "endmaint=@endif" + "endmaint=@endif" \ + "doctodo=@todo\nDoc me! See docs/doxygen/TODO and http://gcc.gnu.org/ml/libstdc++/2002-02/msg00003.html for more." # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 7acf4f41d145dba8125e126400322ce5d94710b2..b42181f5ba2122d4459ce363cfae87c99fa70ea7 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -56,6 +56,10 @@ /** @file stl_iterator.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. + * + * This file implements reverse_iterator, back_insert_iterator, + * front_insert_iterator, insert_iterator, __normal_iterator, and their + * supporting functions and overloaded operators. */ #ifndef __GLIBCPP_INTERNAL_ITERATOR_H @@ -64,6 +68,24 @@ namespace std { // 24.4.1 Reverse iterators + /** + * "Bidirectional and random access iterators have corresponding reverse + * %iterator adaptors that iterate through the data structure in the + * opposite direction. They have the same signatures as the corresponding + * iterators. The fundamental relation between a reverse %iterator and its + * corresponding %iterator @c i is established by the identity: + * @code + * &*(reverse_iterator(i)) == &*(i - 1) + * @endcode + * + * This mapping is dictated by the fact that while there is always a + * pointer past the end of an array, there might not be a valid pointer + * before the beginning of an array." [24.4.1]/1,2 + * + * Reverse iterators can be tricky and surprising at first. Their + * semantics make sense, however, and the trickiness is a side effect of + * the requirement that the iterators must be safe. + */ template<typename _Iterator> class reverse_iterator : public iterator<typename iterator_traits<_Iterator>::iterator_category, @@ -83,21 +105,42 @@ namespace std typedef typename iterator_traits<_Iterator>::pointer pointer; public: + /** + * The default constructor gives an undefined state to this %iterator. + */ reverse_iterator() { } + /** + * This %iterator will move in the opposite direction that @p x does. + */ explicit reverse_iterator(iterator_type __x) : current(__x) { } + /** + * The copy constructor is normal. + */ reverse_iterator(const reverse_iterator& __x) : current(__x.current) { } + /** + * A reverse_iterator across other types can be copied in the normal + * fashion. + */ template<typename _Iter> reverse_iterator(const reverse_iterator<_Iter>& __x) : current(__x.base()) { } + /** + * @return @c current, the %iterator used for underlying work. + */ iterator_type base() const { return current; } + /** + * @return TODO + * + * @doctodo + */ reference operator*() const { @@ -105,9 +148,19 @@ namespace std return *--__tmp; } + /** + * @return TODO + * + * @doctodo + */ pointer operator->() const { return &(operator*()); } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator& operator++() { @@ -115,6 +168,11 @@ namespace std return *this; } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator operator++(int) { @@ -123,6 +181,11 @@ namespace std return __tmp; } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator& operator--() { @@ -130,6 +193,11 @@ namespace std return *this; } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator operator--(int) { reverse_iterator __tmp = *this; @@ -137,10 +205,20 @@ namespace std return __tmp; } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator operator+(difference_type __n) const { return reverse_iterator(current - __n); } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator& operator+=(difference_type __n) { @@ -148,10 +226,20 @@ namespace std return *this; } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator operator-(difference_type __n) const { return reverse_iterator(current + __n); } + /** + * @return TODO + * + * @doctodo + */ reverse_iterator& operator-=(difference_type __n) { @@ -159,10 +247,25 @@ namespace std return *this; } + /** + * @return TODO + * + * @doctodo + */ reference operator[](difference_type __n) const { return *(*this + __n); } }; + //@{ + /** + * @param x A %reverse_iterator. + * @param y A %reverse_iterator. + * @return A simple bool. + * + * Reverse iterators forward many operations to their underlying base() + * iterators. Others are implemented in terms of one another. + * + */ template<typename _Iterator> inline bool operator==(const reverse_iterator<_Iterator>& __x, @@ -210,8 +313,17 @@ namespace std operator+(typename reverse_iterator<_Iterator>::difference_type __n, const reverse_iterator<_Iterator>& __x) { return reverse_iterator<_Iterator>(__x.base() - __n); } + //@} // 24.4.2.2.1 back_insert_iterator + /** + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator appends it to the container using + * push_back. + * + * Tip: Using the back_inserter function to create these iterators can + * save typing. + */ template<typename _Container> class back_insert_iterator : public iterator<output_iterator_tag, void, void, void, void> @@ -220,11 +332,24 @@ namespace std _Container* container; public: + /// A nested typedef for the type of whatever container you used. typedef _Container container_type; + /// The only way to create this %iterator is with a container. explicit back_insert_iterator(_Container& __x) : container(&__x) { } + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container<T>. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the end, if you like). Assigning a value to the %iterator will + * always append the value to the end of the container. + */ back_insert_iterator& operator=(typename _Container::const_reference __value) { @@ -232,21 +357,43 @@ namespace std return *this; } + /// Simply returns *this. back_insert_iterator& operator*() { return *this; } + /// Simply returns *this. (This %iterator does not "move".) back_insert_iterator& operator++() { return *this; } + /// Simply returns *this. (This %iterator does not "move".) back_insert_iterator operator++(int) { return *this; } }; + /** + * @param x A container of arbitrary type. + * @return An instance of back_insert_iterator working on @p x. + * + * This wrapper function helps in creating back_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ template<typename _Container> inline back_insert_iterator<_Container> back_inserter(_Container& __x) { return back_insert_iterator<_Container>(__x); } + /** + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator prepends it to the container using + * push_front. + * + * Tip: Using the front_inserter function to create these iterators can + * save typing. + */ template<typename _Container> class front_insert_iterator : public iterator<output_iterator_tag, void, void, void, void> @@ -255,10 +402,23 @@ namespace std _Container* container; public: + /// A nested typedef for the type of whatever container you used. typedef _Container container_type; + /// The only way to create this %iterator is with a container. explicit front_insert_iterator(_Container& __x) : container(&__x) { } + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container<T>. + * @return This %iterator, for chained operations. + * + * This kind of %iterator doesn't really have a "position" in the + * container (you can think of the position as being permanently at + * the front, if you like). Assigning a value to the %iterator will + * always prepend the value to the front of the container. + */ front_insert_iterator& operator=(typename _Container::const_reference __value) { @@ -266,21 +426,47 @@ namespace std return *this; } + /// Simply returns *this. front_insert_iterator& operator*() { return *this; } + /// Simply returns *this. (This %iterator does not "move".) front_insert_iterator& operator++() { return *this; } + /// Simply returns *this. (This %iterator does not "move".) front_insert_iterator operator++(int) { return *this; } }; + /** + * @param x A container of arbitrary type. + * @return An instance of front_insert_iterator working on @p x. + * + * This wrapper function helps in creating front_insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ template<typename _Container> inline front_insert_iterator<_Container> front_inserter(_Container& __x) { return front_insert_iterator<_Container>(__x); } + /** + * These are output iterators, constructed from a container-of-T. + * Assigning a T to the iterator inserts it in the container at the + * %iterator's position, rather than overwriting the value at that + * position. + * + * (Sequences will actually insert a @e copy of the value before the + * %iterator's position.) + * + * Tip: Using the inserter function to create these iterators can + * save typing. + */ template<typename _Container> class insert_iterator : public iterator<output_iterator_tag, void, void, void, void> @@ -290,11 +476,39 @@ namespace std typename _Container::iterator iter; public: + /// A nested typedef for the type of whatever container you used. typedef _Container container_type; + /** + * The only way to create this %iterator is with a container and an + * initial position (a normal %iterator into the container). + */ insert_iterator(_Container& __x, typename _Container::iterator __i) : container(&__x), iter(__i) {} + /** + * @param value An instance of whatever type + * container_type::const_reference is; presumably a + * reference-to-const T for container<T>. + * @return This %iterator, for chained operations. + * + * This kind of %iterator maintains its own position in the + * container. Assigning a value to the %iterator will insert the + * value into the container at the place before the %iterator. + * + * The position is maintained such that subsequent assignments will + * insert values immediately after one another. For example, + * @code + * // vector v contains A and Z + * + * insert_iterator i (v, ++v.begin()); + * i = 1; + * i = 2; + * i = 3; + * + * // vector v contains A, 1, 2, 3, and Z + * @endcode + */ insert_iterator& operator=(const typename _Container::const_reference __value) { @@ -303,16 +517,30 @@ namespace std return *this; } + /// Simply returns *this. insert_iterator& operator*() { return *this; } + /// Simply returns *this. (This %iterator does not "move".) insert_iterator& operator++() { return *this; } + /// Simply returns *this. (This %iterator does not "move".) insert_iterator& operator++(int) { return *this; } }; + /** + * @param x A container of arbitrary type. + * @return An instance of insert_iterator working on @p x. + * + * This wrapper function helps in creating insert_iterator instances. + * Typing the name of the %iterator requires knowing the precise full + * type of the container, which can be tedious and impedes generic + * programming. Using this function lets you take advantage of automatic + * template parameter deduction, making the compiler match the correct + * types for you. + */ template<typename _Container, typename _Iterator> inline insert_iterator<_Container> inserter(_Container& __x, _Iterator __i) diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h index 3034fce079c2fa5eeab6ad7267f5c135e7a53e1a..8389f5e7d03a778cba29e5766ae5bc3fb7a9e352 100644 --- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h +++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h @@ -1,6 +1,6 @@ // Functions used by iterators -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -56,89 +56,118 @@ /** @file stl_iterator_base_funcs.h * This is an internal header file, included by other library headers. * You should not attempt to use it directly. + * + * This file contains all of the general iterator-related utility + * functions, such as distance() and advance(). */ #ifndef __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H #define __GLIBCPP_INTERNAL_ITERATOR_BASE_FUNCS_H -// This file contains all of the general iterator-related utility -// functions, such as distance() and advance(). -// The internal file stl_iterator.h contains predefined iterators, -// such as front_insert_iterator and istream_iterator. - #pragma GCC system_header #include <bits/concept_check.h> +// Since this entire file is within namespace std, there's no reason to +// waste two spaces along the left column. Thus the leading indentation is +// slightly violated from here on. namespace std { - template<typename _InputIterator> - inline typename iterator_traits<_InputIterator>::difference_type - __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) - { - // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) - typename iterator_traits<_InputIterator>::difference_type __n = 0; - while (__first != __last) { - ++__first; ++__n; - } - return __n; +template<typename _InputIterator> + inline typename iterator_traits<_InputIterator>::difference_type + __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag) + { + // concept requirements + __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>) + + typename iterator_traits<_InputIterator>::difference_type __n = 0; + while (__first != __last) { + ++__first; ++__n; } - - template<typename _RandomAccessIterator> - inline typename iterator_traits<_RandomAccessIterator>::difference_type - __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, - random_access_iterator_tag) - { - // concept requirements - __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) - return __last - __first; - } - - template<typename _InputIterator> - inline typename iterator_traits<_InputIterator>::difference_type - distance(_InputIterator __first, _InputIterator __last) - { - // concept requirements -- taken care of in __distance - return __distance(__first, __last, __iterator_category(__first)); - } - - template<typename _InputIter, typename _Distance> - inline void - __advance(_InputIter& __i, _Distance __n, input_iterator_tag) - { - // concept requirements - __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) + return __n; + } + +template<typename _RandomAccessIterator> + inline typename iterator_traits<_RandomAccessIterator>::difference_type + __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, + random_access_iterator_tag) + { + // concept requirements + __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + return __last - __first; + } + +/** + * @brief A generalization of pointer arithmetic. + * @param first An input iterator. + * @param last An input iterator. + * @return The distance between them. + * + * Returns @c n such that first + n == last. This requires that @p last + * must be reachable from @p first. Note that @c n may be negative. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. +*/ +template<typename _InputIterator> + inline typename iterator_traits<_InputIterator>::difference_type + distance(_InputIterator __first, _InputIterator __last) + { + // concept requirements -- taken care of in __distance + return __distance(__first, __last, __iterator_category(__first)); + } + +template<typename _InputIter, typename _Distance> + inline void + __advance(_InputIter& __i, _Distance __n, input_iterator_tag) + { + // concept requirements + __glibcpp_function_requires(_InputIteratorConcept<_InputIter>) + while (__n--) ++__i; + } + +template<typename _BidirectionalIterator, typename _Distance> + inline void + __advance(_BidirectionalIterator& __i, _Distance __n, + bidirectional_iterator_tag) + { + // concept requirements + __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>) + + if (__n > 0) while (__n--) ++__i; - } - - template<typename _BidirectionalIterator, typename _Distance> - inline void - __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) - { - // concept requirements - __glibcpp_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>) - if (__n > 0) - while (__n--) ++__i; - else - while (__n++) --__i; - } - - template<typename _RandomAccessIterator, typename _Distance> - inline void - __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) - { - // concept requirements - __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) - __i += __n; - } - - template<typename _InputIterator, typename _Distance> - inline void - advance(_InputIterator& __i, _Distance __n) - { - // concept requirements -- taken care of in __advance - __advance(__i, __n, __iterator_category(__i)); - } + else + while (__n++) --__i; + } + +template<typename _RandomAccessIterator, typename _Distance> + inline void + __advance(_RandomAccessIterator& __i, _Distance __n, + random_access_iterator_tag) + { + // concept requirements + __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __i += __n; + } + +/** + * @brief A generalization of pointer arithmetic. + * @param i An input iterator. + * @param n The "delta" by which to change @p i. + * @return Nothing. + * + * This increments @p i by @p n. For bidirectional and random access + * iterators, @p n may be negative, in which case @p i is decremented. + * + * For random access iterators, this uses their @c + and @c - operations + * and are constant time. For other %iterator classes they are linear time. +*/ +template<typename _InputIterator, typename _Distance> + inline void + advance(_InputIterator& __i, _Distance __n) + { + // concept requirements -- taken care of in __advance + __advance(__i, __n, __iterator_category(__i)); + } } // namespace std diff --git a/libstdc++-v3/include/bits/stl_iterator_base_types.h b/libstdc++-v3/include/bits/stl_iterator_base_types.h index 992510d139ea236adbbdfac0418f26a89d9fb2bb..e5b3fa461b4655d395b3721ef92f1644a3fac529 100644 --- a/libstdc++-v3/include/bits/stl_iterator_base_types.h +++ b/libstdc++-v3/include/bits/stl_iterator_base_types.h @@ -1,6 +1,6 @@ // Types used in iterator implementation -*- C++ -*- -// Copyright (C) 2001 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -90,9 +90,12 @@ namespace std /** - * This class does nothing but define nested typedefs. Iterator classes + * This class does nothing but define nested typedefs. %Iterator classes * can inherit from this class to save some work. The typedefs are then * used in specializations and overloading. + * + * In particular, there are no default implementations of requirements + * such as @c operator++ and the like. (How could there be?) */ template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t, typename _Pointer = _Tp*, typename _Reference = _Tp&>