#ifndef STAR_LEXICAL_CAST_HPP #define STAR_LEXICAL_CAST_HPP #include "StarString.hpp" #include "StarMaybe.hpp" #include #include namespace Star { STAR_EXCEPTION(BadLexicalCast, StarException); // Very simple basic lexical cast using stream input. Always operates in the // "C" locale. template Maybe maybeLexicalCast(std::string const& s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { Type result; std::istringstream stream(s); stream.flags(flags); stream.imbue(std::locale::classic()); if (!(stream >> result)) return {}; // Confirm that we read everything out of the stream char ch; if (stream >> ch) return {}; return result; } template Maybe maybeLexicalCast(char const* s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { return maybeLexicalCast(std::string(s), flags); } template Maybe maybeLexicalCast(String const& s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { return maybeLexicalCast(s.utf8(), flags); } template Type lexicalCast(std::string const& s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { auto m = maybeLexicalCast(s, flags); if (m) return m.take(); else throw BadLexicalCast(strf("Lexical cast failed on '%s'", s)); } template Type lexicalCast(char const* s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { return lexicalCast(std::string(s), flags); } template Type lexicalCast(String const& s, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { return lexicalCast(s.utf8(), flags); } template std::string toString(Type const& t, std::ios_base::fmtflags flags = std::ios_base::boolalpha) { std::stringstream ss; ss.flags(flags); ss.imbue(std::locale::classic()); ss << t; return ss.str(); } } #endif