From: Rodolfo Lima (rodolfo_at_[hidden])
Date: 2003-09-13 17:52:07


I'd like to propose an addition to Boost Iterator Adaptor Library. I've come
across the following problem: I have a function that inserts some data in an
output iterator (possibly a inserter_iterator), but the iterator's
value_type isn't the same type of the data i'm inserting. So i'd need a
"conversion" function between the data to be inserted and iterator's value
type. A more real usage would be:

struct data
{
    data(int _a, int _b) : a(_a), b(_b) {};
    data() : a(0), b(0) {};
    int a,b;
    bool operator<(const data &d) const
    {
        if(a==d.a)
            return b < d.b;
        else
            return a < d.a;
    }
};

template<class OutputIter>
void add_random_integer(OutputIter itOut)
{
    *itOut++ = rand();
}

int main()
{
    std::set<data> setData;
    // I need to add data's do setData, but with data::a set to a specific
value, and data::b with a random value. How??
    // This doesn't work: add_random_integer(inserter(setData,
setData.end()));
    // This could be a solution (with my function_inserter and lambda)
    add_random_integer(function_inserter(setData, setData.end(),
bind(constructor<data>(), 10, _1));

    return 0;
}

// function_inserter implementation

template<class Container, class UnaryFunc>
class function_insert_iterator : public std::insert_iterator<Container>
{
    typedef std::insert_iterator<Container> inherited;
public:
    function_insert_iterator(Container &cont, typename Container::iterator
where, const UnaryFunc &fn=UnaryFunc())
  : inherited(cont, where), m_fn(fn) {};

    template<class T>
    function_insert_iterator &operator =(const T &data)
    {
        inherited::operator=(m_fn(data));
        return *this;
    }
    function_insert_iterator& operator*() { inherited::operator*(); }
    function_insert_iterator& operator++() { inherited::operator++(); }
    function_insert_iterator& operator++(int) { inherited::operator++(1); }

private:
    UnaryFunc m_fn;
};

template<class UnaryFunc, class Container>
function_insert_iterator<UnaryFunc, Container> function_inserter(Container
&cont, typename Container::iterator where, const UnaryFunc &fn=UnaryFunc())
{
    return function_insert_iterator<UnaryFunc, Container>(cont, where, fn);
}

That's it. I don't know if there's any other way to do it using existing
libraries. If there is, please let me know.

Regards,
Rodolfo Lima.