Boost logo

Boost :

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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk