dwrswr/cpp-module-06-guide
0
1#include "ScalarConverter.hpp"2#include <cctype>3#include <climits>4#include <cstdlib>5#include <iomanip>6#include <iostream>7#include <limits>8 9enum e_type10{11 CHAR_LIT,12 INT_LIT,13 FLOAT_LIT,14 DOUBLE_LIT,15 INVALID_LIT16};17 18ScalarConverter::ScalarConverter(void) {}19 20ScalarConverter::ScalarConverter(const ScalarConverter &src)21{22 (void)src;23}24 25ScalarConverter::~ScalarConverter(void) {}26 27ScalarConverter &ScalarConverter::operator=(const ScalarConverter &rhs)28{29 (void)rhs;30 return (*this);31}32 33static bool isNumber(const std::string &s, bool &dot)34{35 size_t i = 0;36 size_t digits = 0;37 38 dot = false;39 if (i < s.length() && (s[i] == '+' || s[i] == '-'))40 i++;41 while (i < s.length())42 {43 if (std::isdigit(static_cast<unsigned char>(s[i])))44 digits++;45 else if (s[i] == '.' && !dot)46 dot = true;47 else48 return (false);49 i++;50 }51 return (digits > 0);52}53 54static e_type detect(const std::string &s)55{56 bool dot;57 58 if (s.length() == 3 && s[0] == '\'' && s[2] == '\'')59 return (CHAR_LIT);60 if (s.length() == 1 && !std::isdigit(s[0]))61 return (CHAR_LIT);62 if (s == "nanf" || s == "+inff" || s == "-inff")63 return (FLOAT_LIT);64 if (s == "nan" || s == "+inf" || s == "-inf")65 return (DOUBLE_LIT);66 if (isNumber(s, dot))67 return (dot ? DOUBLE_LIT : INT_LIT);68 if (s.length() > 1 && s[s.length() - 1] == 'f'69 && isNumber(s.substr(0, s.length() - 1), dot))70 return (FLOAT_LIT);71 return (INVALID_LIT);72}73 74static void printChar(double value)75{76 std::cout << "char: ";77 if (value != value || value < CHAR_MIN || value > CHAR_MAX)78 std::cout << "impossible" << std::endl;79 else if (!std::isprint(static_cast<unsigned char>(static_cast<char>(value))))80 std::cout << "Non displayable" << std::endl;81 else82 std::cout << "'" << static_cast<char>(value) << "'" << std::endl;83}84 85static void printInt(double value)86{87 std::cout << "int: ";88 if (value != value || value < INT_MIN || value > INT_MAX)89 std::cout << "impossible" << std::endl;90 else91 std::cout << static_cast<int>(value) << std::endl;92}93 94static void printFloat(double value, bool pseudo)95{96 std::cout << "float: ";97 if (!pseudo && (value != value98 || value < -std::numeric_limits<float>::max()99 || value > std::numeric_limits<float>::max()))100 std::cout << "impossible" << std::endl;101 else102 std::cout << std::fixed << std::setprecision(1)103 << static_cast<float>(value) << "f" << std::endl;104}105 106static void printDouble(double value, bool pseudo)107{108 std::cout << "double: ";109 if (!pseudo && (value != value110 || value < -std::numeric_limits<double>::max()111 || value > std::numeric_limits<double>::max()))112 std::cout << "impossible" << std::endl;113 else114 std::cout << std::fixed << std::setprecision(1) << value << std::endl;115}116 117void ScalarConverter::convert(const std::string &literal)118{119 e_type type = detect(literal);120 std::string body = literal;121 double value = 0.0;122 bool pseudo = false;123 124 if (type == INVALID_LIT)125 {126 std::cout << literal << " is not a char, an int, a float nor a double."127 << std::endl;128 return ;129 }130 if (type == CHAR_LIT)131 value = static_cast<double>(literal.length() == 3 ? literal[1] : literal[0]);132 else133 {134 if (type == FLOAT_LIT)135 body = literal.substr(0, literal.length() - 1);136 pseudo = (body == "nan" || body == "+inf" || body == "-inf");137 value = std::strtod(body.c_str(), NULL);138 }139 printChar(value);140 printInt(value);141 printFloat(value, pseudo);142 printDouble(value, pseudo);143}144 