Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-01-29 19:27:26


On Tuesday 29 January 2002 05:39 pm, you wrote:
> > This would be the way to stuff a member function pointer +
> > "this" pointer into a Boost.Function object without taking up
> > any additional space.
>
> Yes, in fact, going this route would allow us to write a version of
> 'function<>' class that would take _less_ space than the current
> implementation (1 function pointer + 1 data pointer, instead of current 2
> function pointers plus + 1 function/data pointer).

I'm not quite sure how you plan to do this. At the moment, function<>
requires:
  - a "manager" function pointer that handles allocation, deallocation, and
copying of the underlying function object
  - an "invoker" function pointer that handles calls to the function object
  - a data pointer that contains a pointer to the function object

I can't quite see how to wipe out one of these pointers, except perhaps to
use _really_ dirty tricks, like:

template<typename R, typename T1, typename T2, ..., typename TN>
struct function_object_handle {
  any_pointer (*manager)(any_pointer, operation);
  R (*invoker)(any_pointer, T1, T2, ..., TN);
};

template<typename FunctionObject, typename R, typename T1, typename T2, ...,
         typename TN, typename Allocator>
struct function_object_handler {
  static any_pointer manager(any_pointer, operation);
  static R invoker(any_pointer, T1, T2, ..., TN);

  static function_object_handle<R, T1, T2, ..., TN> handle;
};

template<typename FunctionObject, typename R, typename T1, typename T2, ...,
         typename TN, typename Allocator>
function_object_handle<R, T1, T2, ..., TN>
function_object_handler<FunctionObject, R, T1, T2, ..., TN,
Allocator>::handle = {
  &function_object_handler<...>::manager,
  &function_object_handler<...>::invoker
};

After all this messiness, we could shrink the size of a boost::function
object down to the size of 2 pointers: one pointer to the static "handle"
that's specific to the function object type and contains the addresses of
both the manager and the invoker, and one pointer for the actual data.

> So, returning to the original suggestion ('bind(&my:foo, this)'
> optimization) - can we have it? :)

Here's a start: by the end of this weekend, I promise to have the "stateless
function objects" optimization implemented, and I'll try to get unbound
member function pointers optimized as well (thanks for the incomplete type
trick - very nifty).

If there is some reasonable way to describe bind(&my::foo, this) with
&my::foo as a compile-time constant (and therefore encode it as part of the
type), I'm sure we can work it in without too much trouble.

        Doug


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