Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext
type_erased
type-erased example

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.

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