Boost logo

Boost :

Subject: Re: [boost] [Review] Type Traits Introspection library by Edward Diener starts tomorrow Friday 1
From: Edward Diener (eldiener_at_[hidden])
Date: 2011-07-04 11:47:21


On 7/4/2011 7:07 AM, John Maddock wrote:
>> For Intel 11.1 or 12.0 can you tell me if the MPL tests pass,
>> particularly just the test of has_xxx.cpp ? If that fails for MPL it
>> fully explains why my tests for Intel are failing ( I am just reusing
>> BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF internally ) and a workaround
>> would need to be found in MPL.
>
> Ah: there are failures for mpl with Intel as well - results attached.

Thanks !

If you can, is it possible to get the preprocessor output decently
formatted for Intel Linux 12.0 when it expands the macro
BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF on line 20 of
boost/libs/mpl/test/has_xxx.cpp ? There is no rush and if you find it is
too much work, I will understand.

The issue is that BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF is quite
complicated, has workarounds for various scenarios mainly involving some
releases of VC++, and it appears that Intel 11.1 and Intel 12.0 also
can't handle the normal macro generated metafunction properly. David
Abrahams and Alex Gurtovoy may have done the initial work on this macro
for MPL, but it seems as if Daniel Walker also did improvements. I am
using this macro in TTI and also developed another macro based on it for
finding an exact match for a nested template ( the MPL implementations
looks for a match with every macro parameter being a typename/class up
to 5 ) . So to get Intel 11.1 and 12.0 to work, both
BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF and my own macro needs to find a
workaround, but once BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF has an Intel
workaround doing my own will be relatively easy.

Of course the failure is with the Intel compiler in this case but I need
to find out exactly how it is expanding the macro just in case its
preprocessor is in error somehow. I have expanded the macro using Wave,
and I am pretty sure that is what the Intel output is also, but I would
like to check if possible.

The Wave output is:

template<typename T,typename fallback_ = boost::mpl::bool_< false > >
class has_xxx_template
   {
   template< typename U >
   struct has_xxx_template_introspect
     {
     template<template< typename V0 > class V>
     struct has_xxx_template_substitute0 {};
     template<template< typename V0 , typename V1 > class V >
     struct has_xxx_template_substitute1 {};
     template<template< typename V0 , typename V1 , typename V2 > class V >
     struct has_xxx_template_substitute2 {};
     template<template< typename V0 , typename V1 , typename V2 ,
typename V3 > class V >
     struct has_xxx_template_substitute3 {};
     template<template< typename V0 , typename V1 , typename V2 ,
typename V3 , typename V4 > class V >
     struct has_xxx_template_substitute4 {};

     template< typename V > static boost::mpl::aux::no_tag
has_xxx_template_test(...);
     template< typename V > static boost::mpl::aux::yes_tag
has_xxx_template_test
       (
       boost::mpl::aux::type_wrapper< V > const volatile*,
       has_xxx_template_substitute0 <V::template xxx>* = 0
       );
     template< typename V > static boost::mpl::aux::yes_tag
has_xxx_template_test
       (
       boost::mpl::aux::type_wrapper< V > const volatile*,
       has_xxx_template_substitute1 <V::template xxx>* = 0
       );
     template< typename V > static boost::mpl::aux::yes_tag
has_xxx_template_test
       (
       boost::mpl::aux::type_wrapper< V > const volatile*,
       has_xxx_template_substitute2 <V::template xxx>* = 0
       );
     template< typename V > static boost::mpl::aux::yes_tag
has_xxx_template_test
       (
       boost::mpl::aux::type_wrapper< V > const volatile*,
       has_xxx_template_substitute3 <V::template xxx>* = 0
       );
     template< typename V > static boost::mpl::aux::yes_tag
has_xxx_template_test
       (
       boost::mpl::aux::type_wrapper< V > const volatile*,
       has_xxx_template_substitute4 <V::template xxx>* = 0
       );

     static const bool value =
       sizeof(has_xxx_template_test< U >(0)) ==
sizeof(boost::mpl::aux::yes_tag);
     typedef boost::mpl::bool_< value > type;
     };

   public:
     static const bool value = has_xxx_template_introspect< T >::value;
     typedef typename has_xxx_template_introspect<T>::type type;
   };

