1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-12 16:22:22 +01:00

Introduce parse_number() helper function (#2659)

This commit is contained in:
Oxan van Leeuwen
2021-11-10 19:15:06 +01:00
committed by GitHub
parent 219b225ac0
commit 15f9677d33
15 changed files with 70 additions and 36 deletions

View File

@@ -1,5 +1,7 @@
#pragma once
#include <cmath>
#include <string>
#include <functional>
#include <vector>
@@ -51,8 +53,6 @@ std::string to_string(unsigned long long val); // NOLINT
std::string to_string(float val);
std::string to_string(double val);
std::string to_string(long double val);
optional<float> parse_float(const std::string &str);
optional<int> parse_int(const std::string &str);
optional<int> parse_hex(const std::string &str, size_t start, size_t length);
optional<int> parse_hex(char chr);
/// Sanitize the hostname by removing characters that are not in the allowlist and truncating it to 63 chars.
@@ -304,4 +304,52 @@ template<typename T> T *new_buffer(size_t length) {
return buffer;
}
// ---------------------------------------------------------------------------------------------------------------------
/// @name Parsing & formatting
///@{
/// Parse a unsigned decimal number.
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value), int> = 0>
optional<T> parse_number(const char *str, size_t len) {
char *end = nullptr;
unsigned long value = ::strtoul(str, &end, 10); // NOLINT(google-runtime-int)
if (end == nullptr || end != str + len || value > std::numeric_limits<T>::max())
return {};
return value;
}
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value), int> = 0>
optional<T> parse_number(const std::string &str) {
return parse_number<T>(str.c_str(), str.length());
}
/// Parse a signed decimal number.
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value), int> = 0>
optional<T> parse_number(const char *str, size_t len) {
char *end = nullptr;
signed long value = ::strtol(str, &end, 10); // NOLINT(google-runtime-int)
if (end == nullptr || end != str + len || value < std::numeric_limits<T>::min() ||
value > std::numeric_limits<T>::max())
return {};
return value;
}
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value), int> = 0>
optional<T> parse_number(const std::string &str) {
return parse_number<T>(str.c_str(), str.length());
}
/// Parse a decimal floating-point number.
template<typename T, enable_if_t<(std::is_same<T, float>::value), int> = 0>
optional<T> parse_number(const char *str, size_t len) {
char *end = nullptr;
float value = ::strtof(str, &end);
if (end == nullptr || end != str + len || value == HUGE_VALF)
return {};
return value;
}
template<typename T, enable_if_t<(std::is_same<T, float>::value), int> = 0>
optional<T> parse_number(const std::string &str) {
return parse_number<T>(str.c_str(), str.length());
}
///@}
} // namespace esphome