Skip to content

Commit

Permalink
added description and fixed indentations
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomer Ashuach committed Apr 20, 2021
1 parent b4d4bc3 commit 4acd6f1
Showing 1 changed file with 123 additions and 123 deletions.
246 changes: 123 additions & 123 deletions common/utilities/string/string-utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,127 +6,127 @@
#include <string>

namespace utilities {
namespace string {

// Converts string to value via a given argument with desire type
// Input:
// - string of a number
// - argument with T type
// returns true if conversion succeeded

// NOTE for unsigned types:
// if the minus sign was part of the input sequence,
// the numeric value calculated from the sequence of digits is negated as if
// by unary minus in the result type, which applies unsigned integer wraparound rules.
// for example - when stoul gets'-4', it will return -(unsigned long)4

template <typename T, typename std::enable_if <std::is_arithmetic<T>::value>::type* = nullptr> // check if T is arithmetic during compile
inline bool string_to_value(const std::string& str, T& result)
{
try
{
size_t last_char_idx;
if (std::is_integral<T>::value)
{
if (std::is_same<T, unsigned long>::value)
{
if (str[0] == '-') return false; //for explanation see 'NOTE for unsigned types'
result = static_cast<T>(std::stoul(str, &last_char_idx));
}
else if (std::is_same<T, unsigned long long>::value)
{
if (str[0] == '-') return false;
result = static_cast<T>(std::stoull(str, &last_char_idx));
}
else if (std::is_same<T, long>::value)
{
result = static_cast<T>(std::stol(str, &last_char_idx));
}
else if (std::is_same<T, long long>::value)
{
result = static_cast<T>(std::stoll(str, &last_char_idx));
}
else if (std::is_same<T, int>::value)
{
result = static_cast<T>(std::stoi(str, &last_char_idx));
}
else if (std::is_same<T, short>::value)
{// no dedicated function fot short in std

int check_value = std::stoi(str, &last_char_idx);

if (check_value > std::numeric_limits<short>::max() || check_value < std::numeric_limits<short>::min())
throw std::out_of_range("short");

result = static_cast<T>(check_value);

}
else if (std::is_same<T, unsigned int>::value)
{// no dedicated function in std - unsgined corresponds to 16 bit, and unsigned long corresponds to 32 bit
if (str[0] == '-')
return false;

unsigned long check_value = std::stoul(str, &last_char_idx);

if (check_value > std::numeric_limits<unsigned int>::max())
throw std::out_of_range("unsigned int");

result = static_cast<T>(check_value);

}
else if (std::is_same<T, unsigned short>::value || std::is_same<T, unsigned short>::value)
{ // no dedicated function in std - unsgined corresponds to 16 bit, and unsigned long corresponds to 32 bit
if (str[0] == '-')
return false;

unsigned long check_value = std::stoul(str, &last_char_idx);

if (check_value > std::numeric_limits<unsigned short>::max())
throw std::out_of_range("unsigned short");

result = static_cast<T>(check_value);

}
else
{
return false;
}
}
else if (std::is_floating_point<T>::value)
{
if (std::is_same<T, float>::value)
{
result = static_cast<T>(std::stof(str, &last_char_idx));
if (!std::isfinite((float)result))
return false;
}
else if (std::is_same<T, double>::value)
{
result = static_cast<T>(std::stod(str, &last_char_idx));
if (!std::isfinite((double)result))
return false;
}
else if (std::is_same<T, long double>::value)
{
result = static_cast<T>(std::stold(str, &last_char_idx));
if (!std::isfinite((long double)result))
return false;
}
else
{
return false;
}
}
return str.size() == last_char_idx; // all the chars in the string are converted to the value (thus there are no other chars other than numbers)
}
catch (const std::invalid_argument&)
{
return false;
}
catch (const std::out_of_range&)
{
return false;
}
}
} // namespace string
namespace string {

// Converts string to value via a given argument with desire type
// Input:
// - string of a number
// - argument with T type
// returns true if conversion succeeded

// NOTE for unsigned types:
// if the minus sign was part of the input sequence,
// the numeric value calculated from the sequence of digits is negated as if
// by unary minus in the result type, which applies unsigned integer wraparound rules.
// for example - when stoul gets'-4', it will return -(unsigned long)4

template <typename T, typename std::enable_if <std::is_arithmetic<T>::value>::type* = nullptr> // check if T is arithmetic during compile
inline bool string_to_value(const std::string& str, T& result)
{
try
{
size_t last_char_idx;
if (std::is_integral<T>::value)
{
if (std::is_same<T, unsigned long>::value)
{
if (str[0] == '-') return false; //for explanation see 'NOTE for unsigned types'
result = static_cast<T>(std::stoul(str, &last_char_idx));
}
else if (std::is_same<T, unsigned long long>::value)
{
if (str[0] == '-') return false;
result = static_cast<T>(std::stoull(str, &last_char_idx));
}
else if (std::is_same<T, long>::value)
{
result = static_cast<T>(std::stol(str, &last_char_idx));
}
else if (std::is_same<T, long long>::value)
{
result = static_cast<T>(std::stoll(str, &last_char_idx));
}
else if (std::is_same<T, int>::value)
{
result = static_cast<T>(std::stoi(str, &last_char_idx));
}
else if (std::is_same<T, short>::value)
{// no dedicated function fot short in std

int check_value = std::stoi(str, &last_char_idx);

if (check_value > std::numeric_limits<short>::max() || check_value < std::numeric_limits<short>::min())
throw std::out_of_range("short");

result = static_cast<T>(check_value);

}
else if (std::is_same<T, unsigned int>::value)
{// no dedicated function in std - unsgined corresponds to 16 bit, and unsigned long corresponds to 32 bit
if (str[0] == '-')
return false;

unsigned long check_value = std::stoul(str, &last_char_idx);

if (check_value > std::numeric_limits<unsigned int>::max())
throw std::out_of_range("unsigned int");

result = static_cast<T>(check_value);

}
else if (std::is_same<T, unsigned short>::value || std::is_same<T, unsigned short>::value)
{ // no dedicated function in std - unsgined corresponds to 16 bit, and unsigned long corresponds to 32 bit
if (str[0] == '-')
return false;

unsigned long check_value = std::stoul(str, &last_char_idx);

if (check_value > std::numeric_limits<unsigned short>::max())
throw std::out_of_range("unsigned short");

result = static_cast<T>(check_value);

}
else
{
return false;
}
}
else if (std::is_floating_point<T>::value)
{
if (std::is_same<T, float>::value)
{
result = static_cast<T>(std::stof(str, &last_char_idx));
if (!std::isfinite((float)result))
return false;
}
else if (std::is_same<T, double>::value)
{
result = static_cast<T>(std::stod(str, &last_char_idx));
if (!std::isfinite((double)result))
return false;
}
else if (std::is_same<T, long double>::value)
{
result = static_cast<T>(std::stold(str, &last_char_idx));
if (!std::isfinite((long double)result))
return false;
}
else
{
return false;
}
}
return str.size() == last_char_idx; // all the chars in the string are converted to the value (thus there are no other chars other than numbers)
}
catch (const std::invalid_argument&)
{
return false;
}
catch (const std::out_of_range&)
{
return false;
}
}
} // namespace string
} // namespace utilities

0 comments on commit 4acd6f1

Please sign in to comment.