Boost logo

Boost Users :

Subject: Re: [Boost-users] [type_erasure] Problem with iterators
From: Marco Guazzone (marco.guazzone_at_[hidden])
Date: 2015-01-30 05:38:36


On Wed, Jan 28, 2015 at 10:21 PM, Steven Watanabe <watanabesj_at_[hidden]> wrote:
> AMDG
>
> On 01/25/2015 03:24 PM, Marco Guazzone wrote:
>> On Sun, Jan 25, 2015 at 7:43 PM, Steven Watanabe <watanabesj_at_[hidden]> wrote:
>>>
>>> You still need same_type<_t, T>. (Yes, I realize
>>> the interface for forward_iterator isn't the best.
>>> same_type<_t, xxx::value_type> shouldn't be necessary,
>>> at the very least.)
>>>
>>
>> So, there is no way to make it work, is it?
>>
>> I've tried many combinations of params, but none of them seems to work.
>>
>> If someone ends up with a working solution, I would be very grateful
>> if (s)he shares it with us :)
>>
>
> I think you need two uses of same_type to make
> it work. _t, T, and ...::value_type all need
> to be the same. If all else fails, the iterator
> concepts are just composed of a bunch of operators
> with a specialization of concept_interface for
> the iterator_traits typedefs.
>

Hi Steven,

Do you mean this?

    typedef mpl::vector< te::forward_iterator<_iter, const _t&>,
                                  te::same_type<_t, T>,
                                  te::same_type<_t,
te::forward_iterator<_iter, const _t&>::value_type> > requirements;
    typedef te::any< requirements, _iter> fwd_iter_type;

If you do, I've tried but it doesn't work :( The entire code is here below.
If you don't, could you please write in C++ your idea?

*** [erasure.cpp] ***
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/iterator.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/same_type.hpp>
#include <boost/type_erasure/tuple.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/smart_ptr.hpp>
#include <cmath>
#include <cstddef>
#include <iostream>
#include <iterator>
#include <vector>

namespace mpl = boost::mpl;
namespace te = boost::type_erasure;

struct _t: te::placeholder { };
struct _iter: te::placeholder { };

template <typename T>
class base
{
protected:
    typedef mpl::vector< te::forward_iterator<_iter, const _t&>,
                         te::same_type<_t, T>,
                         te::same_type<_t, te::forward_iterator<_iter,
const _t&>::value_type> > requirements;
    typedef te::any< requirements, _iter> fwd_iter_type;
public:
    virtual ~base() { }

    template <typename IterT>
    std::vector<T> foo(IterT first, IterT last) const
    {
        return this->do_foo(first, last);
    }
private:
    virtual std::vector<T> do_foo(fwd_iter_type first, fwd_iter_type
last) const = 0;
}; // base

template <typename T>
class derived: public base<T>
{
private:
    typedef typename base<T>::fwd_iter_type fwd_iter_type;

    std::vector<T> do_foo(fwd_iter_type first, fwd_iter_type last) const
    {
        const std::ptrdiff_t n = std::distance(first, last);
        std::vector<T> res(n);
        for (std::size_t i = 0; first != last; ++first, ++i)
        {
            //res[i] = std::pow(static_cast<T>(*first),i)/n;
            res[i] = std::pow(*first,i)/n;
        }
        return res;
    }
}; // derived

int main()
{
    std::vector<double> dv;
    dv.push_back(5);
    dv.push_back(8);
    dv.push_back(11);

    boost::scoped_ptr< base<double> > p_base(new derived<double>());

    // begin/end
    const std::vector<double> foos = p_base->foo(dv.begin(), dv.end());
    for (std::size_t i = 0; i < foos.size(); ++i)
    {
        std::cout << "foos[" << i << "]: " << foos[i] << std::endl;
    }
    // cbegin/cend
    const std::vector<double> cfoos = p_base->foo(dv.cbegin(), dv.cend());
    for (std::size_t i = 0; i < cfoos.size(); ++i)
    {
        std::cout << "cfoos[" << i << "]: " << cfoos[i] << std::endl;
    }
}

*** [/erasure.cpp] ***

Thank you very much.

-- Marco


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net