Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2005-06-17 17:23:50


Hi Andy,

Andy Little wrote:
>
> "Tobias Schwinger" <tschwinger_at_[hidden]> wrote in message
> news:d8q4ch$dp7$1_at_sea.gmane.org...
>
>> Hi Andy,
>>
>> thank you for your review !
>
>
> No problem. Sorry I'm not more of an expert on this :-)
>
> [snip]
>
>> Looking closer at the type synthesis part we would end up with lots of
>> functions
>> that do exactly the same thing. E.g:
>>
>> function_pointer<Seq>
>> defaultcall_function_pointer<Seq>
>> non_variadic_function_pointer<Seq>
>> non_variadic_defaultcall_function_pointer<Seq>
>
>
>> or we would only use the "most concrete" (the one at the bottom of the
>> list --
>> I
>> guess its name is already enough reason not to seriously consider
>> this) or we
>> would drop the symmetry of sythesis and decomposition (imposing a huge
>> ammount
>> of irregularity on the user).
>
>
> Ok.
>
>>> OTOH why not do it the other way round eg
>>>
>>> template<typename F, typename Tag = any_function>
>>> struct is_function_type;
>>
>>
>> I found it appealing to have the tag next to ("extend") the identifier.
>
>
> I prefer the 'policy' at the end ... whatever.
>
>>> eg giving is_function_type<F> for what I guess is the most usual case.
>>
>>
>> Don't think so. I don't see a reasonable default, here.
>>
>>> I know this overlaps type_traits, but therefore is this any_function
>>> necessary?
>>
>>
>> In fact, this particular case doesn't (at least not exactly), but it
>> can be
>> modeled with TypeTraits, if this is what you mean. It will look
>> somewhat like
>> this (untested freehand code):
>>
>> mpl::or_<
>> is_function<
>> typename remove_reference<typename remove_pointer<T>::type>::type
>> >
>> , is_member_function_pointer<T> >
>
>
> OK...something else to mention in the documentation IMO. Would be nice
> to show
> relation.

Good one!

>
>>> Does providing non functions-types to eg function_type_arity<F> give a
>>> compile
>>> time assertion? Cos I think it should!
>>
>>
>> It gives you a compile error at the point you try to access '::value'
>> ("function_type_arity<Blah blah blah> does not have a member named
>> value").
>>
>> 'BOOST_STATIC_ASSERT' or 'BOOST_MPL_ASSERT*' are not used for this,
>> because
>> this
>> would trigger an error inside the library, instead of where the actual
>> problem
>> in client code is.
>
>
> Ok .. hmmm.... I reckon compiler error messages are output upside down.

Depends on how you look at it...

> They
> make
> it easy for the libarray author, rather than the user.
> A switch to print error messages in reverse order would be nice :-)

There is usually a trace from the point of the error to the outermost template
instantiation. You'ld need a "one-before-the-innermost-switch", here ;-).

>
>>> I would really like an accessible example right at the start.
>>> What is this library useful for? The example source files seem to
>>> have little
>>> regard for anyone reading them.
>>
>>
>> You're right - it's missing.
>
>
> Yes and something regarding decomposing a function and then doing the
> reverse
> ...synthesising it (if thats the correct use of 'synthesis') from the
> decomposed bits.
>
>>> The closure example looks interesting
>>> (though I'm not sure what a closure is) but
>>
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> There is a brief introduction in the header, if it doesn't work for
>> you, try
>> Wikipedia or alike.
>
>
> Ok I guess it would make sense if I found a use for it ;-)
>

The designers at Borland, however found a use. So much, in fact, that they added
a non-standard compiler extension for it (and the compatiblity with Delphi, I
believe). C++Builder attaches event handlers to GUI components, this way.

The example is pretty much modeled after these non-standard types understood by BCC.

>>
>> - interpreter.hpp
>> [ http://tinyurl.com/bu5vn ]
>>
>> - interpreter_example.cpp
>> [ http://tinyurl.com/8ryt3 ]
>
>
>
> Whoa ... This is too complicated. Can you not just isolate the
> function_types
> part?

The number of lines may be scaring. But hey, cheer up - most of them are
comments and good old runtime code ;-).

Seriously, I'ld like to leave this as-is and add more simpler ones (especially
as simple as a few lines - for the documentation).

Contributions are welcome, of course.

> // struct to 'normalise' a function: takes a tuple of args
> // rather than the args directly

Sorry to disappoint you, but this might be less exciting than you had hoped.

(Un)fortunately there is (AFAIK) no way to get the size of a boost::tuple at
compile time.
So we'll use the arity of the function instead (which is worse because we could
handle default arguments, otherwise).
To not only use the library for a workaround here, I'll add a static assertion
to restrict it to function pointers ;-).

Untested code ahead, but it should be easy enough for my typos to be fixable
(hope it works for you)...

     template<std::size_t N> struct function_feeder;

     template<> struct function_feeder<0>
     {
        template<class Function, class Tuple>
        static void feed(Function f, Tuple&)
        {
          f();
        }
     };
     template<> struct function_feeder<1>
     {
        template<class Function, class Tuple>
        static void feed(Function f, Tuple& t)
        {
          f(get<0>(t));
        }
     };
     template<> struct function_feeder<2>
     {
        template<class Function, class Tuple>
        static void feed(Function f, Tuple& t)
        {
          f(get<0>(t),get<1>(t));
        }
     };
     //...

     template<class Function, class Tuple>
     void feed_function(Function f, Tuple& t)
     {
       BOOST_STATIC_ASSERT((
         ::boost::is_function_type<function_pointer,Function>::value
       ));
       function_feeder< ::boost::function_type_arity<Function>::value >
         ::feed(f,t);
     }
     // TODO: make compile, extend at will

Thanks,

Tobias


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