TODO: Update.

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.

From-SVN: r49608
This commit is contained in:
Phil Edwards 2002-02-08 07:34:54 +00:00
parent 6478d7c9c1
commit 8f94053d32
9 changed files with 624 additions and 80 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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.
*/
// // // // // // // // // // // // // // // // // // // // // // // //

View File

@ -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>

View File

@ -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>

View File

@ -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.

View File

@ -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)

View File

@ -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>)
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;
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)
{
// concept requirements -- taken care of in __distance
return __distance(__first, __last, __iterator_category(__first));
}
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 _InputIter, typename _Distance>
inline void
__advance(_InputIter& __i, _Distance __n, input_iterator_tag)
{
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter>)
/**
* @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;
}
else
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 _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));
}
/**
* @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

View File

@ -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&>