diff --git a/CMakeLists.txt b/CMakeLists.txt index 083f9df..acaab0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,18 +23,12 @@ set(sources src/strutils.cpp ) -set(dependencies - fmt -) - idf_component_register( INCLUDE_DIRS src SRCS ${headers} ${sources} - REQUIRES - ${dependencies} ) target_compile_options(${COMPONENT_TARGET} diff --git a/src/arrayview.h b/src/arrayview.h index 1a536b3..609d428 100644 --- a/src/arrayview.h +++ b/src/arrayview.h @@ -33,6 +33,11 @@ struct ArrayView m_begin{begin}, m_end{begin + size} {} + template + constexpr explicit ArrayView(value_type (&array)[N]) noexcept : + m_begin{array}, m_end{array + N} + {} + constexpr ArrayView(const ArrayView &other) noexcept : m_begin{other.m_begin}, m_end{other.m_end} {} diff --git a/src/color_utils.cpp b/src/color_utils.cpp index 2db8c86..f46a3a7 100644 --- a/src/color_utils.cpp +++ b/src/color_utils.cpp @@ -2,14 +2,12 @@ // system includes #include - -// 3rdparty lib includes -#include +#include namespace cpputils { std::string toString(ColorHelper color) { - return fmt::format("#{:02X}{:02X}{:02X}", color.r, color.g, color.b); + return std::format("#{:02X}{:02X}{:02X}", color.r, color.g, color.b); } std::expected parseColor(std::string_view str) @@ -21,13 +19,14 @@ std::expected parseColor(std::string_view str) if (ColorHelper helper; std::sscanf(str.data(), "#%1hhx%1hhx%1hhx", &helper.r, &helper.g, &helper.b) == 3) { - helper.r <<= 4; - helper.g <<= 4; - helper.b <<= 4; + // #F00 -> #FF0000 + helper.r *= 0x11; + helper.g *= 0x11; + helper.b *= 0x11; return helper; } - return std::unexpected(fmt::format("invalid color {}", str)); + return std::unexpected(std::format("invalid color {}", str)); } } // namespace cpputils diff --git a/src/cpptypesafeenum.h b/src/cpptypesafeenum.h index 8606681..ca0b9fc 100644 --- a/src/cpptypesafeenum.h +++ b/src/cpptypesafeenum.h @@ -3,9 +3,7 @@ // system includes #include #include - -// 3rdparty lib includes -#include +#include // local includes #include "cppmacros.h" @@ -13,6 +11,14 @@ // These macros make it possible to define a typesafe enum with parse and // toString methods +namespace typesafeenum { +template +struct iterateEnum; + +template +struct parseEnum; +} + #define DECLARE_TYPESAFE_ENUM_HELPER1(name, ...) name __VA_ARGS__ , #define DECLARE_TYPESAFE_ENUM_HELPER2(name, ...) case TheEnum::name: return #name; #define DECLARE_TYPESAFE_ENUM_HELPER3(name, ...) else if (str == CPP_STRINGIFY(name)) return TheEnum::name; @@ -30,14 +36,14 @@ using TheEnum = Name; \ Values(DECLARE_TYPESAFE_ENUM_HELPER2) \ } \ - return fmt::format("Unknown " #Name "({})", int(value)); \ + return std::format("Unknown " #Name "({})", int(value)); \ } \ inline std::expected parse##Name(std::string_view str) \ { \ using TheEnum = Name; \ if (false) {} \ Values(DECLARE_TYPESAFE_ENUM_HELPER3) \ - return std::unexpected(fmt::format("invalid " #Name " ({})", str)); \ + return std::unexpected(std::format("invalid " #Name " ({})", str)); \ } \ template \ void iterate##Name(T &&cb) \ @@ -45,3 +51,25 @@ using TheEnum = Name; \ Values(DECLARE_TYPESAFE_ENUM_HELPER4) \ } + +#define DECLARE_GLOBAL_TYPESAFE_ENUM(Name, Derivation, Values) \ + DECLARE_TYPESAFE_ENUM(Name, Derivation, Values) \ + namespace typesafeenum { \ + template<> \ + struct iterateEnum { \ + template \ + static void iterate(T&&cb) \ + { \ + return iterate##Name(std::forward(cb)); \ + } \ + }; \ + template<> \ + struct parseEnum { \ + static std::expected parse(std::string_view str) \ + { \ + return parse##Name(str); \ + } \ + }; \ + } + +using namespace typesafeenum; diff --git a/src/numberparsing.h b/src/numberparsing.h index 17205aa..c12e50b 100644 --- a/src/numberparsing.h +++ b/src/numberparsing.h @@ -3,12 +3,10 @@ // system includes #include #include +#include +#include #include #include -#include - -// 3rdparty lib includes -#include namespace cpputils { template std::expected fromString(std::string_view str) = delete; @@ -94,4 +92,20 @@ template<> inline std::expected fromString(std: return std::unexpected(fmt::format("invalid uint64_t {}", str)); return val; } + +template<> inline std::expected fromString(std::string_view str) +{ + float val; + if (std::sscanf(str.data(), "%f", &val) != 1) + return std::unexpected(fmt::format("invalid float {}", str)); + return val; +} + +template<> inline std::expected fromString(std::string_view str) +{ + double val; + if (std::sscanf(str.data(), "%lf", &val) != 1) + return std::unexpected(fmt::format("invalid double {}", str)); + return val; +} } // namespace cpputils diff --git a/src/strutils.cpp b/src/strutils.cpp index 633524e..e872988 100644 --- a/src/strutils.cpp +++ b/src/strutils.cpp @@ -2,10 +2,9 @@ // system includes #include +#include #include -// 3rdparty lib includes -#include namespace cpputils { namespace { @@ -56,7 +55,7 @@ std::expected, std::string> fromHexString(std:: case 'A'...'F': nibbles.nibble0 = c - 'A' + 10; break; case 'a'...'f': nibbles.nibble0 = c - 'a' + 10; break; default: - return std::unexpected(fmt::format("invalid character {} at pos {}", c, std::distance(std::begin(hex), iter))); + return std::unexpected(std::format("invalid character {} at pos {}", c, std::distance(std::begin(hex), iter))); } iter++; @@ -67,7 +66,7 @@ std::expected, std::string> fromHexString(std:: case 'A'...'F': nibbles.nibble1 = c - 'A' + 10; break; case 'a'...'f': nibbles.nibble1 = c - 'a' + 10; break; default: - return std::unexpected(fmt::format("invalid character {} at pos {}", c, std::distance(std::begin(hex), iter))); + return std::unexpected(std::format("invalid character {} at pos {}", c, std::distance(std::begin(hex), iter))); } iter++;