Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:34

0001 /*=============================================================================
0002     Copyright (c) 2001-2014 Joel de Guzman
0003     Copyright (c) 2001-2011 Hartmut Kaiser
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #if !defined(BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM)
0009 #define BOOST_SPIRIT_X3_CAST_CHAR_NOVEMBER_10_2006_0907AM
0010 
0011 #include <boost/type_traits/is_signed.hpp>
0012 #include <boost/type_traits/make_unsigned.hpp>
0013 #include <boost/type_traits/make_signed.hpp>
0014 
0015 namespace boost { namespace spirit { namespace x3 { namespace detail
0016 {
0017     // Here's the thing... typical encodings (except ASCII) deal with unsigned
0018     // integers > 127 (ASCII uses only 127). Yet, most char and wchar_t are signed.
0019     // Thus, a char with value > 127 is negative (e.g. char 233 is -23). When you
0020     // cast this to an unsigned int with 32 bits, you get 4294967273!
0021     //
0022     // The trick is to cast to an unsigned version of the source char first
0023     // before casting to the target. {P.S. Don't worry about the code, the
0024     // optimizer will optimize the if-else branches}
0025 
0026     template <typename TargetChar, typename SourceChar>
0027     TargetChar cast_char(SourceChar ch)
0028     {
0029 #if defined(_MSC_VER)
0030 # pragma warning(push)
0031 # pragma warning(disable: 4127) // conditional expression is constant
0032 #endif
0033         if (is_signed<TargetChar>::value != is_signed<SourceChar>::value)
0034         {
0035             if (is_signed<SourceChar>::value)
0036             {
0037                  // source is signed, target is unsigned
0038                 typedef typename make_unsigned<SourceChar>::type USourceChar;
0039                 return TargetChar(USourceChar(ch));
0040             }
0041             else
0042             {
0043                  // source is unsigned, target is signed
0044                 typedef typename make_signed<SourceChar>::type SSourceChar;
0045                 return TargetChar(SSourceChar(ch));
0046             }
0047         }
0048         else
0049         {
0050             // source and target has same signedness
0051             return TargetChar(ch); // just cast
0052         }
0053 #if defined(_MSC_VER)
0054 # pragma warning(pop)
0055 #endif
0056     }
0057 }}}}
0058 
0059 #endif
0060 
0061