Boost logo

Boost :

Subject: Re: [boost] [Review] TTI
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2011-07-28 17:57:20


On Thu, Jul 28, 2011 at 2:49 PM, John Bytheway <jbytheway+boost_at_[hidden]>wrote:

> On 28/07/11 19:07, Jeffrey Lee Hellrung, Jr. wrote:
> <snip>
> >> Maybe a generic method for any number of types would be possible through
> >> using Boost function types.
> >
> > The way to go, I think, is BOOST_PP_ITERATE (since you have to construct
> the
> > actual call expression declval<T>().xxx(declval<T0>(), declval<T1>(),
> ...,
> > declval<T[N-1]>()))...which implies that you'll have to have a
> >
> > #define BOOST_TTI_PARAM_1 foo
> > #define BOOST_TTI_PARAM_2 bar
> > #include BOOST_TTI_HAS_MEMBER_FUNCTION_THINGY()
> >
> > interface rather than a metafunction-generating macro interface. I guess
> > you can use BOOST_PP_REPEAT but it could make the implementation unwieldy
> > and make it potentially very difficult to track down usage errors :/
> > Variadic templates *might* work here, but I'm really not sure.
>
> Yes, variadic templates make it easy; e.g. this alteration to the end of
> your code works for me with clang++:
>
> template< class T, class Result, class... Args >
> struct has_mem_fn_helper< T, Result ( Args... ) >
> {
> static const bool value =
> (sizeof( is_dummy_result_t(
> declval< derived_t<T>>().xxx(declval<Args>()...)) ) ==
> sizeof( no_type ))
> && (sizeof( is_convertible< Result >::apply(
> declval< derived_t<T>>().xxx(declval<Args>()...)) ) ==
> sizeof( yes_type ));
> typedef has_mem_fn_helper type;
> };
>

> struct X
> { };
>
> struct Y
> { int xxx(int); };
>
> struct Z
> { int xxx(int, int); };
>
> int main(int /*argc*/, char* /*argv*/[])
> {
> BOOST_STATIC_ASSERT(!(has_mem_fn< X >::value));
> BOOST_STATIC_ASSERT( (has_mem_fn< Y >::value));
> BOOST_STATIC_ASSERT( (has_mem_fn< Y, int ( int ) >::value));
> BOOST_STATIC_ASSERT( (has_mem_fn< Y, long ( short ) >::value));
> BOOST_STATIC_ASSERT(!(has_mem_fn< Y, int ( void* ) >::value));
> BOOST_STATIC_ASSERT(!(has_mem_fn< Y, void* ( int ) >::value));
> BOOST_STATIC_ASSERT(!(has_mem_fn< Z, int ( int ) >::value));
> BOOST_STATIC_ASSERT(!(has_mem_fn< Z, int ( void* ) >::value));
> BOOST_STATIC_ASSERT( (has_mem_fn< Z, int ( int, long ) >::value));
> BOOST_STATIC_ASSERT(!(has_mem_fn< Z, int ( void*, int ) >::value));
> return 0;
> }
>

Awesome! Unfortunately, not supported in Visual Studio yet :(

- Jeff


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