12#ifndef SST_CORE_FROM_STRING_H
13#define SST_CORE_FROM_STRING_H
26#include "sst_complex.h"
31std::enable_if_t<std::is_integral_v<T>, T>
32from_string(
const std::string& input)
34 if constexpr ( std::is_signed_v<T> ) {
35 if constexpr ( std::is_same_v<int, T> ) {
36 return std::stoi(input,
nullptr, 0);
38 else if constexpr ( std::is_same_v<long, T> ) {
39 return std::stol(input,
nullptr, 0);
41 else if constexpr ( std::is_same_v<long long, T> ) {
42 return std::stoll(input,
nullptr, 0);
45 return static_cast<T
>(std::stol(input,
nullptr, 0));
49 if constexpr ( std::is_same_v<bool, T> ) {
51 std::string transform(input);
52 for (
auto& c : transform )
54 if ( transform ==
"true" || transform ==
"t" || transform ==
"yes" || transform ==
"y" ||
55 transform ==
"on" || transform ==
"1" ) {
58 else if ( transform ==
"false" || transform ==
"f" || transform ==
"no" || transform ==
"n" ||
59 transform ==
"off" || transform ==
"0" ) {
63 throw std::invalid_argument(
"from_string: no valid conversion");
66 else if constexpr ( std::is_same_v<unsigned long, T> ) {
67 return std::stoul(input,
nullptr, 0);
69 else if constexpr ( std::is_same_v<unsigned long long, T> ) {
70 return std::stoull(input,
nullptr, 0);
73 return static_cast<T
>(std::stoul(input,
nullptr, 0));
79std::enable_if_t<std::is_floating_point_v<T>, T>
80from_string(
const std::string& input)
82 if constexpr ( std::is_same_v<float, T> ) {
85 else if constexpr ( std::is_same_v<double, T> ) {
88 else if constexpr ( std::is_same_v<long double, T> ) {
92 static_assert(
sizeof(T) == 0,
"from_string(): Unsupported type");
97std::enable_if_t<std::is_class_v<T> && !complex_properties<T>::is_complex, T>
98from_string(
const std::string& input)
100 static_assert(std::is_constructible_v<T, std::string>,
101 "ERROR: from_string can only be used with integral and floating point types and with classes that have a "
102 "constructor that takes a single string as input.\n");
107std::enable_if_t<std::is_enum_v<T>, T>
108from_string(
const std::string& input)
110 return static_cast<T
>(from_string<std::underlying_type_t<T>>(input));
115std::enable_if_t<complex_properties<T>::is_complex, T>
116from_string(
const std::string& input)
118 using REAL =
typename complex_properties<T>::real_t;
124 const char* s = input.c_str();
125 while ( isspace(*s) || *s ==
'(' )
129 if constexpr ( std::is_same_v<float, REAL> )
130 cmplx.real = strtof(s, &e);
131 else if constexpr ( std::is_same_v<double, REAL> )
132 cmplx.real = strtod(s, &e);
133 else if constexpr ( std::is_same_v<long double, REAL> )
134 cmplx.real = strtold(s, &e);
136 static_assert(
sizeof(REAL) == 0,
"complex_from_string(): Unsupported REAL type");
139 while ( isspace(*s) )
143 if constexpr ( std::is_same_v<float, REAL> )
144 cmplx.imag = strtof(s, &e);
145 else if constexpr ( std::is_same_v<double, REAL> )
146 cmplx.imag = strtod(s, &e);
147 else if constexpr ( std::is_same_v<long double, REAL> )
148 cmplx.imag = strtold(s, &e);
150 static_assert(
sizeof(REAL) == 0,
"complex_from_string(): Unsupported REAL type");
154 memcpy(
reinterpret_cast<char*
>(&ret), &cmplx,
sizeof(ret));
162std::enable_if_t<!std::is_enum_v<T> && !complex_properties<T>::is_complex, std::string>
163to_string(
const T& input)
165 if constexpr ( std::is_floating_point_v<T> ) {
166 std::ostringstream s;
167 T abs_val = input < 0 ? -input : input;
168 if ( abs_val > (T)10e6 || abs_val < (T)10e-6 )
169 s << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << input;
171 s << std::fixed << std::setprecision(std::numeric_limits<double>::max_digits10) << input;
174 else if constexpr ( std::is_same_v<T, bool> )
175 return input ?
"true" :
"false";
176 else if constexpr ( std::is_arithmetic_v<T> )
177 return std::to_string(input);
179 return typeid(T).name();
184std::enable_if_t<std::is_enum_v<T>, std::string>
185to_string(
const T& input)
187 return std::to_string(
static_cast<std::underlying_type_t<T>
>(input));
192to_string(std::string s)
199std::enable_if_t<complex_properties<T>::is_complex, std::string>
200to_string(
const T& input)
202 typename complex_properties<T>::real_t cmplx[2];
203 memcpy(cmplx, &input,
sizeof(cmplx));
204 return "(" + to_string(cmplx[0]) +
", " + to_string(cmplx[1]) +
")";