[functional] Interested in can_be_called<F, Sig> metafunction?

Hi there, I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in public. Synopsis -------------- can_be_called<F, Sig> F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only. Example ------------- struct X; struct F { void operator()(); }; can_be_called<void(int), void(char)>::type // mpl::true_ can_be_called<int(), void()>::type // mpl::true_, return val can always be discarded can_be_called<int(), int&()>::type // mpl::false_, cannot return as reference can_be_called<void(int&), void(int)>::type // mpl::false_, cannot accept rvalue can_be_called<void(), void(*)()>::type // compile error, "void(*)()" not a function-type can_be_called<F, void()>::type // mpl::true_ can_be_called<F const, void()>::type // mpl::false_, F::operator() is non-const can_be_called<void(X::*)(), void()>::type // mpl::true_, only the signature part is concerned can_be_called<void(X::*)(), void(X*)>::type // mpl::false_, implicit 'this' arg not accounted Repository ---------------- https://github.com/jamboree/boost.functional test files provided, compile well on g++ 4.7.1 & clang 3.2 No docs are written (yet), if you're interested, please let me know and I'll prepare for review or something... Comments are welcome :)

2012/11/4 TONGARI <tongari95@gmail.com>
Hi there,
I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in public.
Synopsis -------------- can_be_called<F, Sig>
F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only.
Example ------------- struct X;
struct F { void operator()(); };
can_be_called<void(int), void(char)>::type // mpl::true_ can_be_called<int(), void()>::type // mpl::true_, return val can always be discarded can_be_called<int(), int&()>::type // mpl::false_, cannot return as reference can_be_called<void(int&), void(int)>::type // mpl::false_, cannot accept rvalue can_be_called<void(), void(*)()>::type // compile error, "void(*)()" not a function-type can_be_called<F, void()>::type // mpl::true_ can_be_called<F const, void()>::type // mpl::false_, F::operator() is non-const can_be_called<void(X::*)(), void()>::type // mpl::true_, only the signature part is concerned can_be_called<void(X::*)(), void(X*)>::type // mpl::false_, implicit 'this' arg not accounted
Repository ---------------- https://github.com/jamboree/boost.functional
test files provided, compile well on g++ 4.7.1 & clang 3.2
No docs are written (yet), if you're interested, please let me know and I'll prepare for review or something...
Comments are welcome :)
Forgot to mention that there are 2 implementations provided, unlimited & limited, limited one can be used w/o variadic template support and has a function-arity limit defined by BOOST_CAN_BE_CALLED_MAX_ARITY. It's shipped with preprocessed headers.

On 04/11/2012 14:15, TONGARI wrote:
Hi there,
I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in public.
Synopsis -------------- can_be_called<F, Sig>
F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only.
Personally, I've found it more useful to just not define result_of<F(args)>::type if F(args) cannot be called.

