1+ #include " ScalarConverter.hpp"
2+
3+ #include < cctype>
4+ #include < cerrno>
5+ #include < cfloat>
6+ #include < cmath>
7+ #include < cstdlib>
8+ #include < iostream>
9+ #include < limits>
10+ #include < stdexcept>
11+ #include < string>
12+
13+ // Constructor
14+ ScalarConverter::ScalarConverter () {}
15+ // Copy constructor
16+ ScalarConverter::ScalarConverter (const ScalarConverter&) {}
17+ // Assignment operator
18+ ScalarConverter& ScalarConverter::operator =(const ScalarConverter&) { return *this ; }
19+ // Destructor
20+ ScalarConverter::~ScalarConverter () {}
21+ // Convert function
22+ void ScalarConverter::convert (const std::string& literal) {
23+ Result result = parseLiteral (literal);
24+ printResult (result);
25+ }
26+ // Parse the literal
27+ ScalarConverter::Result ScalarConverter::parseLiteral (const std::string& literal) {
28+ Result result;
29+ // Check for special cases: NaN, +inf, -inf
30+ if (literal == " nan" || literal == " nanf" ) {
31+ result.isNaN = true ;
32+ return result;
33+ }
34+ if (literal == " +inf" || literal == " -inf" || literal == " inf" || literal == " +inff" || literal == " -inff" ||
35+ literal == " inff" ) {
36+ result.isInf = true ;
37+ return result;
38+ }
39+ // Check for char
40+ if (literal.length () == 1 && std::isprint (literal[0 ])) {
41+ result.c = literal[0 ];
42+ result.hasChar = true ;
43+ return result;
44+ }
45+ // Check for int
46+ try {
47+ long intValue = std::stol (literal);
48+ if (intValue < std::numeric_limits<int >::min () || intValue > std::numeric_limits<int >::max ()) {
49+ throw std::out_of_range (" Integer out of range" );
50+ }
51+ result.i = static_cast <int >(intValue);
52+ result.hasInt = true ;
53+ } catch (const std::invalid_argument&) {
54+ } catch (const std::out_of_range&) {
55+ }
56+ // Check for float
57+ try {
58+ float floatValue = std::stof (literal);
59+ if (floatValue < -std::numeric_limits<float >::max () || floatValue > std::numeric_limits<float >::max ()) {
60+ throw std::out_of_range (" Float out of range" );
61+ }
62+ result.f = floatValue;
63+ result.hasFloat = true ;
64+ } catch (const std::invalid_argument&) {
65+ } catch (const std::out_of_range&) {
66+ }
67+ // Check for double
68+ try {
69+ double doubleValue = std::stod (literal);
70+ if (doubleValue < -std::numeric_limits<double >::max () || doubleValue > std::numeric_limits<double >::max ()) {
71+ throw std::out_of_range (" Double out of range" );
72+ }
73+ result.d = doubleValue;
74+ result.hasDouble = true ;
75+ } catch (const std::invalid_argument&) {
76+ } catch (const std::out_of_range&) {
77+ }
78+ // If all conversions fail, throw an exception
79+ if (!result.hasChar && !result.hasInt && !result.hasFloat && !result.hasDouble ) {
80+ throw std::invalid_argument (" Invalid literal" );
81+ }
82+ return result;
83+ }
84+
85+ // Print the result
86+ void ScalarConverter::printResult (const Result& r) {
87+ if (r.isNaN ) {
88+ std::cout << " char: impossible" << std::endl;
89+ std::cout << " int: impossible" << std::endl;
90+ std::cout << " float: nanf" << std::endl;
91+ std::cout << " double: nan" << std::endl;
92+ } else if (r.isInf ) {
93+ std::cout << " char: impossible" << std::endl;
94+ std::cout << " int: impossible" << std::endl;
95+ std::cout << " float: inf" << std::endl;
96+ std::cout << " double: inf" << std::endl;
97+ } else {
98+ // Print char
99+ if (r.hasChar && std::isprint (r.c )) {
100+ std::cout << " char: '" << r.c << " '" << std::endl;
101+ } else {
102+ std::cout << " char: non displayable" << std::endl;
103+ }
104+
105+ // Print int
106+ if (r.hasInt ) {
107+ std::cout << " int: " << r.i << std::endl;
108+ } else {
109+ std::cout << " int: impossible" << std::endl;
110+ }
111+
112+ // Print float
113+ if (r.hasFloat ) {
114+ float val = r.f ;
115+ if (val == -0 .0f ) {
116+ val = 0 .0f ; // Handle -0.0 case
117+ }
118+ if (std::isinf (val) || std::isnan (val)) {
119+ std::cout << " float: " << (std::isnan (val) ? " nanf" : (val < 0 ? " -inff" : " +inff" )) << std::endl;
120+ } else {
121+ std::cout.precision (1 );
122+ std::cout.setf (std::ios_base::fixed);
123+ std::cout << " float: " << val << " f" << std::endl;
124+ }
125+ } else {
126+ std::cout << " float: impossible" << std::endl;
127+ }
128+
129+ // Print double
130+ if (r.hasDouble ) {
131+ double val = r.d ;
132+ if (val == -0.0 ) {
133+ val = 0.0 ; // Handle -0.0 case
134+ }
135+ if (std::isinf (val) || std::isnan (val)) {
136+ std::cout << " double: " << (std::isnan (val) ? " nan" : (val < 0 ? " -inf" : " +inf" )) << std::endl;
137+ } else {
138+ std::cout.precision (1 );
139+ std::cout.setf (std::ios_base::fixed);
140+ std::cout << " double: " << val << std::endl;
141+ }
142+ } else {
143+ std::cout << " double: impossible" << std::endl;
144+ }
145+ }
146+ }
0 commit comments