diff --git a/common/adc_utils.h b/common/adc_utils.h index dddb2cc..c06d4bb 100644 --- a/common/adc_utils.h +++ b/common/adc_utils.h @@ -77,12 +77,20 @@ static ValueT AdcFromChars(R&& range) std::string s(rr.begin(), rr.end()); size_t pos; - if constexpr (std::is_same_v) { - v = std::stof(s, &pos); - } else if constexpr (std::is_same_v) { - v = std::stod(s, &pos); - } else if constexpr (std::is_same_v) { - v = std::stold(s, &pos); + try { + if constexpr (std::is_same_v) { + v = std::stof(s, &pos); + } else if constexpr (std::is_same_v) { + v = std::stod(s, &pos); + } else if constexpr (std::is_same_v) { + v = std::stold(s, &pos); + } + } catch (const std::invalid_argument&) { + throw std::invalid_argument( + "AdcFromChars: cannot convert char-range to user-type value (invalid argument)"); + } catch (const std::out_of_range&) { + throw std::invalid_argument( + "AdcFromChars: cannot convert char-range to user-type value (result out of range)"); } if (pos != s.size()) { @@ -274,4 +282,53 @@ static auto AdcCharRangeFromTuple(OutputR& res, const std::tuple& tp, Del } +/* + */ +template +class AdcDefaultSerializer +{ + std::string_view _delimiter; + +public: + template + AdcDefaultSerializer(const DT& delimiter = ",") : _delimiter(delimiter.begin(), delimiter.end()) + { + } + + AdcDefaultSerializer(const char* delimiter = ",") : _delimiter(delimiter) {} + + virtual ~AdcDefaultSerializer() = default; + + template + SerializedT operator()(const T& value) + { + SerializedT res; + + if constexpr (traits::adc_is_tuple_v) { + AdcCharRangeFromTuple(res, value, _delimiter); + } else if constexpr (traits::adc_input_char_range) { + AdcCharRangeFromValueRange(res, value, _delimiter); + } else { + res = AdcTrivialSerializer(value); + } + + return res; + } + + template + AdcDefaultSerializer& setDelimiter(const DT& delimiter) + { + _delimiter = std::string_view{delimiter.begin(), delimiter.end()}; + + return *this; + } + + AdcDefaultSerializer& setDelimiter(const char* delimiter) + { + _delimiter = std::string_view{delimiter}; + + return *this; + } +}; + } // namespace adc::utils diff --git a/tests/adc_valueholder_test.cpp b/tests/adc_valueholder_test.cpp index d7a16df..07b7f0e 100644 --- a/tests/adc_valueholder_test.cpp +++ b/tests/adc_valueholder_test.cpp @@ -121,4 +121,12 @@ TEST_CASE("[ADC VALUEHOLDER]") std::cout << ch; } std::cout << "\n"; + + + ss = ";\t"; + // adc::utils::AdcDefaultSerializer sr{"; "}; + adc::utils::AdcDefaultSerializer sr{ss}; + std::cout << "SR: " << sr(std::list{11.11, 22.22, 33.33}) << "\n"; + ss = ",\t"; + std::cout << "SR: " << sr.setDelimiter(" , ")(std::vector{11.11, 22.22, 33.33}) << "\n"; }