| Home | Libraries | People | FAQ | More

##### type_erased

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 desireable 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();
    };

###### type-erased example

    #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