Ticket #7814: lexical_cast.hpp.patch

File lexical_cast.hpp.patch, 5.0 KB (added by Antony Polukhin, 10 years ago)

More generic patch

  • lexical_cast.hpp

     
    767767
    768768    namespace detail // lcast_to_unsigned
    769769    {
    770 #if (defined _MSC_VER)
    771 # pragma warning( push )
    772 // C4146: unary minus operator applied to unsigned type, result still unsigned
    773 # pragma warning( disable : 4146 )
    774 #elif defined( __BORLANDC__ )
    775 # pragma option push -w-8041
    776 #endif
    777770        template<class T>
    778771        inline
    779772        BOOST_DEDUCED_TYPENAME make_unsigned<T>::type lcast_to_unsigned(T value) BOOST_NOEXCEPT
    780773        {
    781             typedef BOOST_DEDUCED_TYPENAME make_unsigned<T>::type result_type;
    782             const result_type uvalue = static_cast<result_type>(value);
    783             return value < 0 ? -uvalue : uvalue;
     774            typedef BOOST_DEDUCED_TYPENAME boost::make_unsigned<T>::type result_type;
     775            return static_cast<result_type>(
     776                value < 0 ? 0u - static_cast<result_type>(value) : value
     777            );
    784778        }
    785 #if (defined _MSC_VER)
    786 # pragma warning( pop )
    787 #elif defined( __BORLANDC__ )
    788 # pragma option pop
    789 #endif
    790779    }
    791780
    792781    namespace detail // lcast_put_unsigned
     
    18251814                }
    18261815
    18271816                bool const succeed = lcast_ret_unsigned<Traits>(output, start, finish);
    1828 #if (defined _MSC_VER)
    1829 # pragma warning( push )
    1830 // C4146: unary minus operator applied to unsigned type, result still unsigned
    1831 # pragma warning( disable : 4146 )
    1832 #elif defined( __BORLANDC__ )
    1833 # pragma option push -w-8041
    1834 #endif
    1835                 if (has_minus) output = static_cast<Type>(-output);
    1836 #if (defined _MSC_VER)
    1837 # pragma warning( pop )
    1838 #elif defined( __BORLANDC__ )
    1839 # pragma option pop
    1840 #endif
     1817
     1818                if (has_minus) {
     1819                    output = static_cast<Type>(0u - output);
     1820                }
     1821
    18411822                return succeed;
    18421823            }
    18431824
     
    18631844
    18641845                bool succeed = lcast_ret_unsigned<Traits>(out_tmp, start, finish);
    18651846                if (has_minus) {
    1866 #if (defined _MSC_VER)
    1867 # pragma warning( push )
    1868 // C4146: unary minus operator applied to unsigned type, result still unsigned
    1869 # pragma warning( disable : 4146 )
    1870 #elif defined( __BORLANDC__ )
    1871 # pragma option push -w-8041
    1872 #endif
    1873                     utype const comp_val = static_cast<utype>(-(std::numeric_limits<Type>::min)());
     1847                    utype const comp_val = (static_cast<utype>(1) << std::numeric_limits<Type>::digits);
    18741848                    succeed = succeed && out_tmp<=comp_val;
    1875                     output = -out_tmp;
    1876 #if (defined _MSC_VER)
    1877 # pragma warning( pop )
    1878 #elif defined( __BORLANDC__ )
    1879 # pragma option pop
    1880 #endif
     1849                    output = static_cast<Type>(0u - out_tmp);
    18811850                } else {
    18821851                    utype const comp_val = static_cast<utype>((std::numeric_limits<Type>::max)());
    18831852                    succeed = succeed && out_tmp<=comp_val;
     
    22952264
    22962265         static source_type nearbyint ( argument_type s )
    22972266         {
    2298             const source_type orig_div_round = s / Rounder::nearbyint(s);
    2299             const source_type eps = std::numeric_limits<source_type>::epsilon();
     2267            const source_type near_int = Rounder::nearbyint(s);
     2268            if (near_int) {
     2269                const source_type orig_div_round = s / near_int;
     2270                const source_type eps = std::numeric_limits<source_type>::epsilon();
    23002271
    2301             if ((orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > eps)
    2302                 BOOST_LCAST_THROW_BAD_CAST(Source, Target);
     2272                if ((orig_div_round > 1 ? orig_div_round - 1 : 1 - orig_div_round) > eps)
     2273                    BOOST_LCAST_THROW_BAD_CAST(Source, Target);
     2274            }
    23032275
    23042276            return s ;
    23052277         }
     
    23372309        {
    23382310            static inline Target lexical_cast_impl(const Source &arg)
    23392311            {
     2312                typedef BOOST_DEDUCED_TYPENAME boost::mpl::eval_if_c<
     2313                        boost::is_float<Source>::value,
     2314                        boost::mpl::identity<Source>,
     2315                        boost::make_unsigned<Source>
     2316                >::type usource_t;
     2317
    23402318                typedef boost::numeric::converter<
    23412319                        Target,
    2342                         Source,
    2343                         boost::numeric::conversion_traits<Target,Source>,
    2344                         nothrow_overflow_handler<Source, Target>,
    2345                         detect_precision_loss<Source, Target>
     2320                        usource_t,
     2321                        boost::numeric::conversion_traits<Target,usource_t>,
     2322                        nothrow_overflow_handler<usource_t, Target>,
     2323                        detect_precision_loss<usource_t, Target>
    23462324                > converter_t;
    23472325
    23482326                return (
    2349                     arg < 0 ? -converter_t::convert(-arg) : converter_t::convert(arg)
     2327                    arg < 0 ? 0u - converter_t::convert(0u - arg) : converter_t::convert(arg)
    23502328                );
    23512329            }
    23522330        };