Fix stack overflow.

This commit is contained in:
Alexander van Gessel 2011-09-03 20:55:52 +01:00
parent 002fead566
commit 17b196cfd0

View file

@ -286,26 +286,8 @@ template <> void si_string_impl_stream_write(std::stringstream &ss, long long in
ss << input;
}
template <typename T>
std::string si_string_impl(T input, bool base2, std::string unit) {
// (input == -input) can happen if we're at the minimum of the native signed integer type, so make sure we don't recurse infinitely
// It will still give bad output, but it won't overflow the stack
if (input < 0 && input != -input)
return unicode_minus + si_string(-input, base2, unit);
return si_string_impl(input, base2, unit);
}
// Specialisation for unsigned as the template causes warnings otherwise
template <> std::string si_string_impl(unsigned input, bool base2, std::string unit) {
return si_string_impl(input, base2, unit);
}
// A second layer of indirection, for the above specialisation
template <typename T>
std::string si_string_impl2(T input, bool base2, std::string unit) {
const int multiplier = base2 ? 1024 : 1000;
// (input == -input) can happen if we're at the minimum of the native signed integer type, so make sure we don't recurse infinitely
// It will still give bad output, but it won't overflow the stack
if (input < 0 && input != -input)
return unicode_minus + si_string(-input, base2, unit);
const T multiplier = base2 ? 1024 : 1000;
typedef boost::array<std::string, 9> strings9;
@ -360,6 +342,21 @@ std::string si_string_impl2(T input, bool base2, std::string unit) {
<< unit;
return ss.str();
}
// Two layers of indirection, for the specialisation below
template <typename T>
std::string si_string_impl(T input, bool base2, std::string unit) {
// (input == -input) can happen if we're at the minimum of the native signed integer type, so make sure we don't recurse infinitely
// It will still give bad output, but it won't overflow the stack
if (input < 0 && input != -input)
return unicode_minus + si_string(-input, base2, unit);
return si_string_impl2(input, base2, unit);
}
// Specialisation for unsigned as the template causes warnings otherwise
template <> std::string si_string_impl(unsigned input, bool base2, std::string unit) {
return si_string_impl2(input, base2, unit);
}
// Public functions
std::string si_string(double input, bool base2, std::string unit) {
return si_string_impl(input, base2, unit);
}