Boost.function enhanced (a little)
I could never understand, why the boost.function class/es do/es/n't
support
what Loki's functor can do: hassle-free taking an instance plus
member
function...
Of course you can do that with std.bind1st plus std.mem_fct or
boost.bind
etc., but I think this is annoying...
What I always liked with boost.function was the kind of template
argument. It
was the way I would think it should be. (Sorry Andrej, I like
typelists - but
not here.) On the other hand, Loki's way assigning either a function
pointer,
or a member function together with an instance (in a closure) without
any
binding-stuff. I think this is really neat: No binding with the
knowledge
of at least the count of arguments etc.
So I wrote a wrapper (s.b.) and I want to introduce it here - and
start a
discussion, what might be a reason not to use it (and perhaps further
why not
add it to the lib but leave it to the users of boost.function "re-
inventing
this wheel" allover again.
Okay, here it comes. The wrapper looks like this:
//-/////////////////////////////////////////////////////////////////////////-//
// Copyright (c) 2009 by Juergen Busch
//
// You are free to use and modify it for any purpose.
//-/////////////////////////////////////////////////////////////////////////-//
// Usage hints:
//
// typedef it like this:
// typedef
// ::jaybus56::boost_ed::functor< int ( const char*, int, char) >
// tBeautiful;
// with:
// int SomeFct( const char*, int, char) {
// ...
// }
// int SomeOtherFct( const char*, int, char) {
// ...
// }
// class SomeClass {
// ...
// public:
// int SomeMemFct( const char*, int, char);
// ...
// } someInst;
// use the typedef like this (avoids to repeat the fct_pttrn):
// tBeautiful::function f;
// ...
// f = SomeFct; // the "old fashioned way" still works
// ...
// f = tBeautiful( SomeOtherFct);
// ...
// // of course the old way works too:
// f = boost::bind( &SomeClass::SomeMemFct, &someInst, _1, _2, _3);
// ...
// // but doesn't it look much better this way? :
// f = tBeautiful( &someInst, &SomeClass::SomeMemFct);
// ...
//
#include "boost/function.hpp"
#include "boost/bind.hpp"
#include "boost/type_traits.hpp"
#include "boost/mpl/int.hpp"
//-----------------------------------------------------------------------------
namespace jaybus56 {
namespace boost_ed {
//-----------------------------------------------------------------------------
template < class boost_fct_pttrn>
class functor: public ::boost::function< boost_fct_pttrn>
{
public:
typedef ::boost::function< boost_fct_pttrn> function;
enum CONSTANTS { arity = function::arity };
public:
template< class F>
functor( F f)
: function( f)
{}
template< class T, class F>
functor( T *t, F f)
{
*this = Binding( t, f, ::boost::mpl::int_<arity>());
}
operator function() const { return *this;}
// Mother's little helpers ;-)
private:
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<1>) const
{ return function( ::boost::bind( f, t, _1)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<2>) const
{ return function( ::boost::bind( f, t, _1, _2)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<3>) const
{ return function( ::boost::bind( f, t, _1, _2, _3)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<4>) const
{ return function( ::boost::bind( f, t, _1, _2, _3, _4)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<5>) const
{ return function( ::boost::bind( f, t, _1, _2, _3, _4, _5)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<6>) const
{ return function( ::boost::bind( f, t, _1, _2, _3, _4, _5, _6)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<7>) const
{ return function( ::boost::bind( f, t, _1, _2, _3, _4, _5, _6,
_7)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<8>) const
{ return function( ::boost::bind( f, t, _1, _2, _3, _4, _5, _6, _7,
_8)); }
template< class T, class F>
function Binding( T *t, F f, ::boost::mpl::int_<9>) const
{ return function( ::boost::bind( f, t, _1, _2, _3, _4, _5, _6, _7,
_8, _9)); }
};
//
=============================================================================
//-----------------------------------------------------------------------------
}// namespace boost_ed
}// namespace jaybus56
//-----------------------------------------------------------------------------
//-/////////////////////////////////////////////////////////////////////////-//
Question: Do you see any reason, why not using this wrapper (or
similar)? Comments appreciated!
Yours Juergen
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]