2001-02-11 20:05:00 +00:00
< html >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=windows-1252" >
< meta name = "GENERATOR" content = "Microsoft FrontPage 4.0" >
< meta name = "ProgId" content = "FrontPage.Editor.Document" >
< title > Indirect Iterator Adaptor Documentation</ title >
</ head >
< body bgcolor = "#FFFFFF" text = "#000000" >
< img src = "../../c++boost.gif" alt = "c++boost.gif (8819 bytes)"
align = "center" width = "277" height = "86" >
< h1 > Indirect Iterator Adaptor</ h1 >
Defined in header
< a href = "../../boost/iterator_adaptors.hpp" > boost/iterator_adaptors.hpp</ a >
< p >
The indirect iterator adaptor augments an iterator by applying an
< b > extra</ b > dereference inside of < tt > operator*()</ tt > . For example,
this iterator makes it possible to view containers of pointers such as
< tt > std::list< foo*> </ tt > as if there were containers of the
pointed-to type (in this case < tt > std::list< foo> </ tt > ). The
following < b > pseudo-code</ b > shows the basic idea of the indirect
iterator:
< pre >
// inside a hypothetical indirect_iterator class...
typedef std::iterator_traits< BaseIterator> ::value_type Pointer;
typedef std::iterator_traits< Pointer> ::reference reference;
reference indirect_iterator::operator*() const {
return **this->base_iterator;
}
</ pre >
< h2 > Synopsis</ h2 >
< pre >
namespace boost {
template < class BaseIterator,
class Value, class Reference, class Pointer>
struct indirect_iterator_generator;
template < class BaseIterator,
class Value, class Pointer, class Reference,
class ConstPointer, class ConstReference>
struct indirect_iterator_pair_generator;
template < class BaseIterator>
typename indirect_iterator_generator< BaseIterator> ::type
make_indirect_iterator(BaseIterator base)
}
</ pre >
< hr >
< h2 >< a name = "indirect_iterator_generator" > The Indirect Iterator Type
Generator</ a ></ h2 >
The class < tt > indirect_iterator_generator</ tt > is a helper class whose
purpose is to construct an indirect iterator type. The main template
parameter for this class is the < tt > BaseIterator</ tt > type that is
being wrapped. In most cases the type of the elements being pointed to
can be deduced using < tt > std::iterator_traits</ tt > , but in some
2001-02-12 01:50:50 +00:00
situations the user may want to override this type, so there are also
template parameters for the type being pointed to (the < tt > Value</ tt > )
as well as reference and pointer versions of the type.
2001-02-11 20:05:00 +00:00
< pre >
template < class BaseIterator,
class Value, class Reference, class Pointer>
class indirect_iterator_generator
{
public:
2001-02-12 05:24:45 +00:00
typedef < tt >< a href = "./iterator_adaptors.htm#iterator_adaptor" > iterator_adaptor</ a > <...> </ tt > type; // the resulting indirect iterator type
2001-02-11 20:05:00 +00:00
};
</ pre >
< h3 > Example</ h3 >
This example uses the < tt > indirect_iterator_generator</ tt > to create
indirect iterators that dereference the pointers stored in the
< tt > pointers_to_chars</ tt > array to access the < tt > char</ tt > 's in the
< tt > characters</ tt > array.
< pre >
#include < boost/config.hpp>
#include < vector>
#include < iostream>
#include < iterator>
#include < boost/iterator_adaptors.hpp>
int main(int, char*[])
{
char characters[] = "abcdefg";
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
char* pointers_to_chars[N]; // at the end.
for (int i = 0; i < N; ++i)
pointers_to_chars[i] = &characters[i];
boost::indirect_iterator_generator< char**, char> ::type
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
std::copy(indirect_first, indirect_last, std::ostream_iterator< char> (std::cout, ","));
std::cout << std::endl;
2001-02-12 01:50:50 +00:00
// to be continued...
2001-02-11 20:05:00 +00:00
</ pre >
< h3 > Template Parameters</ h3 >
< Table border >
< TR >
< TH > Parameter</ TH >< TH > Description</ TH >
</ TR >
< TR >
< TD >< tt > BaseIterator</ tt ></ TD >
< TD > The iterator type being wrapped. The value type of the base iterator
should be a pointer (a < a
href = "http://www.sgi.com/tech/stl/trivial.html" > Trivial
Iterator</ a > ).</ TD >
</ TD >
</ TR >
< TR >
< TD >< tt > Value</ tt ></ TD >
< TD > The value-type of the value-type of the base iterator. That is, the
type of object that is accessed by dereferences in the base iterator twice.< br >
< b > Default:</ b >< br >
< tt > std::iterator_traits< std::iterator_traits< BaseIterator> ::value_type> ::value_type</ tt >
</ TD >
< TR >
< TD >< tt > Reference</ tt ></ TD >
2001-02-12 01:50:50 +00:00
< TD > The corresponding reference type for the < tt > Value</ tt > .< br >
2001-02-11 20:05:00 +00:00
< b > Default:</ b > < tt > Value& </ tt ></ TD >
</ TD >
< TR >
< TD >< tt > Pointer</ tt ></ TD >
2001-02-12 01:50:50 +00:00
< TD > The corresponding pointer type for the < tt > Value</ tt > .< br >
2001-02-11 20:05:00 +00:00
< b > Default:</ b > < tt > Value*</ tt ></ TD >
</ TD >
</ Table >
< h3 > Model of</ h3 >
If the base iterator is a model of < a
href = "http://www.sgi.com/tech/stl/RandomAccessIterator.html" > Random
Access Iterator</ a > then so is the resulting indirect iterator. If
the base iterator supports less functionality than this the resulting
indirect iterator will also support less functionality.
< h3 > Members</ h3 >
The indirect iterator type implements the member functions and
operators required of the < a
href = "http://www.sgi.com/tech/stl/RandomAccessIterator.html" > Random
Access Iterator</ a > concept.
In addition it has the following constructor:
< pre >
indirect_iterator_generator::type(const BaseIterator& it)
</ pre >
< p >
< hr >
< p >
2001-02-12 01:50:50 +00:00
< h2 >< a name = "indirect_iterator_pair_generator" > The Indirect Iterator Pair
2001-02-11 20:05:00 +00:00
Generator</ a ></ h2 >
2001-02-12 01:50:50 +00:00
Sometimes a mutable/const pair of iterator types is needed, such as
when implementing a container type. The
< tt > indirect_iterator_pair_generator</ tt > class makes it more
convenient to create this pair of iterator types.
< pre >
template < class BaseIterator,
class Value, class Pointer, class Reference,
class ConstPointer, class ConstReference>
class indirect_iterator_pair_generator
{
public:
2001-02-12 05:24:45 +00:00
typedef < tt >< a href = "./iterator_adaptors.htm#iterator_adaptor" > iterator_adaptor</ a > <...> </ tt > iterator; // the mutable indirect iterator type
typedef < tt >< a href = "./iterator_adaptors.htm#iterator_adaptor" > iterator_adaptor</ a > <...> </ tt > const_iterator; // the immutable indirect iterator type
2001-02-12 01:50:50 +00:00
};
</ pre >
< h3 > Example</ h3 >
< pre >
// continuing from the last example...
typedef boost::indirect_iterator_pair_generator< char **,
char , char *, char &, const char *, const char & > PairGen;
char mutable_characters[N];
char* pointers_to_mutable_chars[N];
for (int i = 0; i < N ; ++ i )
pointers_to_mutable_chars [ i ] = & mutable_characters [ i ];
PairGen::iterator mutable_indirect_first ( pointers_to_mutable_chars ),
mutable_indirect_last ( pointers_to_mutable_chars + N );
PairGen::const_iterator const_indirect_first ( pointers_to_chars ),
const_indirect_last ( pointers_to_chars + N );
std::transform ( const_indirect_first , const_indirect_last ,
mutable_indirect_first , std::bind1st ( std::plus < char > (), 1));
std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator< char > (std::cout, ","));
std::cout < < std::endl ;
// to be continued ...
</ pre >
The output is:
< pre >
b,c,d,e,f,g,h,
</ pre >
< h3 > Template Parameters</ h3 >
< Table border >
< TR >
< TH > Parameter</ TH >< TH > Description</ TH >
</ TR >
< TR >
< TD >< tt > BaseIterator</ tt ></ TD >
< TD > The iterator type being wrapped. The value type of the base iterator
should be a pointer (a < a
href = "http://www.sgi.com/tech/stl/trivial.html" > Trivial
Iterator</ a > ).</ TD >
</ TD >
</ TR >
< TR >
< TD >< tt > Value</ tt ></ TD >
< TD > The value-type of the value-type of the base iterator. That is, the
type of object that is accessed by dereferences in the base iterator twice.< br >
< b > Default:</ b >< br >
< tt > std::iterator_traits< std::iterator_traits< BaseIterator> ::value_type> ::value_type</ tt >
</ TD >
< TR >
< TD >< tt > Reference</ tt ></ TD >
< TD > The corresponding reference type for the < tt > Value</ tt > .< br >
< b > Default:</ b > < tt > Value& </ tt ></ TD >
</ TD >
< TR >
< TD >< tt > Pointer</ tt ></ TD >
< TD > The corresponding pointer type for the < tt > Value</ tt > .< br >
< b > Default:</ b > < tt > Value*</ tt ></ TD >
</ TD >
< TR >
< TD >< tt > ConstReference</ tt ></ TD >
< TD > The corresponding const reference type for the < tt > Value</ tt > .< br >
< b > Default:</ b > < tt > const Value& </ tt ></ TD >
</ TD >
< TR >
< TD >< tt > ConstPointer</ tt ></ TD >
< TD > The corresponding const pointer type for the < tt > Value</ tt > .< br >
< b > Default:</ b > < tt > const Value*</ tt ></ TD >
</ TD >
</ Table >
< h3 > Model of</ h3 >
If the base iterator is a model of < a
href = "http://www.sgi.com/tech/stl/RandomAccessIterator.html" > Random
Access Iterator</ a > then so is the resulting indirect iterator types.
2001-02-12 04:52:24 +00:00
If the base iterator supports less functionality the
2001-02-12 01:50:50 +00:00
resulting indirect iterator types will also support less
functionality. The resulting < tt > iterator</ tt > type is mutable, and
the resulting < tt > const_iterator</ tt > type is constant.
< h3 > Members</ h3 >
The resulting < tt > iterator</ tt > and < tt > const_iterator</ tt > types
implements the member functions and operators required of the < a
href = "http://www.sgi.com/tech/stl/RandomAccessIterator.html" > Random
Access Iterator</ a > concept. In addition they support the following
constructors:
< pre >
indirect_iterator_pair_generator::iterator(const BaseIterator& it)
</ pre >
< pre >
indirect_iterator_pair_generator::const_iterator(const BaseIterator& it)
</ pre >
2001-02-11 20:05:00 +00:00
< p >
< hr >
< p >
< h2 >< a name = "make_indirect_iterator" > The Indirect Iterator Object Generator</ a ></ h2 >
2001-02-12 01:50:50 +00:00
The < tt > make_indirect_iterator()</ tt > function provides a more
convenient way to create indirect iterator objects. The function saves
the user the trouble of explicitly writing out the iterator types.
2001-02-11 20:05:00 +00:00
2001-02-12 01:50:50 +00:00
< pre >
template < class BaseIterator>
typename indirect_iterator_generator< BaseIterator> ::type
make_indirect_iterator(BaseIterator base)
</ pre >
< h3 > Example</ h3 >
Here we again print the < tt > char</ tt > 's from the array
< tt > characters</ tt > by accessing them through the array of pointers
< tt > pointer_to_chars</ tt > , but this time we use the
< tt > make_indirect_iterator()</ tt > function which saves us some typing.
< pre >
// continuing from the last example...
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator< char > (std::cout, ","));
std::cout < < std::endl ;
return 0 ;
}
</ pre >
The output is:
< pre >
a,b,c,d,e,f,g,
</ pre >
2001-02-11 20:05:00 +00:00
< hr >
< p > Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan --> 10 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" --> </ p >
< p > © Copyright Jeremy Siek 2000. Permission to copy, use,
modify, sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided " as is"
without express or implied warranty, and with no claim as to its suitability for
any purpose.</ p >
</ body >
</ html >
2001-02-12 01:50:50 +00:00
<!-- LocalWords: html charset alt gif hpp BaseIterator const namespace struct
-->
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
-->
<!-- LocalWords: sizeof PairGen pre Siek
-->