Re: [Boost-bugs] [Boost C++ Libraries] #9441: SolarisStudio support

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #9441: SolarisStudio support
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-11-29 11:19:45


#9441: SolarisStudio support
-------------------------------+----------------------
  Reporter: lukester_null@… | Owner: eldiener
      Type: Patches | Status: new
 Milestone: To Be Determined | Component: tti
   Version: Boost 1.55.0 | Severity: Problem
Resolution: | Keywords:
-------------------------------+----------------------

Comment (by lukester_null@…):

 OK so I had a play around with has_template_xxx with the Sun compiler.

 BOOST_TTI_HAS_TEMPLATE(InnerTemplate, (1,(typename)))

 Generates:

 {{{
 template < typename BOOST_TTI_DETAIL_TP_T, typename
 BOOST_TTI_DETAIL_TP_FALLBACK_ = Boost::mpl::bool_< false > >
 class has_template_InnerTemplate_detail
 {
         template< typename U >
         struct has_template_InnerTemplate_detail_introspect
         {
                 template < template < typename > class
 BOOST_TTI_DETAIL_TM_V >
                 struct has_template_InnerTemplate_detail_substitute0
                 {
                 };

                 template< typename V > static Boost::mpl::aux::no_tag
                 has_template_InnerTemplate_detail_test(...);

                 template< typename V > static Boost::mpl::aux::yes_tag
                 has_template_InnerTemplate_detail_test(
 Boost::mpl::aux::type_wrapper< V > const volatile* ,
 has_template_InnerTemplate_detail_substitute0 < V::template InnerTemplate
> * = 0 );

                 static const bool value =
 sizeof(has_template_InnerTemplate_detail_test< U >(0)) ==
 sizeof(Boost::mpl::aux::yes_tag);

                 typedef Boost::mpl::bool_< value > type;
         };

 public:
         static const bool value =
 has_template_InnerTemplate_detail_introspect< BOOST_TTI_DETAIL_TP_T
>::value;

         typedef typename has_template_InnerTemplate_detail_introspect <
 BOOST_TTI_DETAIL_TP_T >::type type;
 };

 template<class BOOST_TTI_DETAIL_TP_T>
 struct has_template_InnerTemplate :
 has_template_InnerTemplate_detail<BOOST_TTI_DETAIL_TP_T>
 {
 };
 }}}

 Two tweaks make this work:

 * Using a nested type typedef within the substitute class (and appropriate
 change for the "yes" test function). Not unreasonable for any compiler I'd
 have thought.
 * In the "yes" test function, using "U template::<template name>" rather
 than "V template::<template name>". This is obviously horribly broken on a
 non-broken compiler but seems to do the trick here...

 Something like:

 {{{
 template < typename BOOST_TTI_DETAIL_TP_T, typename
 BOOST_TTI_DETAIL_TP_FALLBACK_ = Boost::mpl::bool_< false > >
 class has_template_InnerTemplate_detail
 {
         template< typename U >
         struct has_template_InnerTemplate_detail_introspect
         {
                 template < template < typename > class
 BOOST_TTI_DETAIL_TM_V >
                 struct has_template_InnerTemplate_detail_substitute0
                 {
                         typedef void type;
                 };

                 template< typename V > static Boost::mpl::aux::no_tag
                 has_template_InnerTemplate_detail_test(...);

                 template< typename V > static Boost::mpl::aux::yes_tag
                 has_template_InnerTemplate_detail_test(
 Boost::mpl::aux::type_wrapper< V > const volatile* , typename
 has_template_InnerTemplate_detail_substitute0 < U::template InnerTemplate
>::type* = 0 );

                 static const bool value =
 sizeof(has_template_InnerTemplate_detail_test< U >(0)) ==
 sizeof(Boost::mpl::aux::yes_tag);

                 typedef Boost::mpl::bool_< value > type;
         };

 public:
         static const bool value =
 has_template_InnerTemplate_detail_introspect< BOOST_TTI_DETAIL_TP_T
>::value;

         typedef typename has_template_InnerTemplate_detail_introspect <
 BOOST_TTI_DETAIL_TP_T >::type type;
 };

 template<class BOOST_TTI_DETAIL_TP_T>
 struct has_template_InnerTemplate :
 has_template_InnerTemplate_detail<BOOST_TTI_DETAIL_TP_T>
 {
 };
 }}}

 I'll attach a patch (dtemplate_params.patch) that applies the above for
 the specific parameters case, since it's pretty easy to localize it to
 just that file (though not necessarily the "right" thing to do). The
 BOOST_PP_NIL case is a bit more of a problem as it's mostly mpl's
 has_xxx.hpp. I'll attach a patch for that also.

 Tests still fail as the BOOST_PP_NIL usage with non-class template
 parameters actually works. I.e.

 {{{
 #include "boost/tti/has_template.hpp"
 #include "boost/static_assert.hpp"

 class Test
 {
 public:
     template<typename T>
     class InnerTTemplate
     {
     };

     template<int C>
     class InnerITemplate
     {
     };
 };

 class Test2
 {
 };

 namespace Nil
 {

 BOOST_TTI_HAS_TEMPLATE(InnerTTemplate, BOOST_PP_NIL)
 BOOST_TTI_HAS_TEMPLATE(InnerITemplate, BOOST_PP_NIL)

 BOOST_STATIC_ASSERT((has_template_InnerTTemplate<Test>::value));
 BOOST_STATIC_ASSERT((has_template_InnerITemplate<Test>::value));

 BOOST_STATIC_ASSERT((!has_template_InnerTTemplate<Test2>::value));
 BOOST_STATIC_ASSERT((!has_template_InnerITemplate<Test2>::value));

 }

 namespace Spec
 {

 BOOST_TTI_HAS_TEMPLATE(InnerTTemplate, (1,(typename)))
 BOOST_TTI_HAS_TEMPLATE(InnerITemplate, (1,(int)))

 BOOST_STATIC_ASSERT((has_template_InnerTTemplate<Test>::value));
 BOOST_STATIC_ASSERT((has_template_InnerITemplate<Test>::value));

 BOOST_STATIC_ASSERT((!has_template_InnerTTemplate<Test2>::value));
 BOOST_STATIC_ASSERT((!has_template_InnerITemplate<Test2>::value));

 }

 int main()
 {
     return 0;
 }
 }}}

 builds.

 Anyway, I hope this is of some use, though it seems more of an mpl ticket
 at this point...

 Regards

 Luke Elliott.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/9441#comment:1>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:14 UTC