Home | Libraries | People | FAQ | More |
Syntax |
Code |
---|---|
Pipe |
|
Function |
|
Please note that it is frequently unnecessary to use the type_erased
adaptor. It is often better
to use the implicit conversion to any_range
.
Let Rng
be the type of
rng
.
Value
is the
value_type
for the any_range
.
If this is set to boost::use_default, Value
will be calculated from the range type when the adaptor is
applied.
Traversal
is
the tag used to identify the traversal of the resultant range.
Frequently it is desirable to set a traversal category lower
than the source container or range to maximize the number of
ranges that can convert to the any_range
.
If this is left as boost::use_default then Traversal
will be typename boost::iterator_traversal<boost::range_iterator<Rng>::type>::type
Reference
is
the reference
for the any_range
.
boost::use_default
will equate to
typename range_reference<Rng>::type
.
Difference
is the difference_type
for the any_range. boost::use_default
will equate to typename
boost::range_difference<Rng>::type
Buffer
is the
storage used to allocate the underlying iterator wrappers.
This can typically be ignored, but is available as a template
parameter for customization. Buffer must be a model of the
AnyIteratorBufferConcept
.
Traversal
is one of { boost::use_default, boost::single_pass_traversal_tag, boost::forward_traversal_tag, boost::bidirectional_traversal_tag, boost::random_access_traversal_tag
}
typename any_range_type_generator< Rng, Value, Traversal, Reference, Difference, Buffer
>
that represents rng
in a type-erased manner.
Traversal
was specified as boost::use_default
then typename boost::iterator_traversal<boost::range_iterator<Rng>::type>::type
,
otherwise Traversal
.
class AnyIteratorBufferConcept { public: AnyIteratorBufferConcept(); ~AnyIteratorBufferConcept(); // bytes is the requested size to allocate. This function // must return a pointer to an adequate area of memory. // throws: bad_alloc // // The buffer will only ever have zero or one // outstanding memory allocations. void* allocate(std::size_t bytes); // deallocate this buffer void deallocate(); };
#include <boost/range/adaptor/type_erased.hpp> #include <boost/range/algorithm/copy.hpp> #include <boost/assign.hpp> #include <boost/foreach.hpp> #include <iterator> #include <iostream> #include <list> #include <vector> // The client interface from an OO perspective merely requires a sequence // of integers that can be forward traversed typedef boost::any_range< int , boost::forward_traversal_tag , int , std::ptrdiff_t > integer_range; namespace server { void display_integers(const integer_range& rng) { boost::copy(rng, std::ostream_iterator<int>(std::cout, ",")); std::cout << std::endl; } } namespace client { void run() { using namespace boost::assign; using namespace boost::adaptors; // Under most conditions one would simply use an appropriate // any_range as a function parameter. The type_erased adaptor // is often superfluous. However because the type_erased // adaptor is applied to a range, we can use default template // arguments that are generated in conjunction with the // range type to which we are applying the adaptor. std::vector<int> input; input += 1,2,3,4,5; // Note that this call is to a non-template function server::display_integers(input); std::list<int> input2; input2 += 6,7,8,9,10; // Note that this call is to the same non-tempate function server::display_integers(input2); input2.clear(); input2 += 11,12,13,14,15; // Calling using the adaptor looks like this: // Notice that here I have a type_erased that would be a // bidirectional_traversal_tag, but this is convertible // to the forward_traversal_tag equivalent hence this // works. server::display_integers(input2 | type_erased<>()); // However we may simply wish to define an adaptor that // takes a range and makes it into an appropriate // forward_traversal any_range... typedef boost::adaptors::type_erased< boost::use_default , boost::forward_traversal_tag > type_erased_forward; // This adaptor can turn other containers with different // value_types and reference_types into the appropriate // any_range. server::display_integers(input2 | type_erased_forward()); } } int main(int argc, const char* argv[]) { client::run(); return 0; }
This would produce the output:
1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15, 11,12,13,14,15,