Sync from fork #2
@ -23,18 +23,12 @@ set(sources
|
|||||||
src/strutils.cpp
|
src/strutils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(dependencies
|
|
||||||
fmt
|
|
||||||
)
|
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
INCLUDE_DIRS
|
INCLUDE_DIRS
|
||||||
src
|
src
|
||||||
SRCS
|
SRCS
|
||||||
${headers}
|
${headers}
|
||||||
${sources}
|
${sources}
|
||||||
REQUIRES
|
|
||||||
${dependencies}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(${COMPONENT_TARGET}
|
target_compile_options(${COMPONENT_TARGET}
|
||||||
|
@ -33,6 +33,11 @@ struct ArrayView
|
|||||||
m_begin{begin}, m_end{begin + size}
|
m_begin{begin}, m_end{begin + size}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
constexpr explicit ArrayView(value_type (&array)[N]) noexcept :
|
||||||
|
m_begin{array}, m_end{array + N}
|
||||||
|
{}
|
||||||
|
|
||||||
constexpr ArrayView(const ArrayView &other) noexcept :
|
constexpr ArrayView(const ArrayView &other) noexcept :
|
||||||
m_begin{other.m_begin}, m_end{other.m_end}
|
m_begin{other.m_begin}, m_end{other.m_end}
|
||||||
{}
|
{}
|
||||||
|
@ -2,14 +2,12 @@
|
|||||||
|
|
||||||
// system includes
|
// system includes
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <format>
|
||||||
// 3rdparty lib includes
|
|
||||||
#include <fmt/core.h>
|
|
||||||
|
|
||||||
namespace cpputils {
|
namespace cpputils {
|
||||||
std::string toString(ColorHelper color)
|
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<ColorHelper, std::string> parseColor(std::string_view str)
|
std::expected<ColorHelper, std::string> parseColor(std::string_view str)
|
||||||
@ -21,13 +19,14 @@ std::expected<ColorHelper, std::string> parseColor(std::string_view str)
|
|||||||
|
|
||||||
if (ColorHelper helper; std::sscanf(str.data(), "#%1hhx%1hhx%1hhx", &helper.r, &helper.g, &helper.b) == 3)
|
if (ColorHelper helper; std::sscanf(str.data(), "#%1hhx%1hhx%1hhx", &helper.r, &helper.g, &helper.b) == 3)
|
||||||
{
|
{
|
||||||
helper.r <<= 4;
|
// #F00 -> #FF0000
|
||||||
helper.g <<= 4;
|
helper.r *= 0x11;
|
||||||
helper.b <<= 4;
|
helper.g *= 0x11;
|
||||||
|
helper.b *= 0x11;
|
||||||
return helper;
|
return helper;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::unexpected(fmt::format("invalid color {}", str));
|
return std::unexpected(std::format("invalid color {}", str));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace cpputils
|
} // namespace cpputils
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
// system includes
|
// system includes
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <expected>
|
#include <expected>
|
||||||
|
#include <format>
|
||||||
// 3rdparty lib includes
|
|
||||||
#include <fmt/core.h>
|
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
#include "cppmacros.h"
|
#include "cppmacros.h"
|
||||||
@ -13,6 +11,14 @@
|
|||||||
// These macros make it possible to define a typesafe enum with parse and
|
// These macros make it possible to define a typesafe enum with parse and
|
||||||
// toString methods
|
// toString methods
|
||||||
|
|
||||||
|
namespace typesafeenum {
|
||||||
|
template<typename T>
|
||||||
|
struct iterateEnum;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct parseEnum;
|
||||||
|
}
|
||||||
|
|
||||||
#define DECLARE_TYPESAFE_ENUM_HELPER1(name, ...) name __VA_ARGS__ ,
|
#define DECLARE_TYPESAFE_ENUM_HELPER1(name, ...) name __VA_ARGS__ ,
|
||||||
#define DECLARE_TYPESAFE_ENUM_HELPER2(name, ...) case TheEnum::name: return #name;
|
#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;
|
#define DECLARE_TYPESAFE_ENUM_HELPER3(name, ...) else if (str == CPP_STRINGIFY(name)) return TheEnum::name;
|
||||||
@ -30,14 +36,14 @@
|
|||||||
using TheEnum = Name; \
|
using TheEnum = Name; \
|
||||||
Values(DECLARE_TYPESAFE_ENUM_HELPER2) \
|
Values(DECLARE_TYPESAFE_ENUM_HELPER2) \
|
||||||
} \
|
} \
|
||||||
return fmt::format("Unknown " #Name "({})", int(value)); \
|
return std::format("Unknown " #Name "({})", int(value)); \
|
||||||
} \
|
} \
|
||||||
inline std::expected<Name, std::string> parse##Name(std::string_view str) \
|
inline std::expected<Name, std::string> parse##Name(std::string_view str) \
|
||||||
{ \
|
{ \
|
||||||
using TheEnum = Name; \
|
using TheEnum = Name; \
|
||||||
if (false) {} \
|
if (false) {} \
|
||||||
Values(DECLARE_TYPESAFE_ENUM_HELPER3) \
|
Values(DECLARE_TYPESAFE_ENUM_HELPER3) \
|
||||||
return std::unexpected(fmt::format("invalid " #Name " ({})", str)); \
|
return std::unexpected(std::format("invalid " #Name " ({})", str)); \
|
||||||
} \
|
} \
|
||||||
template<typename T> \
|
template<typename T> \
|
||||||
void iterate##Name(T &&cb) \
|
void iterate##Name(T &&cb) \
|
||||||
@ -45,3 +51,25 @@
|
|||||||
using TheEnum = Name; \
|
using TheEnum = Name; \
|
||||||
Values(DECLARE_TYPESAFE_ENUM_HELPER4) \
|
Values(DECLARE_TYPESAFE_ENUM_HELPER4) \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DECLARE_GLOBAL_TYPESAFE_ENUM(Name, Derivation, Values) \
|
||||||
|
DECLARE_TYPESAFE_ENUM(Name, Derivation, Values) \
|
||||||
|
namespace typesafeenum { \
|
||||||
|
template<> \
|
||||||
|
struct iterateEnum<Name> { \
|
||||||
|
template<typename T> \
|
||||||
|
static void iterate(T&&cb) \
|
||||||
|
{ \
|
||||||
|
return iterate##Name(std::forward<T>(cb)); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template<> \
|
||||||
|
struct parseEnum<Name> { \
|
||||||
|
static std::expected<Name, std::string> parse(std::string_view str) \
|
||||||
|
{ \
|
||||||
|
return parse##Name(str); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace typesafeenum;
|
||||||
|
@ -3,12 +3,10 @@
|
|||||||
// system includes
|
// system includes
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <expected>
|
||||||
|
#include <format>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <expected>
|
|
||||||
|
|
||||||
// 3rdparty lib includes
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
namespace cpputils {
|
namespace cpputils {
|
||||||
template<typename T> std::expected<T, std::string> fromString(std::string_view str) = delete;
|
template<typename T> std::expected<T, std::string> fromString(std::string_view str) = delete;
|
||||||
@ -94,4 +92,20 @@ template<> inline std::expected<uint64_t, std::string> fromString<uint64_t>(std:
|
|||||||
return std::unexpected(fmt::format("invalid uint64_t {}", str));
|
return std::unexpected(fmt::format("invalid uint64_t {}", str));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> inline std::expected<float, std::string> fromString<float>(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<double, std::string> fromString<double>(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
|
} // namespace cpputils
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
// system includes
|
// system includes
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <format>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
// 3rdparty lib includes
|
|
||||||
#include <fmt/core.h>
|
|
||||||
|
|
||||||
namespace cpputils {
|
namespace cpputils {
|
||||||
namespace {
|
namespace {
|
||||||
@ -56,7 +55,7 @@ std::expected<std::basic_string<unsigned char>, std::string> fromHexString(std::
|
|||||||
case 'A'...'F': nibbles.nibble0 = c - 'A' + 10; break;
|
case 'A'...'F': nibbles.nibble0 = c - 'A' + 10; break;
|
||||||
case 'a'...'f': nibbles.nibble0 = c - 'a' + 10; break;
|
case 'a'...'f': nibbles.nibble0 = c - 'a' + 10; break;
|
||||||
default:
|
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++;
|
iter++;
|
||||||
@ -67,7 +66,7 @@ std::expected<std::basic_string<unsigned char>, std::string> fromHexString(std::
|
|||||||
case 'A'...'F': nibbles.nibble1 = c - 'A' + 10; break;
|
case 'A'...'F': nibbles.nibble1 = c - 'A' + 10; break;
|
||||||
case 'a'...'f': nibbles.nibble1 = c - 'a' + 10; break;
|
case 'a'...'f': nibbles.nibble1 = c - 'a' + 10; break;
|
||||||
default:
|
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++;
|
iter++;
|
||||||
|
Reference in New Issue
Block a user