From: mcostalba on
On 5 Mag, 15:09, "Roman.Perepeli...(a)gmail.com"
<Roman.Perepeli...(a)gmail.com> wrote:
> On 1 May, 21:43, mcostalba <mcosta...(a)gmail.com> wrote:
>
> > I have to detect if a functor type Fun has a given signature Sig, i.e.
> > if Fun::operator() has a signature Sig
>
> Take a look at is_call_possible metafunction, which was discussed
> in this group before
> (http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/
> thread/4f7c7a96f9afbe44/e5fbc9305539f699#e5fbc9305539f699).
> It seems to do what you want.
>

Thanks Roman for your link.

Actually there are some good ideas in that implementation and I will
try to borrow a few of them...

Unfortunatly it does not fit the bill 100%, indeed:

- Implicit argument type conversion should be avoided in my context,
due to some ambiguites that can arise when there is more then one
candidate among the overload set. So signature matching would be ok to
be strict.

- It seems you have to add a specialization for each argument arity,
in my implementation I would try to avoid this. Indeed my proposed
implementation it's already ok at 95%, the only case for which it
fails is detecting pointers to CONST operator() members with a given
signature.



Anyhow, for interested people, many of the ideas, included overloading
comma operator

template <typename type, typename U>
U& operator,(U&, void_exp_result<type>);

to workaround void return types are also exposed in "Detecting the
Arity of Function Objects"

under the link

http://boost-sandbox.sourceforge.net/libs/proto/doc/html/boost_proto/appendices/implementation/function_arity.html

where an equivalent solution is documented by Eric Nibler in his
boost::proto library.

Thanks
Marco

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: mcostalba on
On 6 Mag, 16:21, "Roman.Perepeli...(a)gmail.com"
<Roman.Perepeli...(a)gmail.com> wrote:
>
>
> Alexandre Courpron modified is_call_possible to create
> is_exact_call_possible. You can find implementation here:http://groups.google.co.uk/group/comp.lang.c++.moderated/browse_threa...

I have quickly checked the link and it surely deserves a deeper read
when I found a bit of time.

Anyhow here is my much simpler solution...so simple that is probably
broken in some way, but I cannot find where:

/* Check if a function/functor Fun has a given signature Sig */
template<typename Fun, typename Sig>
struct is_compatible
{
typedef typename boost::remove_pointer<Fun>::type F;

/* Build pointer_to_member types from the given signature */
typedef typename pointer_to_member<is_function<F>::value, F,
Sig>::type ptm;
typedef typename pointer_to_member<is_function<F>::value, F,
Sig>::const_type ptm_const;

/* Check for a function */
template<class U> static
yes_type detect(typename enable_if<is_same<U, Sig> >::type*);

/* Check for a functor, either const and non-const members are
detected */
template<ptm> struct helper;
template<ptm_const> struct helper_const;

template<class U> static
yes_type detect(helper<&U::operator()>*);

template<class U> static
yes_type detect(helper_const<&U::operator()>*);

/* Default */
template<class U> static
no_type detect(...);

static const bool
value = (sizeof(detect<F>(0)) == sizeof(yes_type));
};


Where template pointer_to_member<> is:

/* Convert a signature type Sig to a pointer_to_member type */
template<int is_function, typename T, typename Sig>
struct pointer_to_member;

template<typename T, typename Sig>
struct pointer_to_member<1, T, Sig> // filter out function types
{
typedef int type;
typedef int const_type;
};

template<typename T, typename R>
struct pointer_to_member<0, T, R()>
{
typedef R(T::* type) ();
typedef R(T::* const_type)() const;
};

template<typename T, typename R, typename A0>
struct pointer_to_member<0, T, R(A0)>
{
typedef R(T::* type)(A0);
typedef R(T::* const_type)(A0) const;
};

...... and so on for each argument arity ........


BTW it seems to work.


Thanks
Marco

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: dizzy on
Hi

mcostalba wrote:

<snip>
> template<class U> static
> yes_type detect(helper<&U::operator()>*);
>
> template<class U> static
> yes_type detect(helper_const<&U::operator()>*);

Not sure if the previously discussed solutions does support it but this
version at least seems to me broken in regard to overloaded operator().
Supose you have a static_visitor functor (a functor with many overloaded
operator()(T&) each taking a different T, usually used with a static
visitor aproach). It would be nice if is_compatible<> would determine or
not if there is a suitable overload for the signature you want. The
expression "&U::operator()" would give an amibuity error in case of
overloading (which is usually solved either wraping it with a static_cast
to the exact function type wanted from the overload set or used as
initialization expression for a pointer/reference to function variable). So
a solution might be "helper<static_cast<ptm>(&U::operator())>" and
something similar for the const version.

I'm also a little puzzled that "&U::operator()" does not give compile error
in case of not giving a functor to is_compatible<> because I don't think
SFINAE helps here, you have an invalid "value expression" not an
invalid "type expression", but quite possible I misunderstand this.

--
Dizzy


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]