Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

type_erased
PrevUpHomeNext

Syntax

Code

Pipe

rng | boost::adaptors::type_erased<Value, Traversal, Reference, Difference, Buffer>()

Function

boost::adaptors::type_erase(rng, boost::adaptors::type_erased<Value, Traversal, Reference, Difference, Buffer>)

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.

  • Template parameters:
    • 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.
  • Precondition: 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 }
  • Returns: The returned value is the same as typename any_range_type_generator< Rng, Value, Traversal, Reference, Difference, Buffer > that represents rng in a type-erased manner.
  • Range Category: Single Pass Range
  • Returned Range Category: if Traversal was specified as boost::use_default then typename boost::iterator_traversal<boost::range_iterator<Rng>::type>::type, otherwise Traversal.
AnyIteratorBufferConcept

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,


PrevUpHomeNext