
Hi Andy, Andy Little wrote:
"Tobias Schwinger" <tschwinger@neoscientists.org> wrote in message news:d8q4ch$dp7$1@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