Jonathan Wakely wrote:
>
> It looks to me as though mysqld will always use '.' as the radix
> character.
Okay, good to know.
But does this not call into question the whole premise behind this
thread, which is that MySQL++ isn't handling floating-point conversion
correctly? With this patch, aren't we more or less right back to where
we were, functionally speaking?
> The attached patch to test/string.cpp will reproduce the error.
You might take a look at my new test/string.cpp. It goes to rather
greater lengths than yours to check things. It all passes, so it is
ipso facto correct. >:)
> The second patch for mystring.h demonstrates one way to fix it using a
> stringstream and a std::locale.
Works for me. Applied.
It made my brain explode, but after gathering the pieces back up and
reassembling it, I found I liked it better than the old macro/template
hybrid stuff.
> (I'm pretty sure) preserves all the side-effects of the
> strtol/strtoul conversions, such as allowing "42" to convert to
> char(42) or "257" to silently overflow a char (both of which the
> stream would handle differently by default.)
Thank you for preserving the current behavior; I like it. I guess we
could throw BadConversion when exceeding the range of a type, but it
goes against all expectation.
> If the template partial specialisations are too fancy then conv(Type)
> could just be overloaded for each builtin type, forwarding to
> do_conv<something> like this:
>
> signed char conv(signed char) const
> { return do_conv<long>("signed char"); }
>
> float conv(float) const
> { return do_conv<double>("float"); }
>
> That would get rid of the conv_promotion and proxy templates
> completely and would also allow better names that typeid() provides on
> some compilers.
Eh...half a dozen of one, six of the other. The downside of this way is
the redundancy of reinventing the typeid().name() wheel.
> btw, I noticed that with and without this patch you can convert
> "1.23.00" to (double)1.23 without error. I'm not sure if that's a bug
> or a feature :-)
Bug, squished.
> you could easily add a String::checked_conv() member function,
> which would pass the unpromoted type directly to do_conv and have the
> stringstream do range checking. No changes would be needed to do_conv
> to make that work. It would be considerably harder to add a
> checked_conv() using the C strtoX functions :-)
Although I hate the idea of doing overflow detection all the time, it's
fine with me to have a checked build option.
I've added it to the Wishlist.
> the stream version would reject "1." -> int, which the current
> code accepts. That can be fixed by adding c = '0'; just before the
> while loop, so that "1." is treated the same as "1.0"
Yes, thanks, fixed.