X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Flexicalcast.h;fp=source%2Flexicalcast.h;h=42393fe251c9bbaee8b56c3767437d70a4ad18e3;hp=a2bb43953d43d764e24ff517d62e1ffd0052f6ee;hb=f5aa787e1a715867a8024816ccd58e9a4c7e23a4;hpb=08b94e4156f1444f196667a715bb0375ec97b931 diff --git a/source/lexicalcast.h b/source/lexicalcast.h index a2bb439..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 */ @@ -15,39 +15,110 @@ Distributed under the LGPL 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; + +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 +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"); - - return tmp; } -template<> -inline std::string lexical_cast(const std::string &s) +// The main interface to the lexical conversion machinery + +template +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 -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<