diff options
author | 2020-09-06 12:12:24 +0200 | |
---|---|---|
committer | 2020-09-06 13:16:05 +0200 | |
commit | f3b2dd65f5d9fd4f3ef7a3ca94efd5b2882e358c (patch) | |
tree | f3d5eb0da83eb8d1c8b942702df547caa8c011a8 /src/lib/netlist/plib/pstonum.h | |
parent | d2c39caec20dc058e0726c1dcaca1ce74c8e04de (diff) |
netlist: fix multi byte string issues.
Diffstat (limited to 'src/lib/netlist/plib/pstonum.h')
-rw-r--r-- | src/lib/netlist/plib/pstonum.h | 43 |
1 files changed, 20 insertions, 23 deletions
diff --git a/src/lib/netlist/plib/pstonum.h b/src/lib/netlist/plib/pstonum.h index b3e0df5504e..3be3f949b7a 100644 --- a/src/lib/netlist/plib/pstonum.h +++ b/src/lib/netlist/plib/pstonum.h @@ -27,11 +27,11 @@ namespace plib // ---------------------------------------------------------------------------------------- template <typename T, typename S> - T pstonum_locale(const std::locale &loc, const S &arg, std::size_t *idx) + T pstonum_locale(const std::locale &loc, const S &arg, bool *err) { std::stringstream ss; ss.imbue(loc); - ss << arg; + ss << putf8string(arg); auto len(ss.tellp()); T x(constants<T>::zero()); if (ss >> x) @@ -39,10 +39,10 @@ namespace plib auto pos(ss.tellg()); if (pos == decltype(pos)(-1)) pos = len; - *idx = narrow_cast<std::size_t>(pos); + *err = (pos != len); } else - *idx = constants<std::size_t>::zero(); + *err = true; return x; } @@ -53,10 +53,10 @@ namespace plib struct pstonum_helper<T, std::enable_if_t<plib::is_integral<T>::value && plib::is_signed<T>::value>> { template <typename S> - long long operator()(std::locale loc, const S &arg, std::size_t *idx) + long long operator()(std::locale loc, const S &arg, bool *err) { //return std::stoll(arg, idx); - return pstonum_locale<long long>(loc, arg, idx); + return pstonum_locale<long long>(loc, arg, err); } }; @@ -64,10 +64,10 @@ namespace plib struct pstonum_helper<T, std::enable_if_t<plib::is_integral<T>::value && !plib::is_signed<T>::value>> { template <typename S> - unsigned long long operator()(std::locale loc, const S &arg, std::size_t *idx) + unsigned long long operator()(std::locale loc, const S &arg, bool *err) { //return std::stoll(arg, idx); - return pstonum_locale<unsigned long long>(loc, arg, idx); + return pstonum_locale<unsigned long long>(loc, arg, err); } }; @@ -75,9 +75,9 @@ namespace plib struct pstonum_helper<T, std::enable_if_t<std::is_floating_point<T>::value>> { template <typename S> - long double operator()(std::locale loc, const S &arg, std::size_t *idx) + long double operator()(std::locale loc, const S &arg, bool *err) { - return pstonum_locale<long double>(loc, arg, idx); + return pstonum_locale<long double>(loc, arg, err); } }; @@ -87,9 +87,9 @@ namespace plib { // FIXME: use strtoflt128 from quadmath.h template <typename S> - FLOAT128 operator()(std::locale loc, const S &arg, std::size_t *idx) + FLOAT128 operator()(std::locale loc, const S &arg, bool *err) { - return narrow_cast<FLOAT128>(pstonum_locale<long double>(loc, arg, idx)); + return narrow_cast<FLOAT128>(pstonum_locale<long double>(loc, arg, err)); } }; #endif @@ -97,22 +97,19 @@ namespace plib template<typename T, typename S> T pstonum(const S &arg, const std::locale &loc = std::locale::classic()) noexcept(false) { - putf8string u8arg(arg); - decltype(u8arg.c_str()) cstr(u8arg.c_str()); - std::size_t idx(0); - auto ret = pstonum_helper<T>()(loc, cstr, &idx); + bool err(false); + auto ret = pstonum_helper<T>()(loc, arg, &err); + if (err) + throw pexception(pstring("Error converting string to number: ") + pstring(arg)); + using ret_type = decltype(ret); if (ret >= narrow_cast<ret_type>(plib::numeric_limits<T>::lowest()) && ret <= narrow_cast<ret_type>(plib::numeric_limits<T>::max())) { - if (cstr[idx] != 0) - throw pexception(pstring("Continuation after numeric value ends: ") + pstring(cstr)); + return narrow_cast<T>(ret); } - else - { - throw pexception(pstring("Out of range: ") + pstring(cstr)); - } - return narrow_cast<T>(ret); + + throw pexception(pstring("Out of range: ") + pstring(arg)); } template<typename R, typename T> |