From: Mikko Rasa Date: Sat, 28 May 2011 09:04:02 +0000 (+0300) Subject: Exception improvements for lexical_cast X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=commitdiff_plain;h=4a38eb20402936497cbb75527dd7a7b321f51415 Exception improvements for lexical_cast --- diff --git a/source/strings/lexicalcast.cpp b/source/strings/lexicalcast.cpp index 5903bb1..a91c18c 100644 --- a/source/strings/lexicalcast.cpp +++ b/source/strings/lexicalcast.cpp @@ -7,6 +7,7 @@ Distributed under the LGPL #include #include +#include "format.h" #include "lexicalcast.h" using namespace std; @@ -130,7 +131,7 @@ template T str_to_int(const std::string &s, const Fmt &f) { if(s.empty()) - throw LexicalError("Empty input in integer conversion"); + throw lexical_error("conversion of '' to integer"); std::string::const_iterator i = s.begin(); @@ -139,7 +140,7 @@ T str_to_int(const std::string &s, const Fmt &f) if(*i=='-') { if(!IsSigned::result) - throw LexicalError("Negative sign in unsigned integer conversion"); + throw lexical_error(format("conversion of '%s' to unsigned integer", s)); neg = true; ++i; } @@ -148,7 +149,7 @@ T str_to_int(const std::string &s, const Fmt &f) // Must have some digits to convert if(i==s.end()) - throw LexicalError("Missing digits in integer conversion"); + throw lexical_error(format("conversion of '%s' to integer", s)); T base = f.get_base(); if(!base && i!=s.end()) @@ -185,10 +186,10 @@ T str_to_int(const std::string &s, const Fmt &f) else if(*i>='a' && *i<='f') digit = *i-'a'+10; if(digit>=base) - throw LexicalError("Invalid digit in integer conversion"); + throw lexical_error(format("conversion of '%s' to integer (base-%d)", s, base)); T next = result*base+digit; if(next/base!=result) - throw LexicalError("Overflow in integer conversion"); + throw lexical_error(format("conversion of '%s' to %d-bit integer", s, sizeof(T)*8)); result = next; } @@ -212,14 +213,14 @@ string bool_to_str(bool b, const Fmt &f) bool str_to_bool(const string &s) { if(s.empty()) - throw LexicalError("Empty input in boolean conversion"); + throw lexical_error("conversion of '' to boolean"); if(s=="1" || s=="true" || s=="yes" || s=="on") return true; else if(s=="0" || s=="false" || s=="no" || s=="off") return false; - throw LexicalError("Invalid input in boolean conversion"); + throw lexical_error(format("conversion of '%s' to boolean", s)); } @@ -229,7 +230,7 @@ template string flt_to_str(T v, const Fmt &f) { if(f.get_type()==Fmt::CHAR) - throw LexicalError("Character format in floating-point conversion"); + throw format_mismatch("floating-point conversion with character format"); Fmt::FloatMode mode = f.get_floatmode(); long double w = abs(v); @@ -395,7 +396,7 @@ template T str_to_flt(const string &s, const Fmt &) { if(s.empty()) - throw LexicalError("Empty input in floating-point conversion"); + throw lexical_error("conversion of '' to floating-point"); std::string::const_iterator i = s.begin(); @@ -411,7 +412,7 @@ T str_to_flt(const string &s, const Fmt &) // Must have some digits to convert if(i==s.end()) - throw LexicalError("Missing digits in floating-point conversion"); + throw lexical_error(format("conversion of '%s' to floating-point", s)); long double v = 0; int exp = 0; @@ -423,7 +424,7 @@ T str_to_flt(const string &s, const Fmt &) if(*i=='.') { if(point_seen) - throw LexicalError("Extra point in floating-point conversion"); + throw lexical_error(format("conversion of '%s' to floating-point", s)); point_seen = true; } else if(*i>='0' && *i<='9') @@ -442,7 +443,7 @@ T str_to_flt(const string &s, const Fmt &) break; } else - throw LexicalError("Invalid digit in floating-point conversion"); + throw lexical_error(format("conversion of '%s' to floating-point", s)); } // Scale and negate the result as needed @@ -469,7 +470,7 @@ T str_to_flt(const string &s, const Fmt &) string str_to_str(const string &s, const Fmt &f) { if(f.get_type()==Fmt::NUM) - throw LexicalError("Numeric format in string conversion"); + throw format_mismatch("string conversion with numeric format"); return s; } @@ -566,9 +567,9 @@ void operator>>(const LexicalConverter &c, char &v) { const std::string &s = c.get(); if(s.empty()) - throw LexicalError("Empty input in character conversion"); + throw lexical_error("conversion of '' to character"); if(s.size()>1) - throw LexicalError("Extra input in character conversion"); + throw lexical_error(format("conversion of '%s' to character", s)); v = s[0]; } } diff --git a/source/strings/lexicalcast.h b/source/strings/lexicalcast.h index 3bfc342..b41654d 100644 --- a/source/strings/lexicalcast.h +++ b/source/strings/lexicalcast.h @@ -10,7 +10,7 @@ Distributed under the LGPL #include #include -#include +#include #include "fmt.h" namespace Msp { @@ -18,10 +18,19 @@ namespace Msp { /** Thrown for errors in lexical conversions */ -class LexicalError: public Exception +class lexical_error: public std::runtime_error { public: - LexicalError(const std::string &w_): Exception(w_) { } + lexical_error(const std::string &w): runtime_error(w) { } + virtual ~lexical_error() throw() { } +}; + + +class format_mismatch: public lexical_error +{ +public: + format_mismatch(const std::string &w): lexical_error(w) { } + virtual ~format_mismatch() throw() { } }; @@ -101,7 +110,7 @@ void operator>>(const LexicalConverter &c, T &v) ss.setf(std::ios_base::fmtflags(0), std::ios_base::skipws); ss>>v; if(ss.fail() || !ss.eof()) - throw LexicalError("Conversion failure"); + throw lexical_error("conversion failure"); } // The main interface to the lexical conversion machinery