On Sun, Nov 4, 2012 at 2:23 PM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
Personally, I've found it more useful to just not define result_of<F(args)>::type if F(args) cannot be called.
The only problem with that is that you have to rely on the creator of a function object to abide by this convention. "can_be_called" (callable might be a simpler name and is what was used with C++0x concepts) would work regardless of whether or not result_of is defined. Anyway, +1 from me to the idea of a can_be_called metafunction. Just because it might be something to consider in terms of interface, the way Callable was with concepts was defined is the following ( http://generic.nfshost.com/generic/standard_concepts/concepts/callable.html ): //////////////////////////////////////////////////////////////////////////////// auto concept Callable <file:///E:/boost_sandbox/generic/libs/doc/html/boost_generic/standard_concepts/concepts/callable.html><typename F, typename... Args> { typename result_type; result_type operator()(F&, Args...); result_type operator()(F&&, Args...);} //////////////////////////////////////////////////////////////////////////////// So, instead of specifying the return type when invoking the metafunction, it automatically defines an associated type "result_type," which a programmer could then check against if he or she desired. Again, your implementation may be more useful depending on the context, but this is something to consider. -- -Matt Calabrese

2012/11/5 Matt Calabrese <rivorus@gmail.com>
So, instead of specifying the return type when invoking the metafunction, it automatically defines an associated type "result_type," which a programmer could then check against if he or she desired. Again, your implementation may be more useful depending on the context, but this is something to consider.
In the case that return type is unimportant, just leave it as void, e.g. can_be_called<F, void(Args...)> BTW, the Boost.Generic Definition column in your page seems to use ",,," instead of "..." for VA, is that true?

On Sun, Nov 4, 2012 at 11:28 PM, TONGARI <tongari95@gmail.com> wrote:
2012/11/5 Matt Calabrese <rivorus@gmail.com>
So, instead of specifying the return type when invoking the metafunction, it automatically defines an associated type "result_type," which a programmer could then check against if he or she desired. Again, your implementation may be more useful depending on the context, but this is something to consider.
In the case that return type is unimportant, just leave it as void, e.g.
can_be_called<F, void(Args...)>
BTW, the Boost.Generic Definition column in your page seems to use ",,," instead of "..." for VA, is that true?
Yes, that's true. The code in the documentation is pulled directly from the library code, which is tested, so what's documented should always be correct. That is also why in some of the documentation you might see workarounds or little bits commented out that I can't support yet). The reason it's ",,," and not "..." is because it's impossible to detect "..." in the preprocessor. On the other hand, ",,," can be detected by passing the data to a variadic macro and seeing if it contains a group of empty arguments in a row. -- -Matt Calabrese

On 04/11/2012 20:54, Matt Calabrese wrote:
On Sun, Nov 4, 2012 at 2:23 PM, Mathias Gaunard < mathias.gaunard@ens-lyon.org> wrote:
Personally, I've found it more useful to just not define result_of<F(args)>::type if F(args) cannot be called.
The only problem with that is that you have to rely on the creator of a function object to abide by this convention. "can_be_called" (callable might be a simpler name and is what was used with C++0x concepts) would work regardless of whether or not result_of is defined.
result_of does not have to be implemented in terms of result<Sig>::type/result_type. template<class T, class R = void> struct enable_if_type { typedef R type; }; template<class Sig, class Enable = void> struct result_of {}; template<class F, class... Args> struct result_of<F(Args...) , typename enable_if_type< decltype( std::declval<F>() (std::declval<Args>()...) ) >::type > { typedef decltype(std::declval<F>()(std::declval<Args>()...)) type; }; Of course, if you don't have decltype, you can't do that and must use the result_type or result templates. In C++03, you'll be able to deduce whether the expression in valid, but not what the result type is.

On 11/4/2012 5:15 AM, TONGARI wrote:
Hi there,
I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in public.
Synopsis -------------- can_be_called<F, Sig>
F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only.
There is a feature request for this already in Trac, with source code attached. https://svn.boost.org/trac/boost/ticket/3783 Sadly, it was opened 3 years ago. -- Eric Niebler BoostPro Computing http://www.boostpro.com

2012/11/6 Eric Niebler <eric@boostpro.com>
On 11/4/2012 5:15 AM, TONGARI wrote:
Hi there,
I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in public.
Synopsis -------------- can_be_called<F, Sig>
F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only.
There is a feature request for this already in Trac, with source code attached.
https://svn.boost.org/trac/boost/ticket/3783
Sadly, it was opened 3 years ago.
Surely I'm aware of this, but I don't think it'd work out-of-box, would it?

On 11/5/2012 9:12 PM, TONGARI wrote:
2012/11/6 Eric Niebler <eric@boostpro.com>
On 11/4/2012 5:15 AM, TONGARI wrote:
Hi there,
I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in public.
Synopsis -------------- can_be_called<F, Sig>
F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only.
There is a feature request for this already in Trac, with source code attached.
https://svn.boost.org/trac/boost/ticket/3783
Sadly, it was opened 3 years ago.
Surely I'm aware of this, but I don't think it'd work out-of-box, would it?
What do you mean? If you mean that the attached code needs polish, I guess you're probably right, but it's been 3 years since I wrote it. :-) If your code is polished, has docs, and tests, then maybe you can attach it to the ticket and ping Tobias. If he doesn't respond, then I guess Function_types is looking for a new maintainer, and you could be it. -- Eric Niebler BoostPro Computing http://www.boostpro.com

