Whitespace cleanup and formatting fixes in docs.

This commit is contained in:
Andrey Semashev
2019-12-12 12:35:38 +03:00
parent 897ff65fdc
commit 3a8728a595
17 changed files with 219 additions and 230 deletions

View File

@ -1,4 +1,3 @@
[section:adaptor Iterator Adaptor]
The `iterator_adaptor` class template adapts some `Base` [#base]_
@ -47,7 +46,7 @@ that assumption.
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor
class iterator_adaptor
: public iterator_facade<Derived, *V'*, *C'*, *R'*, *D'*> // see details
{
friend class iterator_core_access;
@ -60,21 +59,21 @@ that assumption.
typedef iterator_adaptor iterator_adaptor\_;
Base const& base_reference() const;
Base& base_reference();
private: // Core iterator interface for iterator_facade.
private: // Core iterator interface for iterator_facade.
typename iterator_adaptor::reference dereference() const;
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
void advance(typename iterator_adaptor::difference_type n);
void increment();
void decrement();
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
@ -133,7 +132,7 @@ above are defined as follows:
iterator_adaptor();
[*Requires:] The `Base` type must be Default Constructible.[br]
[*Returns:] An instance of `iterator_adaptor` with
[*Returns:] An instance of `iterator_adaptor` with
`m_iterator` default constructed.
@ -167,7 +166,7 @@ above are defined as follows:
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
>
bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const;
[*Returns:] `m_iterator == x.base()`
@ -188,7 +187,7 @@ above are defined as follows:
template <
class OtherDerived, class OtherIterator, class V, class C, class R, class D
>
>
typename iterator_adaptor::difference_type distance_to(
iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const;
@ -229,7 +228,7 @@ operations on the underlying pointer, via the `node_iterator`\ 's
|dereference_and_equal|_). The only real behavioral difference
between `node_base*` and `node_iterator` can be observed when
they are incremented: `node_iterator` follows the
`m_next` pointer, while `node_base*` just applies an address offset.
`m_next` pointer, while `node_base*` just applies an address offset.
.. |dereference_and_equal| replace:: `dereference` and `equal` member functions
.. _dereference_and_equal: iterator_facade.html#implementing-the-core-operations
@ -287,7 +286,7 @@ this technique is known not to work with Borland C++ 5.6.4 and
Metrowerks CodeWarrior versions prior to 9.0]
You can see an example program that exercises this version of the
node iterators
node iterators
[example_link node_iterator3.cpp..here].
@ -306,7 +305,7 @@ types to its `Base` saves the implementor of
std::iterator_traits<Iterator>::*some-associated-type*
at least four times.
at least four times.
We urge you to review the documentation and implementations of
|reverse_iterator|_ and the other Boost `specialized iterator
@ -330,4 +329,4 @@ __ index.html#specialized-adaptors
[endsect]
[endsect]
[endsect]

View File

@ -1,4 +1,3 @@
[section:archetypes Iterator Archetypes]
The `iterator_archetype` class constructs a minimal implementation of
@ -41,23 +40,23 @@ The access category types provided correspond to the following
standard iterator access concept combinations:
readable_iterator_t :=
Readable Iterator
writable_iterator_t :=
Writeable Iterator
readable_writable_iterator_t :=
Readable Iterator & Writeable Iterator & Swappable Iterator
readable_lvalue_iterator_t :=
Readable Iterator & Lvalue Iterator
writeable_lvalue_iterator_t :=
Readable Iterator & Writeable Iterator & Swappable Iterator & Lvalue Iterator
[h3 Traits]
@ -66,25 +65,25 @@ The nested trait types are defined as follows:
if (AccessCategory == readable_iterator_t)
value_type = Value
reference = Value
pointer = Value*
else if (AccessCategory == writable_iterator_t)
value_type = void
reference = void
pointer = void
else if (AccessCategory == readable_writable_iterator_t)
value_type = Value
reference :=
A type X that is convertible to Value for which the following
expression is valid. Given an object x of type X and v of type
expression is valid. Given an object x of type X and v of type
Value.
x = v
@ -92,13 +91,13 @@ The nested trait types are defined as follows:
pointer = Value*
else if (AccessCategory == readable_lvalue_iterator_t)
value_type = Value
reference = Value const&
pointer = Value const*
else if (AccessCategory == writable_lvalue_iterator_t)
value_type = Value
reference = Value&
pointer = Value*
@ -108,11 +107,11 @@ The nested trait types are defined as follows:
difference_type := ptrdiff_t
else
difference_type := unspecified type
iterator_category :=
iterator_category :=
A type X satisfying the following two constraints:
@ -156,5 +155,4 @@ the iterator concept specified by `AccessCategory` and
arguments. `iterator_archetype` does not model any other access
concepts or any more derived traversal concepts.
[endsect]
[endsect]

View File

@ -1,4 +1,3 @@
[section:concepts Iterator Concepts]
[section:access Access]
@ -326,13 +325,13 @@ constant object of type `Distance`.
[pre: there exists a value `n` of `Distance` such that `a + n == b`. `b == a + (b - a)`.]
]
[
[`a\[n\]`]
[`a[n]`]
[convertible to T]
[`*(a + n)`]
[pre: a is a *Readable Iterator*]
]
[
[`a\[n\] = v`]
[`a[n] = v`]
[convertible to T]
[`*(a + n) = v`]
[pre: a is a *Writable iterator*]

View File

@ -1,4 +1,3 @@
[section:counting Counting Iterator]
A `counting_iterator` adapts an object by adding an `operator*` that
@ -18,26 +17,28 @@ into the first array via indirection through the second array.
std::vector<int> numbers;
typedef std::vector<int>::iterator n_iter;
std::copy(boost::counting_iterator<int>(0),
boost::counting_iterator<int>(N),
std::back_inserter(numbers));
boost::counting_iterator<int>(N),
std::back_inserter(numbers));
std::vector<std::vector<int>::iterator> pointers;
std::copy(boost::make_counting_iterator(numbers.begin()),
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
The output is:
indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
[pre
indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
]
The source code for this example can be found [example_link counting_iterator_example.cpp..here].
@ -86,9 +87,9 @@ algorithm:
random_access_traversal_tag, Incrementable, const Incrementable&)
else
return |iterator-category|_\ (
iterator_traversal<Incrementable>::type,
iterator_traversal<Incrementable>::type,
Incrementable, const Incrementable&)
[blurb *Note:* implementers are encouraged to provide an implementation of
`operator-` and a `difference_type` that avoids overflows in
the cases where `std::numeric_limits<Incrementable>::is_specialized`
@ -181,7 +182,7 @@ operations.
counting_iterator& operator--();
[*Effects: ] `--m_inc`[br]
[*Returns: ] `*this`
[*Returns: ] `*this`
Incrementable const& base() const;
@ -189,4 +190,4 @@ operations.
[*Returns: ] `m_inc`
[endsect]
[endsect]

View File

@ -1,4 +1,3 @@
[section:facade Iterator Facade]
While the iterator interface is rich, there is a core subset of the

View File

@ -1,12 +1,11 @@
[section:facade_tutorial Tutorial]
In this section we'll walk through the implementation of a few
iterators using `iterator_facade`, based around the simple
example of a linked list of polymorphic objects. This example was
inspired by a
inspired by a
[@http://thread.gmane.org/gmane.comp.lib.boost.user/5100 `posting`]
by Keith Macdonald on the
by Keith Macdonald on the
[@http://www.boost.org/more/mailing_lists.htm#users `Boost-Users`]
mailing list.
@ -30,16 +29,16 @@ Say we've written a polymorphic linked list node base class:
// print to the stream
virtual void print(std::ostream& s) const = 0;
// double the value
virtual void double_me() = 0;
void append(node_base* p)
{
if (m_next)
m_next->append(p);
if (m_next)
m_next->append(p);
else
m_next = p;
m_next = p;
}
private:
@ -210,7 +209,7 @@ the concepts we want our iterator to model. Referring to the
table__, we can see that the first three rows are applicable
because `node_iterator` needs to satisfy the requirements for
`readable iterator`_, `single pass iterator`_, and `incrementable
iterator`_.
iterator`_.
__ `core operations`_
@ -254,7 +253,7 @@ make them private and grant friendship to
};
Voila; a complete and conforming readable, forward-traversal
iterator! For a working example of its use, see
iterator! For a working example of its use, see
[example_link node_iterator1.cpp..this program].
__ ../../example/node_iterator1.cpp
@ -265,7 +264,7 @@ __ ../../example/node_iterator1.cpp
The term **mutable iterator** means an iterator through which
the object it references (its "referent") can be modified. A
**constant iterator** is one which doesn't allow modification of
its referent.[br][br]
its referent.[br][br]
The words *constant* and *mutable* don't refer to the ability to
modify the iterator itself. For example, an `int const*` is a
non-\ `const` *constant iterator*, which can be incremented
@ -402,7 +401,7 @@ adding a templatized converting constructor [#broken]_ [#random]_:
template <class OtherValue>
bool equal(node_iter<OtherValue> const& other) const
{
{
return this->m_node == other.m_node;
}
@ -431,7 +430,7 @@ adding a templatized converting constructor [#broken]_ [#random]_:
__ ../../example/node_iterator2.hpp
You can see an example program which exercises our interoperable
iterators
iterators
[example_link node_iterator2.cpp..here].
@ -467,7 +466,7 @@ appropriate:
...
private:
private:
struct enabler {};
public:

View File

@ -1,4 +1,3 @@
[section:filter Filter Iterator]
The filter iterator adaptor creates a view of an iterator range in
@ -19,7 +18,6 @@ This example uses `filter_iterator` and then
array of integers. Then `make_filter_iterator` is is used to output
the integers greater than `-2`.
struct is_positive_number {
bool operator()(int x) { return 0 < x; }
};
@ -33,7 +31,7 @@ the integers greater than `-2`.
base_iterator numbers(numbers_);
// Example using filter_iterator
typedef boost::filter_iterator<is_positive_number, base_iterator>
typedef boost::filter_iterator<is_positive_number, base_iterator>
FilterIter;
is_positive_number predicate;
@ -70,10 +68,11 @@ the integers greater than `-2`.
The output is:
4 5 8
4 5 8
0 -1 4 5 8
[pre
4 5 8
4 5 8
0 -1 4 5 8
]
The source code for this example can be found [example_link filter_iterator_example.cpp..here].
@ -114,10 +113,10 @@ The source code for this example can be found [example_link filter_iterator_exam
If `Iterator` models Readable Lvalue Iterator and Bidirectional Traversal
Iterator then `iterator_category` is convertible to
`std::bidirectional_iterator_tag`.
`std::bidirectional_iterator_tag`.
Otherwise, if `Iterator` models Readable Lvalue Iterator and Forward Traversal
Iterator then `iterator_category` is convertible to
`std::forward_iterator_tag`.
`std::forward_iterator_tag`.
Otherwise `iterator_category` is
convertible to `std::input_iterator_tag`.
@ -164,7 +163,7 @@ following tables.
[[Writable Lvalue Iterator, Bidirectional Iterator ][Mutable Bidirectional Iterator]]
]
`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
`filter_iterator<P1, X>` is interoperable with `filter_iterator<P2, Y>`
if and only if `X` is interoperable with `Y`.
@ -179,14 +178,14 @@ operations.
filter_iterator();
[*Requires: ]`Predicate` and `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
[*Effects: ] Constructs a `filter_iterator` whose`m_pred`, `m_iter`, and `m_end`
members are a default constructed.
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
the first position in the range `[x,end)` such that `f(*m_iter) == true`
the first position in the range `[x,end)` such that `f(*m_iter) == true`
or else`m_iter == end`. The member `m_pred` is constructed from
`f` and `m_end` from `end`.
@ -197,7 +196,7 @@ operations.
[*Requires: ] `Predicate` must be Default Constructible and
`Predicate` is a class type (not a function pointer).[br]
[*Effects: ] Constructs a `filter_iterator` where `m_iter` is either
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
the first position in the range `[x,end)` such that `m_pred(*m_iter) == true`
or else`m_iter == end`. The member `m_pred` is default constructed.
@ -236,7 +235,6 @@ operations.
[*Effects: ] Increments `m_iter` and then continues to
increment `m_iter` until either `m_iter == m_end`
or `m_pred(*m_iter) == true`.[br]
[*Returns: ] `*this`
[*Returns: ] `*this`
[endsect]
[endsect]

View File

@ -1,4 +1,3 @@
[section:function_output Function Output Iterator]
The function output iterator adaptor makes it easier to create custom
@ -34,7 +33,7 @@ proxy object.
x.push_back("!");
std::string s = "";
std::copy(x.begin(), x.end(),
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::cout << s << std::endl;
@ -68,7 +67,7 @@ proxy object.
[h3 Requirements]
`UnaryFunction` must be Assignable and Copy Constructible.
`UnaryFunction` must be Assignable and Copy Constructible.
[h3 Concepts]
@ -79,14 +78,14 @@ Incrementable Iterator concepts.
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
[*Effects: ] Constructs an instance of `function_output_iterator`
[*Effects: ] Constructs an instance of `function_output_iterator`
with `m_f` constructed from `f`.
unspecified_type operator*();
[*Returns: ] An object `r` of unspecified type such that `r = t`
is equivalent to `m_f(t)` for all `t`.
function_output_iterator& operator++();

View File

@ -49,29 +49,30 @@ using the `make_indirect_iterator` helper function.
const_indirect_last(pointers_to_chars + N);
std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator<char>(std::cout, ","));
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
// Example of using make_indirect_iterator()
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
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;
The output is:
a,b,c,d,e,f,g,
b,c,d,e,f,g,h,
a,b,c,d,e,f,g,
[pre
a,b,c,d,e,f,g,
b,c,d,e,f,g,h,
a,b,c,d,e,f,g,
]
The source code for this example can be found
The source code for this example can be found
[example_link indirect_iterator_example.cpp..here].
@ -136,9 +137,9 @@ the following pseudo-code, where `V` is
else
typedef Reference reference;
if (Value is use_default) then
if (Value is use_default) then
typedef pointee<V>::type\* pointer;
else
else
typedef Value\* pointer;
if (Difference is use_default)
@ -203,7 +204,7 @@ following operations:
indirect_iterator();
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` with
[*Effects: ] Constructs an instance of `indirect_iterator` with
a default-constructed `m_iterator`.
@ -225,7 +226,7 @@ following operations:
);
[*Requires: ] `Iterator2` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs an instance of `indirect_iterator` whose
[*Effects: ] Constructs an instance of `indirect_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.

View File

@ -305,4 +305,3 @@ library you see today.
Patterns, C++ Report, February 1995, pp. 24-27.]
[endsect]

View File

@ -1,4 +1,3 @@
[section:iterator_traits Iterator Traits]
`std::iterator_traits` provides access to five associated types

View File

@ -1,4 +1,3 @@
[section:permutation Permutation Iterator]
The permutation iterator adaptor provides a permuted view of a given
@ -35,7 +34,7 @@ past-the-end iterator to the indices.
*el_it = std::distance(elements.begin(), el_it);
index_type indices( index_size );
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
std::reverse( indices.begin(), indices.end() );
@ -75,13 +74,14 @@ past-the-end iterator to the indices.
The output is:
The original range is : 0 1 2 3 4 5 6 7 8 9
The reindexing scheme is : 9 8 7 6
The permutated range is : 9 8 7 6
Elements at even indices in the permutation : 9 7
Permutation backwards : 6 7 8 9
Iterate backward with stride 2 : 6 8
[pre
The original range is : 0 1 2 3 4 5 6 7 8 9
The reindexing scheme is : 9 8 7 6
The permutated range is : 9 8 7 6
Elements at even indices in the permutation : 9 7
Permutation backwards : 6 7 8 9
Iterate backward with stride 2 : 6 8
]
The source code for this example can be found
[example_link permutation_iter_example.cpp..here].
@ -117,7 +117,7 @@ The source code for this example can be found
};
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator( ElementIterator e, IndexIterator i);
@ -134,15 +134,15 @@ the `IndexIterator` must be convertible to the difference type of
as `IndexIterator` and the same iterator access concepts as
`ElementIterator`.
If `IndexIterator` models Single Pass Iterator and
If `IndexIterator` models Single Pass Iterator and
`ElementIterator` models Readable Iterator then
`permutation_iterator` models Input Iterator.
If `IndexIterator` models Forward Traversal Iterator and
If `IndexIterator` models Forward Traversal Iterator and
`ElementIterator` models Readable Lvalue Iterator then
`permutation_iterator` models Forward Iterator.
If `IndexIterator` models Bidirectional Traversal Iterator and
If `IndexIterator` models Bidirectional Traversal Iterator and
`ElementIterator` models Readable Lvalue Iterator then
`permutation_iterator` models Bidirectional Iterator.
@ -199,7 +199,7 @@ following operations.
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator(ElementIterator e, IndexIterator i);
[*Returns: ] `permutation_iterator<ElementIterator, IndexIterator>(e, i)`

View File

@ -1,4 +1,3 @@
[section:reverse Reverse Iterator]
The reverse iterator adaptor iterates through the adapted iterator
@ -9,7 +8,6 @@ range in the opposite direction.
The following example prints an array of characters in reverse order
using `reverse_iterator`.
char letters_[] = "hello world!";
const int N = sizeof(letters_)/sizeof(char) - 1;
typedef char* base_iterator;
@ -35,10 +33,11 @@ using `reverse_iterator`.
The output is:
original sequence of letters: hello world!
sequence in reverse order: !dlrow olleh
sequence in double-reversed (normal) order: hello world!
[pre
original sequence of letters: hello world!
sequence in reverse order: !dlrow olleh
sequence in double-reversed (normal) order: hello world!
]
The source code for this example can be found
[example_link reverse_iterator_example.cpp..here].
@ -116,7 +115,7 @@ operations.
reverse_iterator();
[*Requires: ] `Iterator` must be Default Constructible.[br]
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
[*Effects: ] Constructs an instance of `reverse_iterator` with `m_iterator`
default constructed.
explicit reverse_iterator(Iterator x);
@ -132,7 +131,7 @@ operations.
);
[*Requires: ] `OtherIterator` is implicitly convertible to `Iterator`.[br]
[*Effects: ] Constructs instance of `reverse_iterator` whose
[*Effects: ] Constructs instance of `reverse_iterator` whose
`m_iterator` subobject is constructed from `y.base()`.
@ -157,4 +156,4 @@ operations.
[*Effects: ] `++m_iterator`[br]
[*Returns: ] `*this`
[endsect]
[endsect]

