Add wifi, nvs and inplace_function implementations
This commit is contained in:
1
components/util/CMakeLists.txt
Normal file
1
components/util/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
idf_component_register(INCLUDE_DIRS include)
|
||||
122
components/util/include/util/inplace_function.h
Normal file
122
components/util/include/util/inplace_function.h
Normal file
@@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
template <typename func_sig_t, std::size_t storage_size = 8>
|
||||
class inplace_function;
|
||||
|
||||
template <typename return_t, typename... args_t, std::size_t storage_size>
|
||||
class inplace_function<return_t(args_t...), storage_size> {
|
||||
|
||||
using storage_t = std::byte[storage_size];
|
||||
using wrapper_func_t = return_t (*)(storage_t, args_t...);
|
||||
|
||||
public:
|
||||
inplace_function() = default;
|
||||
|
||||
///
|
||||
/// @brief Constructor for function objects.
|
||||
///
|
||||
template <typename F>
|
||||
inplace_function(F f) {
|
||||
bind(f);
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Construct from free function pointer.
|
||||
///
|
||||
template <auto F>
|
||||
static inplace_function construct() {
|
||||
inplace_function<return_t(args_t...)> func;
|
||||
func.template bind<F>();
|
||||
return func;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Construct form member function pointer.
|
||||
///
|
||||
template <auto F, typename class_t>
|
||||
static inplace_function construct(class_t& c) {
|
||||
inplace_function<return_t(args_t...)> func;
|
||||
func.template bind<F>(c);
|
||||
return func;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Construct from function object.
|
||||
///
|
||||
template <typename F>
|
||||
static inplace_function construct(F f) {
|
||||
inplace_function<return_t(args_t...)> func;
|
||||
func.bind(f);
|
||||
return func;
|
||||
}
|
||||
|
||||
return_t operator()(args_t... args) {
|
||||
if (mWrapper)
|
||||
mWrapper(mStorage, args...);
|
||||
else
|
||||
throw std::bad_function_call();
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return !(mWrapper == nullptr);
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Bind a free function.
|
||||
///
|
||||
/// @tparam F Pointer to free function
|
||||
///
|
||||
template <auto F>
|
||||
requires std::is_invocable_r_v<return_t, decltype(F), args_t...>
|
||||
void bind() {
|
||||
mWrapper = [](storage_t, args_t... args) {
|
||||
std::invoke(F, std::forward<args_t>(args)...);
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Bind a member function.
|
||||
///
|
||||
/// @tparam class_t Class the member belongs to.
|
||||
/// @param c Reference to object the member function should be called on.
|
||||
/// @tparam F Member function pointer.
|
||||
///
|
||||
template <auto F, typename class_t>
|
||||
requires std::is_invocable_r_v<return_t, decltype(F), class_t&,
|
||||
args_t...> &&
|
||||
(sizeof(class_t*) <= storage_size)
|
||||
void bind(class_t& c) {
|
||||
new (mStorage)(class_t*){&c};
|
||||
|
||||
mWrapper = [](storage_t storage, args_t... args) {
|
||||
std::invoke(F, reinterpret_cast<class_t*>(storage),
|
||||
std::forward<args_t>(args)...);
|
||||
};
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Bind a function object.
|
||||
///
|
||||
template <typename F>
|
||||
requires std::is_invocable_r_v<return_t, F, args_t...> &&
|
||||
(sizeof(F) <= storage_size) &&
|
||||
std::is_trivially_destructible_v<F>
|
||||
void bind(F f) {
|
||||
new (mStorage) F{std::move(f)};
|
||||
mWrapper = [](storage_t storage, args_t... args) {
|
||||
std::invoke(*reinterpret_cast<F*>(storage),
|
||||
std::forward<args_t>(args)...);
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
storage_t mStorage;
|
||||
wrapper_func_t mWrapper = nullptr;
|
||||
};
|
||||
Reference in New Issue
Block a user