From 471b524df2fd75747c3429ea0f22004c5448bb4b Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Thu, 4 Feb 2021 01:57:20 +0100 Subject: [PATCH] Made this lib compatible with esp-idf components system --- CMakeLists.txt | 15 ++ cleanuphelper.h | 36 --- delayedconstruction.h | 99 -------- espflags.h | 114 --------- esputils.h | 232 ------------------ .../binary_semaphore.h | 4 +- .../counting_semaphore.h | 4 +- esprandom.h => include/esprandom.h | 5 +- event_group.h => include/event_group.h | 4 +- http_client.h => include/http_client.h | 4 +- lockhelper.h => include/lockhelper.h | 4 +- lockingqueue.h => include/lockingqueue.h | 1 - .../mutex_semaphore.h | 4 +- .../recursive_mutex_semaphore.h | 4 +- .../recursivelockhelper.h | 4 +- .../websocket_client.h | 4 +- 16 files changed, 36 insertions(+), 502 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 cleanuphelper.h delete mode 100644 delayedconstruction.h delete mode 100644 espflags.h delete mode 100644 esputils.h rename binary_semaphore.h => include/binary_semaphore.h (91%) rename counting_semaphore.h => include/counting_semaphore.h (92%) rename esprandom.h => include/esprandom.h (86%) rename event_group.h => include/event_group.h (94%) rename http_client.h => include/http_client.h (98%) rename lockhelper.h => include/lockhelper.h (93%) rename lockingqueue.h => include/lockingqueue.h (98%) rename mutex_semaphore.h => include/mutex_semaphore.h (91%) rename recursive_mutex_semaphore.h => include/recursive_mutex_semaphore.h (91%) rename recursivelockhelper.h => include/recursivelockhelper.h (92%) rename websocket_client.h => include/websocket_client.h (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..344e014 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +set(headers + include/binary_semaphore.h + include/counting_semaphore.h + include/esprandom.h + include/event_group.h + include/http_client.h + include/lockhelper.h + include/lockingqueue.h + include/mutex_semaphore.h + include/recursivelockhelper.h + include/recursive_mutex_semaphore.h + include/websocket_client.h +) + +idf_component_register(INCLUDE_DIRS include SRCS ${headers} REQUIRES freertos esp_system esp_http_client esp_websocket_client cpputils) diff --git a/cleanuphelper.h b/cleanuphelper.h deleted file mode 100644 index 5f1237f..0000000 --- a/cleanuphelper.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -// system includes -#include -#include - -namespace espcpputils { -template -class CleanupHelper -{ -public: - CleanupHelper(T && cleanup) : - m_cleanup{std::move(cleanup)} - {} - - ~CleanupHelper() - { - if (m_cleanup) - (*m_cleanup)(); - } - - void disarm() - { - m_cleanup = std::nullopt; - } - -private: - std::optional m_cleanup; -}; - -template -CleanupHelper makeCleanupHelper(T && cleanup) -{ - return CleanupHelper(std::move(cleanup)); -} -} // namespace espcpputils diff --git a/delayedconstruction.h b/delayedconstruction.h deleted file mode 100644 index e14dda3..0000000 --- a/delayedconstruction.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -// system includes -#include -#include -#include - -// local includes -#include "esputils.h" - -namespace espcpputils { -template -class DelayedConstruction -{ - ESP_DISABLE_COPY_MOVE(DelayedConstruction) - -public: - DelayedConstruction() = default; - ~DelayedConstruction() - { - if (m_constructed) - destruct(); - } - - template - void construct(Targs &&...args) - { - assert(!m_constructed); - new (&helper.value) T {std::forward(args)...}; - m_constructed = true; - } - - void destruct() - { - assert(m_constructed); - helper.value.~T(); - m_constructed = false; - } - - T &get() - { - assert(m_constructed); - return helper.value; - } - - const T &get() const - { - assert(m_constructed); - return helper.value; - } - - T *operator->() - { - assert(m_constructed); - return &helper.value; - } - - const T *operator->() const - { - assert(m_constructed); - return &helper.value; - } - - T &operator*() - { - assert(m_constructed); - return helper.value; - } - - const T &operator*() const - { - assert(m_constructed); - return helper.value; - } - - //! allows for getting the address before the object has been constructed - T &getUnsafe() - { - return helper.value; - } - - //! allows for getting the address before the object has been constructed - const T &getUnsafe() const - { - return helper.value; - } - - bool constructed() const { return m_constructed; } - -private: - bool m_constructed{}; - union Helper - { - Helper() {} - ~Helper() {} - T value; - } helper; -}; -} // namespace espcpputils diff --git a/espflags.h b/espflags.h deleted file mode 100644 index 29012f8..0000000 --- a/espflags.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -// system includes -#include -#include -#include -#include - -namespace espcpputils { -class EspFlag -{ - using uint = unsigned int; - using ushort = unsigned short; - - int i; -public: - constexpr inline EspFlag(int value) noexcept : i(value) {} - constexpr inline operator int() const noexcept { return i; } - - constexpr inline EspFlag(uint value) noexcept : i(int(value)) {} - constexpr inline EspFlag(short value) noexcept : i(int(value)) {} - constexpr inline EspFlag(ushort value) noexcept : i(int(uint(value))) {} - constexpr inline operator uint() const noexcept { return uint(i); } -}; - -template -class EspFlags -{ - static_assert((sizeof(Enum) <= sizeof(int)), - "EspFlags uses an int as storage, so an enum with underlying " - "long long will overflow."); - static_assert((std::is_enum::value), "EspFlags is only usable on enumeration types."); - - using uint = unsigned int; - using ushort = unsigned short; - -public: - typedef typename std::conditional< - std::is_unsigned::type>::value, - unsigned int, - signed int - >::type Int; - - typedef Enum enum_type; - - constexpr inline EspFlags() noexcept : i(0) {} - constexpr inline EspFlags(Enum flags) noexcept : i(Int(flags)) {} - - constexpr inline EspFlags(EspFlag flag) noexcept : i(flag) {} - - constexpr inline EspFlags(std::initializer_list flags) noexcept - : i(initializer_list_helper(flags.begin(), flags.end())) {} - - constexpr inline EspFlags &operator&=(int mask) noexcept { i &= mask; return *this; } - constexpr inline EspFlags &operator&=(uint mask) noexcept { i &= mask; return *this; } - constexpr inline EspFlags &operator&=(Enum mask) noexcept { i &= Int(mask); return *this; } - constexpr inline EspFlags &operator|=(EspFlags other) noexcept { i |= other.i; return *this; } - constexpr inline EspFlags &operator|=(Enum other) noexcept { i |= Int(other); return *this; } - constexpr inline EspFlags &operator^=(EspFlags other) noexcept { i ^= other.i; return *this; } - constexpr inline EspFlags &operator^=(Enum other) noexcept { i ^= Int(other); return *this; } - - constexpr inline operator Int() const noexcept { return i; } - - constexpr inline EspFlags operator|(EspFlags other) const noexcept { return EspFlags(EspFlag(i | other.i)); } - constexpr inline EspFlags operator|(Enum other) const noexcept { return EspFlags(EspFlag(i | Int(other))); } - constexpr inline EspFlags operator^(EspFlags other) const noexcept { return EspFlags(EspFlag(i ^ other.i)); } - constexpr inline EspFlags operator^(Enum other) const noexcept { return EspFlags(EspFlag(i ^ Int(other))); } - constexpr inline EspFlags operator&(int mask) const noexcept { return EspFlags(EspFlag(i & mask)); } - constexpr inline EspFlags operator&(uint mask) const noexcept { return EspFlags(EspFlag(i & mask)); } - constexpr inline EspFlags operator&(Enum other) const noexcept { return EspFlags(EspFlag(i & Int(other))); } - constexpr inline EspFlags operator~() const noexcept { return EspFlags(EspFlag(~i)); } - - constexpr inline bool operator!() const noexcept { return !i; } - - constexpr inline bool testFlag(Enum flag) const noexcept { return (i & Int(flag)) == Int(flag) && (Int(flag) != 0 || i == Int(flag) ); } - constexpr inline EspFlags &setFlag(Enum flag, bool on = true) noexcept - { - return on ? (*this |= flag) : (*this &= ~Int(flag)); - } - -private: - constexpr static inline Int initializer_list_helper(typename std::initializer_list::const_iterator it, - typename std::initializer_list::const_iterator end) - noexcept - { - return (it == end ? Int(0) : (Int(*it) | initializer_list_helper(it + 1, end))); - } - - Int i; -}; - -class EspIncompatibleFlag -{ - int i; -public: - constexpr inline explicit EspIncompatibleFlag(int i) noexcept; - constexpr inline operator int() const noexcept { return i; } -}; - -constexpr inline EspIncompatibleFlag::EspIncompatibleFlag(int value) noexcept : i(value) {} -} // namespace espcpputils - -#define ESP_DECLARE_FLAGS(Flags, Enum)\ -typedef ::espcpputils::EspFlags Flags; - -#define ESP_DECLARE_INCOMPATIBLE_FLAGS(Flags) \ -constexpr inline ::espcpputils::EspIncompatibleFlag operator|(Flags::enum_type f1, int f2) noexcept \ -{ return ::espcpputils::EspIncompatibleFlag(int(f1) | f2); } - -#define ESP_DECLARE_OPERATORS_FOR_FLAGS(Flags) \ -constexpr inline ::espcpputils::EspFlags operator|(Flags::enum_type f1, Flags::enum_type f2) noexcept \ -{ return ::espcpputils::EspFlags(f1) | f2; } \ -constexpr inline ::espcpputils::EspFlags operator|(Flags::enum_type f1, ::espcpputils::EspFlags f2) noexcept \ -{ return f2 | f1; } ESP_DECLARE_INCOMPATIBLE_FLAGS(Flags) diff --git a/esputils.h b/esputils.h deleted file mode 100644 index ede3b7b..0000000 --- a/esputils.h +++ /dev/null @@ -1,232 +0,0 @@ -#pragma once - -// system includes -#include -#include -#include -#include -#include -#include -#include - -/* - Avoid "unused parameter" warnings -*/ -#define ESP_UNUSED(x) (void)x; - -/* These two macros make it possible to turn the builtin line expander into a - * string literal. */ -#define ESP_STRINGIFY2(x) #x -#define ESP_STRINGIFY(x) ESP_STRINGIFY2(x) - -/* - Some classes do not permit copies to be made of an object. These - classes contains a private copy constructor and assignment - operator to disable copying (the compiler gives an error message). -*/ -#define ESP_DISABLE_COPY(Class) \ - Class(const Class &) = delete;\ - Class &operator=(const Class &) = delete; -#define ESP_DISABLE_MOVE(Class) \ - Class(Class &&) = delete; \ - Class &operator=(Class &&) = delete; -#define ESP_DISABLE_COPY_MOVE(Class) \ - ESP_DISABLE_COPY(Class) \ - ESP_DISABLE_MOVE(Class) - - -/* These two macros make it possible to define a typesafe enum with parse and - * toString methods */ -#define DECLARE_TYPESAFE_ENUM_HELPER1(name) name, -#define DECLARE_TYPESAFE_ENUM_HELPER2(name) case TheEnum::name: return #name; -#define DECLARE_TYPESAFE_ENUM_HELPER3(name) else if (str == ESP_STRINGIFY(name)) return TheEnum::name; - -#define DECLARE_TYPESAFE_ENUM(Name, Derivation, Values) \ - enum class Name Derivation \ - { \ - Values(DECLARE_TYPESAFE_ENUM_HELPER1) \ - }; \ - std::string toString(Name value); \ - std::optional parse##Name(std::string_view str); - -#define IMPLEMENT_TYPESAFE_ENUM(Name, Derivation, Values) \ - std::string toString(Name value) \ - { \ - switch (value) \ - { \ - using TheEnum = Name; \ - Values(DECLARE_TYPESAFE_ENUM_HELPER2) \ - } \ - return std::string{"Unknown " #Name "("} + std::to_string(int(value)) + ')'; \ - } \ - std::optional parse##Name(std::string_view str) \ - { \ - using TheEnum = Name; \ - if (false) {} \ - Values(DECLARE_TYPESAFE_ENUM_HELPER3) \ - return std::nullopt; \ - } - -namespace espcpputils { - -template -class Signal -{ -public: - using Slot = std::function; - - Signal &operator+=(Slot &&slot) - { - m_slots.emplace_back(std::move(slot)); - return *this; - } - - Signal &operator+=(const Slot &slot) - { - m_slots.emplace_back(slot); - return *this; - } - - template - void operator()(Targs && ...args) const - { - for (const auto &slot : m_slots) - slot(std::forward(args)...); - } - -private: - std::vector m_slots; -}; - -namespace literals { -namespace { -/** - * User-defined Literals - * usage: - * - * uint32_t = test = 10_MHz; // --> 10000000 - */ - -constexpr unsigned long long operator"" _kHz(unsigned long long x) -{ - return x * 1000; -} - -constexpr unsigned long long operator"" _MHz(unsigned long long x) -{ - return x * 1000 * 1000; -} - -constexpr unsigned long long operator"" _GHz(unsigned long long x) -{ - return x * 1000 * 1000 * 1000; -} - -constexpr unsigned long long operator"" _kBit(unsigned long long x) -{ - return x * 1024; -} - -constexpr unsigned long long operator"" _MBit(unsigned long long x) -{ - return x * 1024 * 1024; -} - -constexpr unsigned long long operator"" _GBit(unsigned long long x) -{ - return x * 1024 * 1024 * 1024; -} - -constexpr unsigned long long operator"" _kB(unsigned long long x) -{ - return x * 1024; -} - -constexpr unsigned long long operator"" _MB(unsigned long long x) -{ - return x * 1024 * 1024; -} - -constexpr unsigned long long operator"" _GB(unsigned long long x) -{ - return x * 1024 * 1024 * 1024; -} -} // namespace -} // namespace literals - -namespace { -template -T vmin(T&&t) -{ - return std::forward(t); -} - -template -typename std::common_type::type vmin(T0&& val1, T1&& val2, Ts&&... vs) -{ - if (val1 < val2) - return vmin(val1, std::forward(vs)...); - else - return vmin(val2, std::forward(vs)...); -} - -template -constexpr const T& clamp( const T& v, const T& lo, const T& hi ) -{ - // assert( !(hi < lo) ); - return (v < lo) ? lo : (hi < v) ? hi : v; -} - -template -T mapValue(T x, T in_min, T in_max, T out_min, T out_max) -{ - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - -template -struct EspNonConstOverload -{ - template - constexpr auto operator()(R (T::*ptr)(Args...)) const noexcept -> decltype(ptr) - { return ptr; } - template - static constexpr auto of(R (T::*ptr)(Args...)) noexcept -> decltype(ptr) - { return ptr; } -}; -template -struct EspConstOverload -{ - template - constexpr auto operator()(R (T::*ptr)(Args...) const) const noexcept -> decltype(ptr) - { return ptr; } - template - static constexpr auto of(R (T::*ptr)(Args...) const) noexcept -> decltype(ptr) - { return ptr; } -}; -template -struct EspOverload : EspConstOverload, EspNonConstOverload -{ - using EspConstOverload::of; - using EspConstOverload::operator(); - using EspNonConstOverload::of; - using EspNonConstOverload::operator(); - template - constexpr auto operator()(R (*ptr)(Args...)) const noexcept -> decltype(ptr) - { return ptr; } - template - static constexpr auto of(R (*ptr)(Args...)) noexcept -> decltype(ptr) - { return ptr; } -}; - -template constexpr __attribute__((__unused__)) EspOverload espOverload = {}; -template constexpr __attribute__((__unused__)) EspConstOverload espConstOverload = {}; -template constexpr __attribute__((__unused__)) EspNonConstOverload espNonConstOverload = {}; - -template -bool is_in(First &&first, T && ... t) -{ - return ((first == t) || ...); -} - -} // namespace -} // namespace espcpputils diff --git a/binary_semaphore.h b/include/binary_semaphore.h similarity index 91% rename from binary_semaphore.h rename to include/binary_semaphore.h index 56b9d5e..4f56f69 100644 --- a/binary_semaphore.h +++ b/include/binary_semaphore.h @@ -6,12 +6,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class binary_semaphore { - ESP_DISABLE_COPY_MOVE(binary_semaphore) + CPP_DISABLE_COPY_MOVE(binary_semaphore) public: binary_semaphore() : diff --git a/counting_semaphore.h b/include/counting_semaphore.h similarity index 92% rename from counting_semaphore.h rename to include/counting_semaphore.h index 9c7d408..6518c6e 100644 --- a/counting_semaphore.h +++ b/include/counting_semaphore.h @@ -6,12 +6,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class counting_semaphore { - ESP_DISABLE_COPY_MOVE(counting_semaphore) + CPP_DISABLE_COPY_MOVE(counting_semaphore) public: counting_semaphore(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount) : diff --git a/esprandom.h b/include/esprandom.h similarity index 86% rename from esprandom.h rename to include/esprandom.h index ff6d3f1..c4e72d1 100644 --- a/esprandom.h +++ b/include/esprandom.h @@ -3,6 +3,7 @@ // system includes #include #include +#include // esp-idf includes #include @@ -24,14 +25,14 @@ public: std::string randomString(std::size_t length) { - static constexpr auto chars = + static constexpr const char chars[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; auto rng = esp_random_device{}; - auto dist = std::uniform_int_distribution{{}, std::strlen(chars) - 1}; + auto dist = std::uniform_int_distribution{{}, std::size(chars) - 1}; auto result = std::string(length, '\0'); std::generate_n(std::begin(result), length, [&]() { return chars[dist(rng)]; }); diff --git a/event_group.h b/include/event_group.h similarity index 94% rename from event_group.h rename to include/event_group.h index 554f28c..f86efad 100644 --- a/event_group.h +++ b/include/event_group.h @@ -5,12 +5,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class event_group { - ESP_DISABLE_COPY_MOVE(event_group) + CPP_DISABLE_COPY_MOVE(event_group) public: event_group() : diff --git a/http_client.h b/include/http_client.h similarity index 98% rename from http_client.h rename to include/http_client.h index 1b9368d..3272da7 100644 --- a/http_client.h +++ b/include/http_client.h @@ -4,12 +4,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class http_client { - ESP_DISABLE_COPY_MOVE(http_client) + CPP_DISABLE_COPY_MOVE(http_client) public: http_client(const esp_http_client_config_t *config) : diff --git a/lockhelper.h b/include/lockhelper.h similarity index 93% rename from lockhelper.h rename to include/lockhelper.h index a2e0e2b..e829967 100644 --- a/lockhelper.h +++ b/include/lockhelper.h @@ -5,12 +5,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class LockHelper { - ESP_DISABLE_COPY_MOVE(LockHelper) + CPP_DISABLE_COPY_MOVE(LockHelper) public: LockHelper(QueueHandle_t _xMutex, TickType_t xTicksToWait=portMAX_DELAY) : diff --git a/lockingqueue.h b/include/lockingqueue.h similarity index 98% rename from lockingqueue.h rename to include/lockingqueue.h index 11242c0..35b4c75 100644 --- a/lockingqueue.h +++ b/include/lockingqueue.h @@ -9,7 +9,6 @@ #include // local includes -#include "esputils.h" #include "delayedconstruction.h" #include "recursive_mutex_semaphore.h" #include "recursivelockhelper.h" diff --git a/mutex_semaphore.h b/include/mutex_semaphore.h similarity index 91% rename from mutex_semaphore.h rename to include/mutex_semaphore.h index a72008e..d7519ac 100644 --- a/mutex_semaphore.h +++ b/include/mutex_semaphore.h @@ -6,12 +6,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class mutex_semaphore { - ESP_DISABLE_COPY_MOVE(mutex_semaphore) + CPP_DISABLE_COPY_MOVE(mutex_semaphore) public: mutex_semaphore() : diff --git a/recursive_mutex_semaphore.h b/include/recursive_mutex_semaphore.h similarity index 91% rename from recursive_mutex_semaphore.h rename to include/recursive_mutex_semaphore.h index a6a34ba..4f2a156 100644 --- a/recursive_mutex_semaphore.h +++ b/include/recursive_mutex_semaphore.h @@ -6,12 +6,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class recursive_mutex_semaphore { - ESP_DISABLE_COPY_MOVE(recursive_mutex_semaphore) + CPP_DISABLE_COPY_MOVE(recursive_mutex_semaphore) public: recursive_mutex_semaphore() : diff --git a/recursivelockhelper.h b/include/recursivelockhelper.h similarity index 92% rename from recursivelockhelper.h rename to include/recursivelockhelper.h index c522c88..f9136d8 100644 --- a/recursivelockhelper.h +++ b/include/recursivelockhelper.h @@ -5,12 +5,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class RecursiveLockHelper { - ESP_DISABLE_COPY_MOVE(RecursiveLockHelper) + CPP_DISABLE_COPY_MOVE(RecursiveLockHelper) public: RecursiveLockHelper(QueueHandle_t _xMutex, TickType_t xTicksToWait=portMAX_DELAY) : diff --git a/websocket_client.h b/include/websocket_client.h similarity index 96% rename from websocket_client.h rename to include/websocket_client.h index 5c4af51..3fc155e 100644 --- a/websocket_client.h +++ b/include/websocket_client.h @@ -4,12 +4,12 @@ #include // local includes -#include "esputils.h" +#include "cppmacros.h" namespace espcpputils { class websocket_client { - ESP_DISABLE_COPY_MOVE(websocket_client) + CPP_DISABLE_COPY_MOVE(websocket_client) public: websocket_client(const esp_websocket_client_config_t &config) :