(C++) LexicalCast
January 11, 2018 · View on GitHub
(C++) LexicalCast
LexicalCast is a convert code snippet to convert std::string to (possibly) any data type. CanCast can check if this conversion is possible.
LexicalCast uses CanCast.
LexicalCast serves the same purpose as boost::lexical_cast, but does not use Boost. Note that there are differences between LexicalCast and boost::lexical_cast, as boost::lexical_cast is more strict.
#include <string> #include <cassert> //From http://www.richelbilderbeek.nl/CppLexicalCast.htm template <typename TargetType> const TargetType LexicalCast(const std::string& s); //From http://www.richelbilderbeek.nl/CppLexicalCast.htm template <> const int LexicalCast<int>(const std::string& s) { assert(CanCast<int>(s) == true); return std::atoi(s.c_str()); } //From http://www.richelbilderbeek.nl/CppLexicalCast.htm template <> const double LexicalCast<double>(const std::string& s) { assert(CanCast<double>(s) == true); return std::atof(s.c_str()); }
Comparison between LexicalCast and boost::lexical_cast
The table below shows if a std::string can be converted according to CanCast (CC) and CanLexicalCast (CLC) and what the result will be after LexicalCast (LC) and boost::lexical_cast (l_c). Note that the first std::string was a space (' '). Below the table I show the code I've used to generate this output.
******************************************************************************* Testing CanCast and LexicalCast ******************************************************************************* std:: CC? LC CC? LC string int int double double false ... false ... a false ... false ... 1 true 1 true 1 1. true 1 true 1 1.1 true 1 true 1.1 1.1. true 1 true 1.1 1.1.1 true 1 true 1.1 1a true 1 true 1 1.1a true 1 true 1.1 -1 true -1 true -1 -1. true -1 true -1 -1.1 true -1 true -1.1 -1.1. true -1 true -1.1 -1.1.1 true -1 true -1.1 ******************************************************************************* Testing CanLexicalCast and boost::lexical_cast ******************************************************************************* std:: CLC? l_c CLC? l_c string int int double double false ... false ... a false ... false ... 1 true 1 true 1 1. false ... true 1 1.1 false ... true 1.1 1.1. false ... false ... 1.1.1 false ... false ... 1a false ... false ... 1.1a false ... false ... -1 true -1 true -1 -1. false ... true -1 -1.1 false ... true -1.1 -1.1. false ... false ... -1.1.1 false ... false ...
const std::vector<std::string> GetTests() { std::vector<std::string> v; v.push_back(" "); v.push_back("a"); v.push_back("1"); v.push_back("1."); v.push_back("1.1"); v.push_back("1.1."); v.push_back("1.1.1"); v.push_back("1a"); v.push_back("1.1a"); v.push_back("-1"); v.push_back("-1."); v.push_back("-1.1"); v.push_back("-1.1."); v.push_back("-1.1.1"); return v; } int main() { const std::vector<std::string> v = GetTests(); const int size = v.size(); std::cout << std::string(79,'*') << std::endl; std::cout << "Testing CanCast and LexicalCast" << std::endl; std::cout << std::string(79,'*') << std::endl; { std::cout << "std::" << '\t' << "CC?" << '\t' << "LC" << '\t' << "CC?" << '\t' << "LC" << std::endl; std::cout << "string" << '\t' << "int" << '\t' << "int" << '\t' << "double" << '\t' << "double" << std::endl; for (int i=0; i!=size; ++i) { const std::string s = v[i]; std::cout << s << '\t'; if (CanCast<int>(s) == true) { std::cout << "true" << '\t' << LexicalCast<int>(s) << '\t'; } else { std::cout << "false" << '\t' << "..." << '\t'; } if (CanCast<double>(s) == true) { std::cout << "true" << '\t' << LexicalCast<double>(s) << '\t'; } else { std::cout << "false" << '\t' << "..." << '\t'; } std::cout << std::endl; } } std::cout << std::string(79,'*') << std::endl; std::cout << "Testing CanLexicalCast and boost::lexical_cast" << std::endl; std::cout << std::string(79,'*') << std::endl; { std::cout << "std::" << '\t' << "CLC?" << '\t' << "l_c" << '\t' << "CLC?" << '\t' << "l_c" << std::endl; std::cout << "string" << '\t' << "int" << '\t' << "int" << '\t' << "double" << '\t' << "double" << std::endl; for (int i=0; i!=size; ++i) { const std::string s = v[i]; std::cout << s << '\t'; if (CanLexicalCast<int>(s) == true) { std::cout << "true" << '\t' << boost::lexical_cast<int>(s) << '\t'; } else { std::cout << "false" << '\t' << "..." << '\t'; } if (CanLexicalCast<double>(s) == true) { std::cout << "true" << '\t' << boost::lexical_cast<double>(s) << '\t'; } else { std::cout << "false" << '\t' << "..." << '\t'; } std::cout << std::endl; } } }