View File

@ -1,4 +1,3 @@
[section:shared_container Shared Container Iterator]
Defined in header [@../../../boost/shared_container_iterator.hpp `boost/shared_container_iterator.hpp`].
@ -27,12 +26,12 @@ iterator.
namespace boost {
template <typename Container>
class shared_container_iterator;
template <typename Container>
shared_container_iterator<Container>
make_shared_container_iterator(typename Container::iterator base,
make_shared_container_iterator(typename Container::iterator base,
boost::shared_ptr<Container> const& container);
std::pair<
typename shared_container_iterator<Container>,
typename shared_container_iterator<Container>
@ -46,7 +45,7 @@ iterator.
The class template `shared_container_iterator` is the shared container
iterator type. The `Container` template type argument must model the
[@http://www.sgi.com/tech/stl/Container.html Container] concept.
[@http://www.sgi.com/tech/stl/Container.html Container] concept.
[h2 Example]
@ -63,41 +62,43 @@ the underlying vector and thereby extend the container's lifetime.
#include <algorithm>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
void set_range(iterator& i, iterator& end) {
boost::shared_ptr< std::vector<int> > ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
i = iterator(ints->begin(),ints);
end = iterator(ints->end(),ints);
}
int main() {
iterator i,end;
set_range(i,end);
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}
The output from this part is:
0,1,2,3,4,5,
[pre
0,1,2,3,4,5,
]
[table Template Parameters
[[Parameter][Description]]
@ -130,13 +131,13 @@ iterator will be valid. In addition it has the following constructor:
boost::shared_ptr<Container> const& container)
This function provides an alternative to directly constructing a
`shared_container_iterator`. Using the object generator, a
`shared_container_iterator`. Using the object generator, a
`shared_container_iterator` can be created and passed to a function without
explicitly specifying its type.
[h2 Example]
This example, similar to the previous,
This example, similar to the previous,
uses `make_shared_container_iterator()` to create the iterators.
[example_link shared_iterator_example2.cpp..`shared_iterator_example2.cpp`]:
@ -147,35 +148,35 @@ uses `make_shared_container_iterator()` to create the iterators.
#include <iterator>
#include <iostream>
#include <vector>
template <typename Iterator>
void print_range_nl (Iterator begin, Iterator end) {
typedef typename std::iterator_traits<Iterator>::value_type val;
std::copy(begin,end,std::ostream_iterator<val>(std::cout,","));
std::cout.put('\n');
}
int main() {
typedef boost::shared_ptr< std::vector<int> > ints_t;
{
ints_t ints(new std::vector<int>());
ints->push_back(0);
ints->push_back(1);
ints->push_back(2);
ints->push_back(3);
ints->push_back(4);
ints->push_back(5);
print_range_nl(boost::make_shared_container_iterator(ints->begin(),ints),
boost::make_shared_container_iterator(ints->end(),ints));
}
return 0;
}
@ -206,12 +207,12 @@ In the following example, a range of values is returned as a pair of shared_cont
#include "boost/shared_ptr.hpp"
#include "boost/tuple/tuple.hpp" // for boost::tie
#include <algorithm> // for std::copy
#include <iostream>
#include <iostream>
#include <vector>
typedef boost::shared_container_iterator< std::vector<int> > iterator;
typedef boost::shared_container_iterator< std::vector<int> > iterator;
std::pair<iterator,iterator>
return_range() {
boost::shared_ptr< std::vector<int> > range(new std::vector<int>());
@ -223,18 +224,18 @@ In the following example, a range of values is returned as a pair of shared_cont
range->push_back(5);
return boost::make_shared_container_range(range);
}
int main() {
iterator i,end;
boost::tie(i,end) = return_range();
std::copy(i,end,std::ostream_iterator<int>(std::cout,","));
std::cout.put('\n');
return 0;
}
@ -245,4 +246,4 @@ the same as the previous two.
[endsect]
[endsect]
[endsect]

View File

@ -1,4 +1,3 @@
[section:specialized Specialized Adaptors]
[include ./counting_iterator.qbk]
@ -19,4 +18,4 @@
[include ./zip_iterator.qbk]
[endsect]
[endsect]

View File

@ -1,4 +1,3 @@
[section:transform Transform Iterator]
The transform iterator adapts an iterator by modifying the
@ -14,36 +13,37 @@ generate iterators that multiply (or add to) the value returned by
dereferencing the iterator. It would be cooler to use lambda library
in this example.
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const int N = sizeof(x)/sizeof(int);
typedef boost::binder1st< std::multiplies<int> > Function;
typedef boost::transform_iterator<Function, int*> doubling_iterator;
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
std::cout << "multiplying the array by 2:" << std::endl;
while (i != i_end)
std::cout << *i++ << " ";
std::cout << std::endl;
std::cout << "adding 4 to each element in the array:" << std::endl;
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const int N = sizeof(x)/sizeof(int);
typedef boost::binder1st< std::multiplies<int> > Function;
typedef boost::transform_iterator<Function, int*> doubling_iterator;
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
std::cout << "multiplying the array by 2:" << std::endl;
while (i != i_end)
std::cout << *i++ << " ";
std::cout << std::endl;
std::cout << "adding 4 to each element in the array:" << std::endl;
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
The output is:
multiplying the array by 2:
2 4 6 8 10 12 14 16
adding 4 to each element in the array:
5 6 7 8 9 10 11 12
[pre
multiplying the array by 2:
2 4 6 8 10 12 14 16
adding 4 to each element in the array:
5 6 7 8 9 10 11 12
]
The source code for this example can be found
The source code for this example can be found
[example_link transform_iterator_example.cpp..here].
[h2 Reference]
@ -52,8 +52,8 @@ The source code for this example can be found
[h3 Synopsis]
template <class UnaryFunction,
class Iterator,
class Reference = use_default,
class Iterator,
class Reference = use_default,
class Value = use_default>
class transform_iterator
{
@ -116,7 +116,7 @@ where the type of `f(*i)` must be
`result_of<const UnaryFunction(iterator_traits<Iterator>::reference)>::type`.
The argument `Iterator` shall model Readable Iterator.
The argument `Iterator` shall model Readable Iterator.
[h3 Concepts]
@ -126,11 +126,11 @@ The resulting `transform_iterator` models the most refined of the
following that is also modeled by `Iterator`.
* Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
* Writable Lvalue Iterator if `transform_iterator::reference` is a non-const reference.
* Readable Lvalue Iterator if `transform_iterator::reference` is a const reference.
* Readable Iterator otherwise.
* Readable Iterator otherwise.
The `transform_iterator` models the most refined standard traversal
@ -143,11 +143,11 @@ the `Iterator` argument models.
[table Category
[[If `Iterator` models][then `transform_iterator` models]]
[[Single Pass Iterator][Input Iterator]]
[[Forward Traversal Iterator][Forward Iterator]]
[[Bidirectional Traversal Iterator][Bidirectional Iterator]]
[[Random Access Traversal Iterator][Random Access Iterator]]
[[If `Iterator` models][then `transform_iterator` models]]
[[Single Pass Iterator][Input Iterator]]
[[Forward Traversal Iterator][Forward Iterator]]
[[Bidirectional Traversal Iterator][Bidirectional Iterator]]
[[Random Access Traversal Iterator][Random Access Iterator]]
]
If `transform_iterator` models Writable Lvalue Iterator then it is a
@ -177,7 +177,7 @@ operations:
template<class F2, class I2, class R2, class V2>
transform_iterator(
transform_iterator<F2, I2, R2, V2> const& t
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
);

View File

@ -1,17 +1,16 @@
[section:zip Zip Iterator]
The zip iterator provides the ability to parallel-iterate
over several controlled sequences simultaneously. A zip
over several controlled sequences simultaneously. A zip
iterator is constructed from a tuple of iterators. Moving
the zip iterator moves all the iterators in parallel.
Dereferencing the zip iterator returns a tuple that contains
the results of dereferencing the individual iterators.
the results of dereferencing the individual iterators.
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
The tuple of iterators is now implemented in terms of a Boost fusion sequence.
Because of this the 'tuple' may be any Boost fusion sequence and, for backwards
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
compatibility through a Boost fusion sequence adapter, a Boost tuple. Because the
'tuple' may be any boost::fusion sequence the 'tuple' may also be any type for which a
Boost fusion adapter exists. This includes, among others, a std::tuple and a std::pair.
Just remember to include the appropriate Boost fusion adapter header files for these
other Boost fusion adapters. The zip_iterator header file already includes the
@ -22,9 +21,9 @@ to use a Boost tuple as your 'tuple'.
There are two main types of applications of the `zip_iterator`. The first
one concerns runtime efficiency: If one has several controlled sequences
of the same length that must be somehow processed, e.g., with the
of the same length that must be somehow processed, e.g., with the
`for_each` algorithm, then it is more efficient to perform just
one parallel-iteration rather than several individual iterations. For an
one parallel-iteration rather than several individual iterations. For an
example, assume that `vect_of_doubles` and `vect_of_ints`
are two vectors of equal length containing doubles and ints, respectively,
and consider the following two iterations:
@ -53,7 +52,7 @@ These two iterations can now be replaced with a single one as follows:
A non-generic implementation of `zip_func` could look as follows:
struct zip_func :
struct zip_func :
public std::unary_function<const boost::tuple<const double&, const int&>&, void>
{
void operator()(const boost::tuple<const double&, const int&>& t) const
@ -72,16 +71,16 @@ to make combining iterators. A combining iterator is an iterator
that parallel-iterates over several controlled sequences and, upon
dereferencing, returns the result of applying a functor to the values of the
sequences at the respective positions. This can now be achieved by using the
`zip_iterator` in conjunction with the `transform_iterator`.
`zip_iterator` in conjunction with the `transform_iterator`.
Suppose, for example, that you have two vectors of doubles, say
Suppose, for example, that you have two vectors of doubles, say
`vect_1` and `vect_2`, and you need to expose to a client
a controlled sequence containing the products of the elements of
a controlled sequence containing the products of the elements of
`vect_1` and `vect_2`. Rather than placing these products
in a third vector, you can use a combining iterator that calculates the
products on the fly. Let us assume that `tuple_multiplies` is a
functor that works like `std::multiplies`, except that it takes
its two arguments packaged in a tuple. Then the two iterators
its two arguments packaged in a tuple. Then the two iterators
`it_begin` and `it_end` defined below delimit a controlled
sequence containing the products of the elements of `vect_1` and
`vect_2`:
@ -128,7 +127,7 @@ sequence containing the products of the elements of `vect_1` and
template<typename IteratorTuple>
class zip_iterator
{
{
public:
typedef /* see below */ reference;
@ -154,8 +153,8 @@ sequence containing the products of the elements of `vect_1` and
IteratorTuple m_iterator_tuple; // exposition only
};
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t);
The `reference` member of `zip_iterator` is the type of the tuple
@ -168,23 +167,23 @@ of the first of the iterator types in the `IteratorTuple` argument.
The `iterator_category` member of `zip_iterator` is convertible to the
minimum of the traversal categories of the iterator types in the `IteratorTuple`
argument. For example, if the `zip_iterator` holds only vector
iterators, then `iterator_category` is convertible to
iterators, then `iterator_category` is convertible to
`boost::random_access_traversal_tag`. If you add a list iterator, then
`iterator_category` will be convertible to `boost::bidirectional_traversal_tag`,
but no longer to `boost::random_access_traversal_tag`.
[h2 Requirements]
All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
All iterator types in the argument `IteratorTuple` shall model Readable Iterator.
[h2 Concepts]
The resulting `zip_iterator` models Readable Iterator.
The fact that the `zip_iterator` models only Readable Iterator does not
The fact that the `zip_iterator` models only Readable Iterator does not
prevent you from modifying the values that the individual iterators point
to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
constructed from the reference types of the individual iterators, not
to. The tuple returned by the `zip_iterator`'s `operator*` is a tuple
constructed from the reference types of the individual iterators, not
their value types. For example, if `zip_it` is a `zip_iterator` whose
first member iterator is an `std::vector<double>::iterator`, then the
following line will modify the value which the first member iterator of
@ -195,7 +194,7 @@ following line will modify the value which the first member iterator of
Consider the set of standard traversal concepts obtained by taking
the most refined standard traversal concept modeled by each individual
iterator type in the `IteratorTuple` argument.The `zip_iterator`
iterator type in the `IteratorTuple` argument.The `zip_iterator`
models the least refined standard traversal concept in this set.
`zip_iterator<IteratorTuple1>` is interoperable with
@ -254,8 +253,8 @@ operations.
[*Effects:] Decrements each iterator in `m_iterator_tuple`.[br]
[*Returns:] `*this`
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
template<typename IteratorTuple>
zip_iterator<IteratorTuple>
make_zip_iterator(IteratorTuple t);
[*Returns:] An instance of `zip_iterator<IteratorTuple>` with `m_iterator_tuple`
@ -263,4 +262,4 @@ operations.
[endsect]
[endsect]
[endsect]