2012/11/6 Eric Niebler <eric@boostpro.com>
2012/11/6 Eric Niebler <eric@boostpro.com>
On 11/4/2012 5:15 AM, TONGARI wrote:
Hi there,
I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in
On 11/5/2012 9:12 PM, TONGARI wrote: public.
Synopsis -------------- can_be_called<F, Sig>
F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only.
There is a feature request for this already in Trac, with source code attached.
https://svn.boost.org/trac/boost/ticket/3783
Sadly, it was opened 3 years ago.
Surely I'm aware of this, but I don't think it'd work out-of-box, would it?
What do you mean? If you mean that the attached code needs polish, I guess you're probably right, but it's been 3 years since I wrote it. :-)
That was my first try that doesn't compile, but it's due to the disability in file iteration for local include path on the compiler I used, but it's easy to fix anyway. And some misreading in your code gave me the impression that it won't work properly, but surely it does work :-) Regarding the difference, mine also concerns the return type (it's useful in my case) and capable of member-function ptr (not sure it's useful or not) and may work for some contrived cases...
If your code is polished, has docs, and tests, then maybe you can attach it to the ticket and ping Tobias. If he doesn't respond, then I guess Function_types is looking for a new maintainer, and you could be it.
But I don't want it in FunctionTypes, Functional seems a better place to me and could just become Functional/Can Be Called as other Functional/XXX.

On Tue, Nov 6, 2012 at 12:22 AM, TONGARI <tongari95@gmail.com> wrote:
2012/11/6 Eric Niebler <eric@boostpro.com>
2012/11/6 Eric Niebler <eric@boostpro.com>
On 11/4/2012 5:15 AM, TONGARI wrote:
Hi there,
I've used this metafunction for some time, and it just fitted my need. Recently, I make up my mind to complete it, willing to put it in
On 11/5/2012 9:12 PM, TONGARI wrote: public.
Synopsis -------------- can_be_called<F, Sig>
F Any callable type to test, even member-function ptr. Sig The desired calling signature, function-type only.
There is a feature request for this already in Trac, with source code attached.
https://svn.boost.org/trac/boost/ticket/3783
Sadly, it was opened 3 years ago.
Surely I'm aware of this, but I don't think it'd work out-of-box, would it?
What do you mean? If you mean that the attached code needs polish, I guess you're probably right, but it's been 3 years since I wrote it. :-)
That was my first try that doesn't compile, but it's due to the disability in file iteration for local include path on the compiler I used, but it's easy to fix anyway.
And some misreading in your code gave me the impression that it won't work properly, but surely it does work :-)
Regarding the difference, mine also concerns the return type (it's useful in my case) and capable of member-function ptr (not sure it's useful or not) and may work for some contrived cases...
If your code is polished, has docs, and tests, then maybe you can attach it to the ticket and ping Tobias. If he doesn't respond, then I guess Function_types is looking for a new maintainer, and you could be it.
But I don't want it in FunctionTypes, Functional seems a better place to me and could just become Functional/Can Be Called as other Functional/XXX.
Wouldn't this fit in Boost.TypeTraits, along side the other type traits that introspect operators? - Jeff

2012/11/6 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
Wouldn't this fit in Boost.TypeTraits, along side the other type traits that introspect operators?
TypeTraits is also in my consideration, so I'm not against it. So would you suggest opening up a new Functional category in that?

On Tue, Nov 6, 2012 at 7:14 AM, TONGARI <tongari95@gmail.com> wrote:
2012/11/6 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
Wouldn't this fit in Boost.TypeTraits, along side the other type traits that introspect operators?
TypeTraits is also in my consideration, so I'm not against it. So would you suggest opening up a new Functional category in that?
Hmmm, well, maybe for documentation purposes, but I think that's the only place that Boost.TypeTraits has a notion of category...? I would think it might be sufficient to group it with the operator type traits in the documentation, though. - Jeff

2012/11/7 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
On Tue, Nov 6, 2012 at 7:14 AM, TONGARI <tongari95@gmail.com> wrote:
2012/11/6 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
Wouldn't this fit in Boost.TypeTraits, along side the other type traits that introspect operators?
TypeTraits is also in my consideration, so I'm not against it. So would you suggest opening up a new Functional category in that?
Hmmm, well, maybe for documentation purposes, but I think that's the only place that Boost.TypeTraits has a notion of category...? I would think it might be sufficient to group it with the operator type traits in the documentation, though.
Well, though conceptually reasonable, but that'd seem exotic in all of the others named has_xxx... I still prefer a new place if possible that I could have more control on it.

Le 07/11/12 06:18, TONGARI a écrit :
2012/11/7 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
On Tue, Nov 6, 2012 at 7:14 AM, TONGARI <tongari95@gmail.com> wrote:
2012/11/6 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
Wouldn't this fit in Boost.TypeTraits, along side the other type traits that introspect operators?
TypeTraits is also in my consideration, so I'm not against it. So would you suggest opening up a new Functional category in that?
Hmmm, well, maybe for documentation purposes, but I think that's the only place that Boost.TypeTraits has a notion of category...? I would think it might be sufficient to group it with the operator type traits in the documentation, though.
Well, though conceptually reasonable, but that'd seem exotic in all of the others named has_xxx... Hi,
Boost.TypeTraits has other traits as is_, ... What about is_callable_with?
I still prefer a new place if possible that I could have more control on it.
What kind of control do you want? Best, Vicente

