]> git.tdb.fi Git - libs/core.git/commitdiff
Exception improvements for lexical_cast
authorMikko Rasa <tdb@tdb.fi>
Sat, 28 May 2011 09:04:02 +0000 (12:04 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 28 May 2011 09:12:53 +0000 (12:12 +0300)
source/strings/lexicalcast.cpp
source/strings/lexicalcast.h

index 5903bb1197d6364382714dd4f1772b477844b919..a91c18cc287f149f7ad80eb39122935796812abb 100644 (file)
@@ -7,6 +7,7 @@ Distributed under the LGPL
 
 #include <cmath>
 #include <limits>
+#include "format.h"
 #include "lexicalcast.h"
 
 using namespace std;
@@ -130,7 +131,7 @@ template<typename T>
 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<T>::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<typename T>
 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<typename T>
 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];
        }
 }
index 3bfc342a1f584e91cc218eb24b226c7a29c777da..b41654d1537a822f8a13af2d1a0616a4761d0e2f 100644 (file)
@@ -10,7 +10,7 @@ Distributed under the LGPL
 
 #include <sstream>
 #include <string>
-#include <msp/core/except.h>
+#include <stdexcept>
 #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