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