Files
boost_iterator/development/libs/iterator/iterator_traits.htm

138 lines
5.3 KiB
HTML
Raw Normal View History

2001-03-19 17:41:49 +00:00
<html>
<!--
-- Copyright (c) Jeremy Siek 2000
--
-- Permission to use, copy, modify, distribute and sell this software
-- and its documentation for any purpose is hereby granted without fee,
-- provided that the above copyright notice appears in all copies and
-- that both that copyright notice and this permission notice appear
-- in supporting documentation. I make no representations about the
-- suitability of this software for any purpose. It is provided "as is"
-- without express or implied warranty.
-->
<head>
<title>Boost Iterator Traits</title>
</head>
2001-03-19 18:01:41 +00:00
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../c++boost.gif"
ALT="C++ Boost" width="277" height="86">
<BR Clear>
2001-03-19 17:41:49 +00:00
<h1>Boost Iterator Traits</h1>
Header <tt><a href="../../boost/iterator_traits.hpp">boost/iterator_traits.hpp</a></tt>
2001-03-19 18:01:41 +00:00
<p>
The <tt>boost::iterator_traits</tt> class provides access to the
associated types of iterators that model the Boost <a
href="./iterator_concepts.htm">Iterator Concepts</a>, which are a
replacement for the iterator requirements in the C++ standard.
The main difference between <tt>std::iterator_traits</tt> and
<tt>boost::iterator_traits</tt> is that the <tt>iterator_category</tt>
type has been removed, and replaced with two new types:
<ul>
<li><tt>traversal_category</tt>:&nbsp;&nbsp; Can the iterator go forward, backward, etc.?
<li><tt>return_category</tt>:&nbsp;&nbsp; Is the iterator read or write only?
Is the dereferenced type an lvalue?
</ul>
<p>
An important feature of the <tt>boost::iterator_traits</tt> is that it
is <b>backwards compatible</b>, i.e., it will automatically work for
iterators for which there are valid definitions of
<tt>std::iterator_traits</tt>. The old <tt>iterator_category</tt> is
mapped to the appropriate traversal and return categories.
<p>
When creating a new iterator type that is meant to work with
<tt>boost::iterator_traits</tt>, you can either create a
specialization of <tt>boost::iterator_traits</tt> for your iterator
type, or you can provide all the necessary associated types as nested
typedefs. In this case, your iterator class will need to inherit from
<tt>new_iterator_base</tt> to let <tt>boost::iterator_traits</tt> know
that it will be able to find typedefs for <tt>traversal_category</tt>
and <tt>return_category</tt> in you iterator class.
2001-03-19 17:41:49 +00:00
<pre>
namespace boost {
2001-03-19 18:01:41 +00:00
<i>// Inherit from iterator_base if your iterator defines its own
// return_category and traversal_category. Otherwise, the "old style"
// iterator category will be mapped to the return_category and
// traversal_category.</i>
struct new_iterator_base { };
2001-03-19 17:41:49 +00:00
template &lt;typename Iterator&gt;
struct iterator_traits
{
if (Iterator inherits from new_iterator_base) {
typedef typename Iterator::value_type value_type;
typedef typename Iterator::reference reference;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::return_category return_category;
typedef typename Iterator::traversal_category traversal_category;
} else {
typedef std::iterator_traits&lt;Iterator&gt; OldTraits;
typedef typename OldTraits::value_type value_type;
typedef typename OldTraits::reference reference;
typedef typename OldTraits::pointer pointer;
typedef typename OldTraits::difference_type difference_type;
typedef typename OldTraits::iterator_category Cat;
<i>// Determine the traversal_category based on the old iterator_category</i>
if (Cat inherits from std::random_access_iterator_tag)
typedef boost::random_access_iterator_tag traversal_category;
else if (Cat inherits from std::bidirectional_iterator_tag)
typedef boost::bidirectional_iterator_tag traversal_category;
else if (Cat inherits from std::forward_iterator_tag)
typedef boost::forward_iterator_tag traversal_category;
else
typedef boost::single_pass_iterator_tag traversal_category;
<i>// Determine the return_category based on the old iterator_category and value_type</i>
if (Cat inherits from std::forward_iterator_tag)
if (is-const(T))
typedef boost::constant_lvalue_iterator_tag return_category;
else
typedef boost::mutable_lvalue_iterator_tag return_category;
else if (Cat inherits from std::input_iterator_tag)
typedef boost::readable_iterator_tag return_category;
else if (Cat inherits from std::output_iterator_tag)
typedef boost::writable_iterator_tag return_category;
else
typedef boost::error_iterator_tag return_category;
}
};
template &lt;typename T&gt;
struct iterator_traits&lt;T*&gt;
{
typedef T value_type;
typedef T&amp; reference;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
if (is-const(T))
typedef boost::constant_lvalue_iterator_tag return_category;
else
typedef boost::mutable_lvalue_iterator_tag return_category;
typedef boost::random_access_iterator_tag traversal_category;
};
}
</pre>
<hr>
<address><a href="mailto:jsiek@lsc.nd.edu">jeremy siek</a></address>
<!-- Created: Sun Mar 18 14:06:57 EST 2001 -->
<!-- hhmts start -->
2001-03-19 18:01:41 +00:00
Last modified: Mon Mar 19 12:59:30 EST 2001
2001-03-19 17:41:49 +00:00
<!-- hhmts end -->
</body>
</html>