]> git.tdb.fi Git - libs/core.git/blobdiff - source/lexicalcast.h
Rewrite lexical_cast to use internal conversion routines
[libs/core.git] / source / lexicalcast.h
index a2bb43953d43d764e24ff517d62e1ffd0052f6ee..42393fe251c9bbaee8b56c3767437d70a4ad18e3 100644 (file)
@@ -1,7 +1,7 @@
 /* $Id$
 
 This file is part of libmspstrings
 /* $Id$
 
 This file is part of libmspstrings
-Copyright © 2006-2007 Mikko Rasa
+Copyright © 2006-2008 Mikko Rasa
 Distributed under the LGPL
 */
 
 Distributed under the LGPL
 */
 
@@ -15,39 +15,110 @@ Distributed under the LGPL
 
 namespace Msp {
 
 
 namespace Msp {
 
+/**
+Thrown for errors in lexical conversions
+*/
 class LexicalError: public Exception
 {
 public:
        LexicalError(const std::string &w_): Exception(w_) { }
 };
 
 class LexicalError: public Exception
 {
 public:
        LexicalError(const std::string &w_): Exception(w_) { }
 };
 
-template<typename T>
-T lexical_cast(const std::string &s)
+/**
+Helper class for lexical_cast to facilitate operator overloading.
+*/
+class LexicalConverter
 {
 {
-       std::istringstream ss(s);
-       ss.setf(std::ios_base::fmtflags(0), std::ios_base::skipws);
+private:
+       Fmt fmt;
+       std::string buf;
+
+public:
+       LexicalConverter(const Fmt &f): fmt(f) { }
+       LexicalConverter(const std::string &s, const Fmt &f): fmt(f), buf(s) { }
+
+       const Fmt &get_fmt() const { return fmt; }
+       const std::string &get() const { return buf; }
+       void result(const std::string &);
+};
+
+void operator<<(LexicalConverter &, char);
+void operator<<(LexicalConverter &, signed char);
+void operator<<(LexicalConverter &, short);
+void operator<<(LexicalConverter &, int);
+void operator<<(LexicalConverter &, long);
+void operator<<(LexicalConverter &, unsigned char);
+void operator<<(LexicalConverter &, unsigned short);
+void operator<<(LexicalConverter &, unsigned);
+void operator<<(LexicalConverter &, unsigned long);
+#ifdef __GNUC__
+void operator<<(LexicalConverter &, long long);
+void operator<<(LexicalConverter &, unsigned long long);
+#endif
+void operator<<(LexicalConverter &, bool);
+void operator<<(LexicalConverter &, float);
+void operator<<(LexicalConverter &, double);
+void operator<<(LexicalConverter &, long double);
+void operator<<(LexicalConverter &, const std::string &);
+void operator<<(LexicalConverter &, const char *);
+void operator<<(LexicalConverter &, const void *);
+
+void operator>>(const LexicalConverter &, char &);
+void operator>>(const LexicalConverter &, signed char &);
+void operator>>(const LexicalConverter &, short &);
+void operator>>(const LexicalConverter &, int &);
+void operator>>(const LexicalConverter &, long &);
+void operator>>(const LexicalConverter &, unsigned char &);
+void operator>>(const LexicalConverter &, unsigned short &);
+void operator>>(const LexicalConverter &, unsigned int &);
+void operator>>(const LexicalConverter &, unsigned long &);
+#ifdef __GNUC__
+void operator>>(const LexicalConverter &, long long &);
+void operator>>(const LexicalConverter &, unsigned long long &);
+#endif
+void operator>>(const LexicalConverter &, bool &);
+void operator>>(const LexicalConverter &, float &);
+void operator>>(const LexicalConverter &, double &);
+void operator>>(const LexicalConverter &, long double &);
+void operator>>(const LexicalConverter &, std::string &);
 
 
-       T tmp;
-       ss>>tmp;
+// Generic operators using stringstream
 
 
+template<typename T>
+void operator<<(LexicalConverter &c, const T &v)
+{
+       std::ostringstream ss;
+       ss<<c.get_fmt()<<v;
+       c.result(ss.str());
+}
+
+template<typename T>
+void operator>>(const LexicalConverter &c, T &v)
+{
+       std::istringstream ss(c.get());
+       ss.setf(std::ios_base::fmtflags(0), std::ios_base::skipws);
+       ss>>v;
        if(ss.fail() || !ss.eof())
                throw LexicalError("Conversion failure");
        if(ss.fail() || !ss.eof())
                throw LexicalError("Conversion failure");
-
-       return tmp;
 }
 
 }
 
-template<>
-inline std::string lexical_cast<std::string>(const std::string &s)
+// The main interface to the lexical conversion machinery
+
+template<typename T>
+inline T lexical_cast(const std::string &s, const Fmt &f=Fmt())
 {
 {
-       return s;
+       LexicalConverter conv(s, f);
+       T result;
+       conv>>result;
+       return result;
 }
 
 template<typename T>
 }
 
 template<typename T>
-std::string lexical_cast(const T &v, const Fmt &f=Fmt())
+inline std::string lexical_cast(const T &v, const Fmt &f=Fmt())
 {
 {
-       std::ostringstream ss;
-       ss<<f<<v;
-       return ss.str();
+       LexicalConverter conv(f);
+       conv<<v;
+       return conv.get();
 }
 
 } // namespace Msp
 }
 
 } // namespace Msp