Boost logo

Boost Users :

From: Sam Partington (Sam.Partington_at_[hidden])
Date: 2003-09-01 05:51:26


Well, I've trimmed you're example down some more, as to me it didn't seem to
be important that the struct was a member of CFilter. So I think your
question boils down to :

struct A
{
        int a;
};
typedef std::map<int, A> my_map;

void do_something_on_a_slice(int a)
{
        // whatever
}

void f(const my_map& map_)
{
        std::for_each(map_.begin(), map_.end(), /*what goes here*/);
}

You could use iterator_adaptors for this, but I think that is complicating
things unnecessarily, something like this would work (untested) :

struct select_a : std::unary_function<my_map::value_type, int>
{
        const result_type& operator()(const argument_type& arg) const
        {
                return arg.second.a;
        }
        // similar non const operator here
};

void f(const std::map<int, A>& map_)
{
        boost::projection_iterator_generator<select_a,
my_map::const_iterator>::type first(map_.begin()), last(map_.end());
        std::for_each(first, last, do_something_on_a_slice);
}

See http://www.boost.org/libs/utility/projection_iterator.htm

But I think bind in this situation is a better solution. (Partly because
the interface to iterator_adaptors will be changing in the next release,
possibly to the point of breaking the above code - Jeremy?)

void f(const my_map& map_)
{
        using boost::bind;
        std::for_each(map_.begin(), map_.end(),
                bind(do_something_on_a_slice,
                        bind(&A::a,
                                bind(&my_map::value_type::second, _1)
                        )
                )
        );
}

Though at this point I would consider writing a function object, any
expression involving three bind's is getting close to (or some might say
past) write-only code.

As to efficiency, if this is a bottleneck it is mostly likely the iteration
over the map that is causing the problem, or the actual 'doing' code. Most
of the binding code should be optimised away by the compiler to a bare
mimimum. It may be that you are better changing container, a sorted vector
perhaps.

HTH

Sam

(PS Apologies if I did miss a point somewhere and oversimplify your code)

Chris Russell <> wrote:
> Hello folks, I've got an interesting little design problem
> and I'm looking
> for some advice on how best to implement an efficient solution.

(snip)

> Here's a simplified statement of the problem that I believe
> outlines the
> relevant details:
>
> I've got a class declared as follows:
>
> --- begin example class ----

> In English: CFilter declares some structure with some number
> of data members
> of arbitrary types. Internally CFilter allocates a std::map of these
> structures using some key_t. Effectively this defines a table
> of data whose
> rows are of type sRow_t, and whose columns can be conceptualized as
> std::vector<A_t>, std::vector<B_t> where
> std::vector<sRow_t.some_member>.size() == mapData<key_t,
> sDataRow_t>.size().
>
> At runtime, CFilter.ProcessRow is called std::map<key_t,
> sRow_t>.size() times followed by a single call to CFilter.ProcessData.
>
> I'm trying to figure out how to _efficiently_ access the
> column vectors in
> the implementation of CFilter.ProcessData.


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