The error meesage from the Intel compiler is:

has_xxx.cpp(20): error: more than one instance of overloaded function
"has_xxx_template<T,
fallback_>::has_xxx_template_introspect<U>::has_xxx_template_test [with
T=a5, fallback_=boost::mpl::bool_<false>, U=a5]" matches the argument list:
             function template "boost::mpl::aux::yes_tag
has_xxx_template<T,
fallback_>::has_xxx_template_introspect<U>::has_xxx_template_test(const
volatile boost::mpl::aux::type_wrapper<V> *, has_xxx_template<a5,
boost::mpl::bool_<false>>::has_xxx_template_introspect<a5>::has_xxx_template_substitute0<V::xxx>
*) [with T=a5, fallback_=boost::mpl::bool_<false>, U=a5]"
             function template "boost::mpl::aux::yes_tag
has_xxx_template<T,
fallback_>::has_xxx_template_introspect<U>::has_xxx_template_test(const
volatile boost::mpl::aux::type_wrapper<V> *, has_xxx_template<a5,
boost::mpl::bool_<false>>::has_xxx_template_introspect<a5>::has_xxx_template_substitute1<V::xxx>
*) [with T=a5, fallback_=boost::mpl::bool_<false>, U=a5]"
             function template "boost::mpl::aux::yes_tag
has_xxx_template<T,
fallback_>::has_xxx_template_introspect<U>::has_xxx_template_test(const
volatile boost::mpl::aux::type_wrapper<V> *, has_xxx_template<a5,
boost::mpl::bool_<false>>::has_xxx_template_introspect<a5>::has_xxx_template_substitute2<V::xxx>
*) [with T=a5, fallback_=boost::mpl::bool_<false>, U=a5]"
             function template "boost::mpl::aux::yes_tag
has_xxx_template<T,
fallback_>::has_xxx_template_introspect<U>::has_xxx_template_test(const
volatile boost::mpl::aux::type_wrapper<V> *, has_xxx_template<a5,
boost::mpl::bool_<false>>::has_xxx_template_introspect<a5>::has_xxx_template_substitute3<V::xxx>
*) [with T=a5, fallback_=boost::mpl::bool_<false>, U=a5]"
             function template "boost::mpl::aux::yes_tag
has_xxx_template<T,
fallback_>::has_xxx_template_introspect<U>::has_xxx_template_test(const
volatile boost::mpl::aux::type_wrapper<V> *, has_xxx_template<a5,
boost::mpl::bool_<false>>::has_xxx_template_introspect<a5>::has_xxx_template_substitute4<V::xxx>
*) [with T=a5, fallback_=boost::mpl::bool_<false>, U=a5]"
             argument types are: (int)
   BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_xxx_template, xxx, false)
   ^
           detected during:
             instantiation of class "has_xxx_template<T,
fallback_>::has_xxx_template_introspect<U> [with T=a5,
fallback_=boost::mpl::bool_<false>, U=a5]" at line 20
             instantiation of class "has_xxx_template<T, fallback_>
[with T=a5, fallback_=boost::mpl::bool_<false>]" at line 148 of
"../../../boost/mpl/assert.hpp"
             instantiation of class "boost::mpl::assert_arg_pred_not<P>
[with P=has_xxx_template<a5, boost::mpl::bool_<false>>]" at line 82

For Intel, this is really an issue that needs to be addressed in MPL and
then I will attempt to update my own macro for finding an exact match
based on it. It also appears as if Intel needs to fix their compiler for
future releases since the same code is handled by other compilers properly.


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