"Problems when Scanner::value_t is int" revisited

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

"Problems when Scanner::value_t is int" revisited

Jason Kankiewicz
This is in reference to Jordan DeLong's original message in this forum
"Problems when Scanner::value_t is int (possible bug)" dated 6/26/2005
5:14 PM (http://sourceforge.net/mailarchive/message.php?msg_id=12176737) .
In that thread, Jordan DeLong offered a patch file for Boost 1.32's
"spirit/core/primitives/impl/primitives.ipp" which Joel de Guzman
promised to apply to the release subsequent to Boost 1.33.

Well, being that the problem persists in the RC_1_33_0 branch and there
is a planned release of Boost 1.33.1, might not now be the time to do so?

To make everyone's life easier, I've attached a patch file of my own
which blends Jordan DeLong's original with the changes between versions
1.32 and RC_1_33_0 of "spirit/core/primitives/impl/primitives.ipp". My
patched code now compiles both under win32 VC++ 7.1 and darwin GCC 3.3.

Thank you.

Index: primitives/impl/primitives.ipp
===================================================================
--- primitives/impl/primitives.ipp (revision 2447)
+++ primitives/impl/primitives.ipp (working copy)
@@ -10,6 +10,10 @@
 #if !defined(BOOST_SPIRIT_PRIMITIVES_IPP)
 #define BOOST_SPIRIT_PRIMITIVES_IPP
 
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/is_same.hpp>
+
 // This should eventually go to a config file.
 #if defined(__GNUC__) && (__GNUC__ < 3) && !defined(_STLPORT_VERSION)
 #  ifndef BOOST_SPIRIT_NO_CHAR_TRAITS
@@ -150,19 +154,48 @@
 #  endif
 #endif // BOOST_SPIRIT_NO_CHAR_TRAITS
 
+        // Metafunction returning whether we should use char_traits<>
+        // to do convertions for a particular type.
+        template <typename T>
+        struct use_char_traits :
+            boost::mpl::or_<
+                boost::is_same<T, char>,
+                boost::is_same<T, wchar_t>
+            >
+        {};
+
         template <typename CharT>
-        inline typename
-        BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE::char_traits<CharT>::int_type
+        inline
+        typename boost::disable_if<use_char_traits<CharT>, CharT>::type
         to_int_type(CharT c)
         {
+            return c;
+        }
+
+        template <typename CharT>
+        inline
+        typename boost::disable_if<use_char_traits<CharT>, CharT>::type
+        to_char_type(CharT c)
+        {
+            return c;
+        }
+
+        template <typename CharT>
+        inline
+        typename boost::enable_if <
+                                    use_char_traits<CharT>
+                                  , typename BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE::char_traits<CharT>::int_type
+                                  >::type
+        to_int_type(CharT c)
+        {
             return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
                 ::char_traits<CharT>::to_int_type(c);
         }
-    
+
         template <typename CharT>
-        inline CharT
-        to_char_type(typename
-            BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE::char_traits<CharT>::int_type c)
+        inline
+        typename boost::enable_if<use_char_traits<CharT>, CharT>::type
+        to_char_type(CharT c)
         {
             return BOOST_SPIRIT_CHAR_TRAITS_NAMESPACE
                 ::char_traits<CharT>::to_char_type(c);
@@ -174,105 +207,120 @@
         //
         ///////////////////////////////////////////////////////////////////////
 
+        template <typename CharT>
         inline bool
-        isalnum_(char c)
+        isalnum_(CharT c)
         {
             using namespace std;
             return isalnum(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        isalpha_(char c)
+        isalpha_(CharT c)
         {
             using namespace std;
             return isalpha(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        iscntrl_(char c)
+        iscntrl_(CharT c)
         {
             using namespace std;
             return iscntrl(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        isdigit_(char c)
+        isdigit_(CharT c)
         {
             using namespace std;
             return isdigit(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        isgraph_(char c)
+        isgraph_(CharT c)
         {
             using namespace std;
             return isgraph(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        islower_(char c)
+        islower_(CharT c)
         {
             using namespace std;
             return islower(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        isprint_(char c)
+        isprint_(CharT c)
         {
             using namespace std;
             return isprint(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        ispunct_(char c)
+        ispunct_(CharT c)
         {
             using namespace std;
             return ispunct(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        isspace_(char c)
+        isspace_(CharT c)
         {
             using namespace std;
             return isspace(to_int_type(c)) ? true : false;
         }
     
+        template <typename CharT>
         inline bool
-        isupper_(char c)
+        isupper_(CharT c)
         {
             using namespace std;
             return isupper(to_int_type(c)) ? true : false;  
         }
     
+        template <typename CharT>
         inline bool
-        isxdigit_(char c)
+        isxdigit_(CharT c)
         {
             using namespace std;
             return isxdigit(to_int_type(c)) ? true : false;  
         }
     
+        template <typename CharT>
         inline bool
-        isblank_(char c)
+        isblank_(CharT c)
         {
             return (c == ' ' || c == '\t');
         }
-        
-        inline char
-        tolower_(char c)
+
+        template <typename CharT>
+        inline CharT
+        tolower_(CharT c)
         {
             using namespace std;
-            return to_char_type<char>(tolower(to_int_type(c)));
+            return to_char_type<CharT>(tolower(to_int_type(c)));
         }
-    
-        inline char
-        toupper_(char c)
+
+        template <typename CharT>
+        inline CharT
+        toupper_(CharT c)
         {
             using namespace std;
-            return to_char_type<char>(toupper(to_int_type(c)));
+            return to_char_type<CharT>(toupper(to_int_type(c)));
         }
 
 #if !defined(BOOST_NO_CWCTYPE)
 
+        template<>
         inline bool
         isalnum_(wchar_t c)
         {
@@ -280,6 +328,7 @@
             return iswalnum(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isalpha_(wchar_t c)
         {
@@ -287,6 +336,7 @@
             return iswalpha(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         iscntrl_(wchar_t c)
         {
@@ -294,6 +344,7 @@
             return iswcntrl(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isdigit_(wchar_t c)
         {
@@ -301,6 +352,7 @@
             return iswdigit(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isgraph_(wchar_t c)
         {
@@ -308,6 +360,7 @@
             return iswgraph(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         islower_(wchar_t c)
         {
@@ -315,6 +368,7 @@
             return iswlower(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isprint_(wchar_t c)
         {
@@ -322,6 +376,7 @@
             return iswprint(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         ispunct_(wchar_t c)
         {
@@ -329,6 +384,7 @@
             return iswpunct(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isspace_(wchar_t c)
         {
@@ -336,6 +392,7 @@
             return iswspace(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isupper_(wchar_t c)
         {
@@ -343,6 +400,7 @@
             return iswupper(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isxdigit_(wchar_t c)
         {
@@ -350,12 +408,14 @@
             return iswxdigit(to_int_type(c)) ? true : false;  
         }
     
+        template<>
         inline bool
         isblank_(wchar_t c)
         {
             return (c == L' ' || c == L'\t');
         }
     
+        template<>
         inline wchar_t
         tolower_(wchar_t c)
         {
@@ -363,6 +423,7 @@
             return to_char_type<wchar_t>(towlower(to_int_type(c)));
         }
     
+        template<>
         inline wchar_t
         toupper_(wchar_t c)
         {