Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2003-03-28 12:01:04


"Chris Trengove" <trengove_at_[hidden]> writes:

> A question for David Abrahams (or anyone else who might have a bright idea).
>
> I have resolved quite a few of the issues involved in porting Boost.Python
> to Borland, but here is one particularly nasty problem. In
> member_function_cast.hpp you have code, which after expansion at the hands
> of Boost.Preprocessor, gives
>
> template <class T>
> struct member_function cast
> {
> template <class S,class R>
> static cast_helper<S, R (T::*) ()> stage1(R (S::*)())
> {
> return cast_helper<S, R (T::*)()>();
> }
>
> // Many more definitions of stage1() with increasing numbers of
> parameters (arity).
> };
>
> Unfortunately, this runs foul of the infamous BCC "emoticon" bug, whereby
> the ")" character (and various others) will terminate the template argument
> list. In the above, the compiler therefore sees "cast_helper<S,R
> (T::*[end_of_template]". I assume that it is this bug which mandates the
> special treatment for BCC in
> boost/type_traits/is_member_function_pointer.hpp.
>
> The standard workaround is to use a typedef, which in this case would be
>
> typedef R (T::*T_mfp)();
> static cast_helper<S,T_mfp> stage1(...)
>
> But of course here we will need separate typedefs for each of the "arities"
> of stage1(), and we need to define them so that they are available to the
> stage1 template. It seems to me that the function overloading approach being
> used here then becomes infeasible.
>
> Any ideas?

The contorted structure of the member_function_cast dance that we do:

    python::detail::member_function_cast<Target,F>::stage1(f).stage2((Target*)0).stage3(f)

Is due to a combination of compiler bugs: vc6+7 which don't support
partial specialization and Codewarrior 7 which doesn't support the
"sizeof(somefunction(x))" trick (and thus is_base_and_derived,
is_convertible, et. al don't work).

You can get an idea of the intended semantics of this dance by looking
at libs/python/test/member_function_cast.cpp. The idea is that if f
is a member function, and its class is a base class of Target, it
will be implicitly converted to a pointer-to-member of Target.
Otherwise it will be left alone.

We are going to drop support for CodeWarrior 7 in the next version of
Boost.Python anyway, so you could reimplement those semantics with a
much more straightforward interface that works with BCC. I think you
should be able to make

     member_function_cast<Target>(f)

work.

HTH,

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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