Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-07-02 02:08:26


Joel de Guzman wrote:
> Stefan Seefeld wrote:
>> Michael Marcin wrote:
>>> If I include <boost/fusion/support/tag_of.hpp> my compiler (derived from
>>> Metrowerks 9.4) gives me several errors claiming illegal partial
>>> specializations.
>>>
>>> It looks like it's partially specializing forward declarations of the tag_of
>>> structure. I don't know if that's allowed (from the error I assume probably
>>> not) but it certainly seems to be pointless to me. Are these perhaps
>>> supposed to be more than declarations?
>> What's the point, if you (partially) specialize it anyway ?
>>
>> FWIW, I have seen similar errors with IBM's XLC++ and am pretty sure that
>> at least in that particular case it was a compiler bug.
>
> Yes, it's most probably a compiler bug. I've seen this before.
> patch welcome ;-). I do not have CW now.

The attached patch should fix this problem. It uses an MPL assert in the
primary template to catch potential ODR violations, rather than forward
declared partial specializations.

HTH,

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

Index: tag_of.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/fusion/support/tag_of.hpp,v
retrieving revision 1.7
diff -b -d -u -r1.7 tag_of.hpp
--- tag_of.hpp 22 Mar 2007 19:21:29 -0000 1.7
+++ tag_of.hpp 2 Jul 2007 06:05:29 -0000
@@ -13,6 +13,7 @@
 #include <boost/mpl/has_xxx.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/mpl/identity.hpp>
+#include <boost/mpl/assert.hpp>
 #include <boost/mpl/bool.hpp>
 #include <boost/mpl/if.hpp>
 #include <utility>
@@ -45,6 +46,39 @@
     namespace detail
     {
         BOOST_MPL_HAS_XXX_TRAIT_DEF(fusion_tag)
+
+ template<typename Sequence>
+ struct is_specialized
+ : mpl::false_
+ {};
+
+ template <
+ class T0, class T1, class T2, class T3, class T4,
+ class T5, class T6, class T7, class T8, class T9
+ >
+ struct is_specialized<tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
+ : mpl::true_
+ {};
+
+ template <class Head, class Tail>
+ struct is_specialized<tuples::cons<Head, Tail> >
+ : mpl::true_
+ {};
+
+ template <>
+ struct is_specialized<tuples::null_type>
+ : mpl::true_
+ {};
+
+ template <typename T, std::size_t N>
+ struct is_specialized<boost::array<T, N> >
+ : mpl::true_
+ {};
+
+ template<typename T1, typename T2>
+ struct is_specialized<std::pair<T1, T2> >
+ : mpl::true_
+ {};
     }
 
     namespace traits
@@ -54,31 +88,15 @@
           : mpl::if_< detail::is_mpl_sequence<Sequence>,
               mpl::identity<mpl_sequence_tag>,
               mpl::identity<non_fusion_tag> >::type
- { };
+ {
+ BOOST_MPL_ASSERT_NOT((detail::is_specialized<Sequence>));
+ };
 
         template <typename Sequence>
         struct tag_of<Sequence, typename boost::enable_if<detail::has_fusion_tag<Sequence> >::type>
         {
             typedef typename Sequence::fusion_tag type;
         };
-
- template <
- class T0, class T1, class T2, class T3, class T4,
- class T5, class T6, class T7, class T8, class T9
- >
- struct tag_of<tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >;
-
- template <class Head, class Tail>
- struct tag_of<tuples::cons<Head, Tail> >;
-
- template <>
- struct tag_of<tuples::null_type>;
-
- template <typename T, std::size_t N>
- struct tag_of<boost::array<T, N> >;
-
- template<typename T1, typename T2>
- struct tag_of<std::pair<T1, T2> >;
     }
 
     namespace detail


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