Boost logo

Boost :

From: Tom Brinkman (reportbase_at_[hidden])
Date: 2008-06-19 11:18:53


One thing you can do to make Gil algorithms more generic and usable
with boost::fusion or boost function is to wrap them like below into
generic functors.

Grouping your drawing algorithims like the following
examples allow you to create really powerful generic drawing algorithms.

See example below.

You have to follow each step. I've used this technique to good effect and
I"m thinking about writing an article about this.

With these techiques, you should be able to use
all the functionality of boost::fusion, boost::function and boost::signal,
as well as all the other cool generic libraries on boost.

//Step 1: Create a generic algorithm that operates on a GIL View generically
namespace impl
{
        
template <typename view_t>
void do_something(view_t view, typename view_t::value_type value)
{
        
}

}

//Step 2a: Create Generic Functors (most generic structure)
struct do_something
{
        template <typename view_t>
        void operator(view_t view)
        {
                impl::do_something(view,rgb8_pixel_type(0,0,0));
        }
};

//Step 2b: Create Generic Functors (less generic structure)
template <typename view_t>
struct do_something2
{
        typedef typename view_t::value_type value_type_t;
        value_type_t color;
        
        do_something2(value_type_t color) : color(color) {}
                
        void operator(view_t view)
        {
                impl::do_something(view,color);
        }
}

//Step 3: wrap your algorithms like this:
template <typename view_t>
void do_something_special(view_t view)
{
        typedef boost::function<void (view_t)> operation_t;

        operation_t operations[] =
        {
                do_something(),
                do_something2<rgb8_view_t>(rgb8_pixel_t(0,0,0))
                do_something3<rgb8_view_t>(rgb8_pixel_t(100,0,0))
                do_something4<rgb8_view_t>(rgb8_pixel_t(100,0,100))
        };

        draw<view_t> draw(operations,sizeof(operations)/sizeof(operation_t));
        draw(view);
}

//Step 4: The draw functor
template <template view_t>
struct draw
{
        typedef boost::function<void (view_t)> operation_t;
        typedef std::vector<operation> operations_t;
        operations_t operations;
        
        draw(operations* operations_, int size)
        {
                     for (int n = 0; n < size; ++n)
                               operations.push_back(operations_[n]);
        }
                
        void operator()(view_t view)
        {
                operations_t::iterator it = operations.begin();
                for (; it != operations.end(); ++it)
                {
                        operation_t operation = *it;
                        operation(view);
                }
        }
};

//Step 5: The Real Benefit. Grouping your drawing algorithims like
//this allows you to create really powerful generic drawing algorithms.
//This is where it gets cool!!!

template <typename view_t>
void do_something_else(view_t view)
{
        typedef boost::function<void (view_t&)> operation_t;

        operation_t operations[] =
        {
                do_something(),
                do_something2<rgb8_view_t>(rgb8_pixel_t(0,0,0))
                do_something3<rgb8_view_t>(rgb8_pixel_t(100,0,0))
                do_something4<rgb8_view_t>(rgb8_pixel_t(100,0,100))
        };

        operation_t operations2[] =
        {
                draw<view_t>(operations,sizeof(operations)/sizeof(operation_t));
                draw2<view_t>(operations,sizeof(operations)/sizeof(operation_t));
                draw3<view_t>(operations,sizeof(operations)/sizeof(operation_t));
        };

        draw4<view_t> draw4(operations2,sizeof(operations2)/sizeof(operation_t));
        draw4(view);
}


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