X-Git-Url: http://git.tdb.fi/?p=libs%2Fcore.git;a=blobdiff_plain;f=source%2Fstrings%2Flexicalcast.h;h=25e3268126bde5d65cf19dca35d188c96dcebb5e;hp=b41654d1537a822f8a13af2d1a0616a4761d0e2f;hb=468ec9f6554c89b52e10a280411c9b9d99ef451b;hpb=4a38eb20402936497cbb75527dd7a7b321f51415 diff --git a/source/strings/lexicalcast.h b/source/strings/lexicalcast.h index b41654d..25e3268 100644 --- a/source/strings/lexicalcast.h +++ b/source/strings/lexicalcast.h @@ -1,16 +1,10 @@ -/* $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 #include "fmt.h" namespace Msp { @@ -41,14 +35,15 @@ class LexicalConverter { private: Fmt fmt; + bool filled; std::string buf; public: - LexicalConverter(const Fmt &f): fmt(f) { } - LexicalConverter(const std::string &s, const Fmt &f): fmt(f), buf(s) { } + LexicalConverter(const Fmt &f): fmt(f), filled(false) { } + LexicalConverter(const std::string &s, const Fmt &f): fmt(f), filled(true), buf(s) { } const Fmt &get_fmt() const { return fmt; } - const std::string &get() const { return buf; } + const std::string &get() const; void result(const std::string &); }; @@ -96,7 +91,39 @@ void operator>>(const LexicalConverter &, std::string &); // Generic operators using stringstream template -void operator<<(LexicalConverter &c, const T &v) +struct HasFormattedOutput: Sfinae +{ + static std::ostream &s; + static T &v; + + /* The expression must depend on the template parameter, or the compiler + will give an error. */ + template + static Yes f(int (*)[sizeof(s<::v)]); + template + static No f(...); + + enum { value = Evaluate(0))>::value }; +}; + +template +struct HasFormattedInput: Sfinae +{ + static std::istream &s; + static T &v; + + template + static Yes f(int (*)[sizeof(s>>HasFormattedOutput::v)]); + template + static No f(...); + + enum { value = Evaluate(0))>::value }; +}; + + +template +typename EnableIf::value, void>::Yes +operator<<(LexicalConverter &c, const T &v) { std::ostringstream ss; ss< -void operator>>(const LexicalConverter &c, T &v) +typename EnableIf::value, void>::Yes +operator>>(const LexicalConverter &c, T &v) { std::istringstream ss(c.get()); ss.setf(std::ios_base::fmtflags(0), std::ios_base::skipws); @@ -113,23 +141,51 @@ void operator>>(const LexicalConverter &c, T &v) throw lexical_error("conversion failure"); } -// The main interface to the lexical conversion machinery +// Helper struct to provide partial template specialization + +template +struct LexicalCast; template -inline T lexical_cast(const std::string &s, const Fmt &f = Fmt()) +struct LexicalCast { - LexicalConverter conv(s, f); - T result; - conv>>result; - return result; -} + static T 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()) +template +struct LexicalCast +{ + static std::string cast(const F &v, const Fmt &f = Fmt()) + { + LexicalConverter conv(f); + conv< +struct LexicalCast +{ + static std::string cast(const std::string &v, const Fmt &f = Fmt()) + { + LexicalConverter conv(f); + conv< +inline T lexical_cast(const F &v, const Fmt &f = Fmt()) { - LexicalConverter conv(f); - conv<::cast(v, f); } } // namespace Msp