X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fstrings%2Flexicalcast.h;fp=source%2Fstrings%2Flexicalcast.h;h=3bfc342a1f584e91cc218eb24b226c7a29c777da;hp=0000000000000000000000000000000000000000;hb=b42ed73a1b241c0e93ee03c43c4584b41c549bac;hpb=5b1368cb791cab043f0435628cacbaff36e39b7b diff --git a/source/strings/lexicalcast.h b/source/strings/lexicalcast.h new file mode 100644 index 0000000..3bfc342 --- /dev/null +++ b/source/strings/lexicalcast.h @@ -0,0 +1,128 @@ +/* $Id$ + +This file is part of libmspstrings +Copyright © 2006-2008 Mikko Rasa +Distributed under the LGPL +*/ + +#ifndef MSP_STRINGS_LEXICALCAST_H_ +#define MSP_STRINGS_LEXICALCAST_H_ + +#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_) { } +}; + + +/** +Helper class for lexical_cast to facilitate operator overloading. +*/ +class LexicalConverter +{ +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 &); + +// 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 + +template +inline T lexical_cast(const std::string &s, const Fmt &f = Fmt()) +{ + LexicalConverter conv(s, f); + T result; + conv>>result; + return result; +} + +template +inline std::string lexical_cast(const T &v, const Fmt &f = Fmt()) +{ + LexicalConverter conv(f); + conv<