diff --git a/potassco/string_convert.h b/potassco/string_convert.h index d59fa7e..612e1e9 100644 --- a/potassco/string_convert.h +++ b/potassco/string_convert.h @@ -121,6 +121,7 @@ int xconvert(const char* x, int& out, const char** errPos = 0, int = 0); int xconvert(const char* x, long& out, const char** errPos = 0, int = 0); int xconvert(const char* x, unsigned long& out, const char** errPos = 0, int = 0); int xconvert(const char* x, double& out, const char** errPos = 0, int = 0); +int xconvert(const char* x, float& out, const char** errPos = 0, int = 0); int xconvert(const char* x, const char*& out, const char** errPos = 0, int = 0); int xconvert(const char* x, std::string& out, const char** errPos = 0, int sep = 0); template diff --git a/src/string_convert.cpp b/src/string_convert.cpp index 51a6af2..7f91ab6 100644 --- a/src/string_convert.cpp +++ b/src/string_convert.cpp @@ -234,6 +234,13 @@ int xconvert(const char* x, double& out, const char** errPos, int) { return parsed(err != x, err, errPos); } +int xconvert(const char* x, float& out, const char** errPos, int i) { + double temp; + int r = xconvert(x, temp, errPos, i); + if (r > 0) { out = static_cast(temp); } + return r; +} + int xconvert(const char* x, const char*& out, const char** errPos, int) { out = x; if (errPos) { *errPos = x + strlen(x); } diff --git a/tests/test_string_convert.cpp b/tests/test_string_convert.cpp index 177f31e..77dce8d 100644 --- a/tests/test_string_convert.cpp +++ b/tests/test_string_convert.cpp @@ -142,19 +142,29 @@ TEST_CASE("String conversion", "[string]") { SECTION("double parsing is locale-independent") { typedef std::pair P; - P lcg[] = {P("de", "DE"), P("el", "GR"), P("ru", "RU"), P("es", "ES"), P("it", "IT")}; - const char* x = 0; -#if defined(_MSC_VER) && _MSC_VER <= 1600 - x = setlocale(LC_ALL, "deu_deu"); -#endif - for (const P* it = lcg, *end = it + sizeof(lcg)/sizeof(P); it != end && !x; ++it) { - x = setlocale(LC_ALL, std::string(it->first).append(1, '_').append(it->second).c_str()); - if (x != 0) { break; } - x = setlocale(LC_ALL, std::string(it->first).append(1, '-').append(it->second).c_str()); + typedef std::pair R; + P lcg[] = {P("deu", "deu"), P("de", "DE"), P("el", "GR"), P("ru", "RU"), P("es", "ES"), P("it", "IT")}; + char sep[3] = {'_', '-', 0}; + const char* codeset[3] = {"", ".utf8", 0}; + R restore(setlocale(LC_ALL, nullptr), std::locale()); + bool set = false; + for (const P* it = lcg, *end = it + sizeof(lcg)/sizeof(P); it != end && !set; ++it) { + for (const char* s = sep; *s && !set; ++s) { + for (const char** code = codeset; *code && !set; ++code) { + std::string loc(it->first); + loc.append(1, *s).append(it->second).append(*code); + if (setlocale(LC_ALL, loc.c_str())) { + restore.second = std::locale::global(std::locale(loc)); + set = true; + } + } + } } - if (x) { - REQUIRE(Potassco::string_cast("12.32") == 12.32); - setlocale(LC_ALL, "C"); + if (set) { + CHECK_NOTHROW(Potassco::string_cast("12.32") == 12.32); + CHECK_NOTHROW(Potassco::string_cast("12.32") == 12.32f); + setlocale(LC_ALL, restore.first.c_str()); + REQUIRE_NOTHROW(std::locale::global(restore.second)); } else { WARN("could not set locale - test ignored");