2012/11/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
Le 07/11/12 06:18, TONGARI a écrit :
2012/11/7 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
On Tue, Nov 6, 2012 at 7:14 AM, TONGARI <tongari95@gmail.com> wrote:
2012/11/6 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
Wouldn't this fit in Boost.TypeTraits, along side the other type traits
that introspect operators?
TypeTraits is also in my consideration, so I'm not against it. So would you suggest opening up a new Functional category in that?
Hmmm, well, maybe for documentation purposes, but I think that's the
only place that Boost.TypeTraits has a notion of category...? I would think it might be sufficient to group it with the operator type traits in the documentation, though.
Well, though conceptually reasonable, but that'd seem exotic in all of
the others named has_xxx...
Hi,
Boost.TypeTraits has other traits as is_, ... What about is_callable_with?
Hmmm, then I'd prefer a shorter "has_call" that'd fit in Operator Type Traits better. But do you think member-function ptr fits in this context? e.g. has_call<void(X::*)(), void()>::type // mpl::true_
I still prefer a new place if possible that I could have more control on
it.
What kind of control do you want?
To rule the doc style and include hierarchy, providing specific macros for compile/preprocess, for example. Otherwise I have to follow the convention of the parent lib...

Le 07/11/12 09:18, TONGARI a écrit :
2012/11/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
Le 07/11/12 06:18, TONGARI a écrit :
2012/11/7 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com>
Wouldn't this fit in Boost.TypeTraits, along side the other type traits
that introspect operators?
TypeTraits is also in my consideration, so I'm not against it. So would you suggest opening up a new Functional category in that?
Hmmm, well, maybe for documentation purposes, but I think that's the only
2012/11/6 Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> place that Boost.TypeTraits has a notion of category...? I would think it might be sufficient to group it with the operator type traits in the documentation, though.
Well, though conceptually reasonable, but that'd seem exotic in all of
On Tue, Nov 6, 2012 at 7:14 AM, TONGARI <tongari95@gmail.com> wrote: the others named has_xxx...
Hi,
Boost.TypeTraits has other traits as is_, ... What about is_callable_with?
Hmmm, then I'd prefer a shorter "has_call" that'd fit in Operator Type Traits better. has_ is related to something a class can have, while is_ can be applied to a class or a function. But do you think member-function ptr fits in this context? e.g.
has_call<void(X::*)(), void()>::type // mpl::true_
I don't think this fill you initial can_be_called. Do you?
I still prefer a new place if possible that I could have more control on
it.
What kind of control do you want? To rule the doc style and include hierarchy, providing specific macros for compile/preprocess, for example. Could you give some examples? Otherwise I have to follow the convention of the parent lib...
Could you say what is wrong following the parent lib? Best, Vicente

2012/11/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
has_ is related to something a class can have, while is_ can be applied to a class or a function.
Not necessary. Those in Operator Type Traits can be used on non-class types, e.g. has_plus<int>, so has_call is consistent with that.
But do you think member-function ptr fits in this context? e.g.
has_call<void(X::*)(), void()>::type // mpl::true_
I don't think this fill you initial can_be_called. Do you?
Actually I'm not sure if it's feasible to support member-function ptr at all, what do others think?
Could you say what is wrong following the parent lib?
Nothing, just a bit tedious :p So my current prefer would be "has_call" under Operator Type Traits category. BTW, the History section seems unupdated even after the extension added :-/

On Wed, Nov 7, 2012 at 5:23 AM, TONGARI <tongari95@gmail.com> wrote:
2012/11/7 Vicente J. Botet Escriba <vicente.botet@wanadoo.fr>
[...]
But do you think member-function ptr fits in this context? e.g.
has_call<void(X::*)(), void()>::type // mpl::true_
I don't think this fill you initial can_be_called. Do you?
Actually I'm not sure if it's feasible to support member-function ptr at all, what do others think?
Member function/data pointers can't be used with the usual function-call syntax, so I wouldn't think they would satisfy this trait. [...] - Jeff
participants (6)
-
Eric Niebler
-
Jeffrey Lee Hellrung, Jr.
-
Mathias Gaunard
-
Matt Calabrese
-
TONGARI
-
Vicente J. Botet Escriba