X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fstrings%2Flexicalcast.cpp;h=2b84d9bbbcdaa4e93af36d15d6bb5063807f7ef6;hp=782f4a8537adb05583c6e45e68c6b80620439142;hb=b116e161e377da0e4e52f07745ecb2d22f962ae9;hpb=c7afef88380ebebc8c2b04e48664d73281ec8848 diff --git a/source/strings/lexicalcast.cpp b/source/strings/lexicalcast.cpp index 782f4a8..2b84d9b 100644 --- a/source/strings/lexicalcast.cpp +++ b/source/strings/lexicalcast.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "format.h" #include "lexicalcast.h" @@ -9,26 +10,8 @@ namespace { using namespace Msp; -template -struct IsSigned -{ enum { result = !(static_cast(-1)>0) }; }; - -templatesizeof(unsigned long))> -struct Temporary -{ typedef unsigned long Type; }; - -template -struct Temporary -{ -#ifdef WIN32 - typedef __int64 Type; -#else - typedef unsigned long long Type; -#endif -}; - /* Helper to avoid warnings about an unsigned type never being < 0 */ -template::result> +template::value> struct IsNegative { static bool eval(T v) { return v<0; } }; @@ -36,9 +19,17 @@ template struct IsNegative { static bool eval(T) { return false; } }; +template::value> +struct Negate +{ static T eval(T v) { return -v; } }; + +template +struct Negate +{ static T eval(T v) { return (~v)+1; } }; + /* Helper to avoid errors about ambiguous function calls since there are no overloads of abs for unsigned types */ -template::result> +template::value> struct Absolute { static T eval(T v) { return v<0 ? -v : v; } }; @@ -72,7 +63,7 @@ char *int_to_str(T v, const Fmt &f, char *end) const char *digits = (f.get_uppercase() ? udigits : ldigits); if(v) { - typename Temporary::Type w = Absolute::eval(v); + typename std::make_unsigned::type w = Absolute::eval(v); while(w) { *--ptr = digits[w%base]; @@ -121,18 +112,18 @@ string int_to_str(T v, const Fmt &f) } template -T str_to_int(const std::string &s, const Fmt &f) +T str_to_int(const string &s, const Fmt &f) { if(s.empty()) throw lexical_error("conversion of '' to integer"); - std::string::const_iterator i = s.begin(); + auto i = s.begin(); // See if the input starts with a sign bool neg = false; if(*i=='-') { - if(!IsSigned::result) + if(is_unsigned::value) throw lexical_error(format("conversion of '%s' to unsigned integer", s)); neg = true; ++i; @@ -187,7 +178,7 @@ T str_to_int(const std::string &s, const Fmt &f) } if(neg) - result = -result; + result = Negate::eval(result); return result; } @@ -250,7 +241,7 @@ string flt_to_str(T v, const Fmt &f) if(w>=10) { long double div = 1; - while(div*10(digits)); - if(w>10) + if(w>=10) { // Rounding bumped us to the next exponent, deal with it w /= 10; @@ -311,13 +304,19 @@ string flt_to_str(T v, const Fmt &f) } if(!showexp) { - ++digits; - ++point; + if(mode==Fmt::FIXED) + ++digits; + if(leading_zeroes) + --leading_zeroes; + else + ++point; } else ++exp; } + digits += leading_zeroes; + // Create a buffer and start from the end unsigned size = max(f.get_width(), digits+8); char *buf = new char[size]; @@ -339,14 +338,17 @@ string flt_to_str(T v, const Fmt &f) { if(i==point) *mptr++ = '.'; - if(showexp || static_cast(i)>=-exp) + if(!leading_zeroes) { int digit = static_cast(w); *mptr++ = '0'+digit; w = (w-digit)*10; } else + { *mptr++ = '0'; + --leading_zeroes; + } } if(f.get_showpoint()) @@ -391,7 +393,7 @@ T str_to_flt(const string &s, const Fmt &) if(s.empty()) throw lexical_error("conversion of '' to floating-point"); - std::string::const_iterator i = s.begin(); + auto i = s.begin(); // See if the input starts with a sign bool neg = false; @@ -473,6 +475,7 @@ namespace Msp { void LexicalConverter::result(const string &s) { + filled = true; if(s.size()(p), c.get_fmt())); } +{ c.result(int_to_str(reinterpret_cast(p), c.get_fmt())); } /*** operator>> ***/ @@ -558,7 +568,7 @@ void operator>>(const LexicalConverter &c, char &v) v = str_to_int(c.get(), c.get_fmt()); else { - const std::string &s = c.get(); + const string &s = c.get(); if(s.empty()) throw lexical_error("conversion of '' to character"); if(s.size()>1)