(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;     }   } }