X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Flexicalcast.h;h=42393fe251c9bbaee8b56c3767437d70a4ad18e3;hp=c73856b8228894374f00b97e2f81dcbcd4532ca2;hb=f5aa787e1a715867a8024816ccd58e9a4c7e23a4;hpb=381c89769c0ffaa14e6a92c662323b5c45e1eba3 diff --git a/source/lexicalcast.h b/source/lexicalcast.h index c73856b..42393fe 100644 --- a/source/lexicalcast.h +++ b/source/lexicalcast.h @@ -1,7 +1,7 @@ /* $Id$ This file is part of libmspstrings -Copyright © 2006-2007 Mikko Rasa +Copyright © 2006-2008 Mikko Rasa Distributed under the LGPL */ @@ -10,38 +10,115 @@ Distributed under the LGPL #include #include -#include +#include #include "fmt.h" namespace Msp { +/** +Thrown for errors in lexical conversions +*/ class LexicalError: public Exception { public: LexicalError(const std::string &w_): Exception(w_) { } }; -template -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; - T tmp; - ss>>tmp; +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 &); + +// Generic operators using stringstream + +template +void operator<<(LexicalConverter &c, const T &v) +{ + std::ostringstream ss; + ss< +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"); +} + +// The main interface to the lexical conversion machinery - return tmp; +template +inline T lexical_cast(const std::string &s, const Fmt &f=Fmt()) +{ + LexicalConverter conv(s, f); + T result; + conv>>result; + return result; } template -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<