Add handle wrapper class

This commit is contained in:
Henrik Stickann 2022-12-02 16:41:56 +01:00
parent 15f79b0446
commit 94a3d1981e
2 changed files with 120 additions and 0 deletions

View File

@ -0,0 +1,74 @@
#ifndef STA_RTOS_HANDLE_HPP
#define STA_RTOS_HANDLE_HPP
#include <type_traits>
namespace sta
{
/**
* @brief Helper for managing access to RTOS handles.
*
* @tparam T CMSIS RTOS2 handle type
*
* @ingroup STA_RTOS_API
*/
template <typename T>
class RtosHandle
{
public:
using handle_type = T; /**< Handle type */
// TODO Support integer type with sizeof(T) == sizeof(void *)
static_assert(std::is_same<handle_type, void *>::value, "Only compatible with void * handle types");
/**
* @brief Helper type for deferred handle evaluation.
*/
struct Deferred
{
handle_type * pointer;
/**
* @brief Construct from handle address.
*
* @param handlePointer Handle variable address
*/
Deferred(handle_type * handlePointer);
};
public:
/**
* @brief Construct handle from value.
*
* @param handle Handle value
*/
RtosHandle(handle_type handle);
/**
* @brief Construct handle with deferred evaluation.
*
* @param handle Handle variable address
*/
RtosHandle(Deferred handle);
/**
* @brief Access handle value.
*
* If the deferred ctor was used the handle value is
* evaluated on the first call to this method.
*
* @return Handle value
*/
handle_type get();
private:
handle_type handle_; /**< Handle value or variable address */
bool deferred_; /**< Is handle evaluation deferred */
};
} // namespace sta
#include <sta/rtos/handle.tpp>
#endif // STA_RTOS_HANDLE_HPP

View File

@ -0,0 +1,46 @@
#ifndef STA_RTOS_HANDLE_TPP
#define STA_RTOS_HANDLE_TPP
#ifndef STA_RTOS_HANDLE_HPP
# error "Internal header. Use <sta/rtos/handle.hpp> instead."
#endif // !STA_RTOS_HANDLE_HPP
#include <sta/assert.hpp>
namespace sta
{
template <typename T>
RtosHandle<T>::Deferred::Deferred(handle_type * handlePointer)
: pointer{handlePointer}
{}
template <typename T>
RtosHandle<T>::RtosHandle(handle_type handle)
: handle_{handle}, deferred_{false}
{}
template <typename T>
RtosHandle<T>::RtosHandle(Deferred handle)
: handle_{handle.pointer}, deferred_{true}
{
STA_ASSERT(handle.pointer != nullptr);
}
template <typename T>
typename RtosHandle<T>::handle_type RtosHandle<T>::get()
{
if (deferred_)
{
// Dereference void ** in handle
handle_ = *reinterpret_cast<handle_type *>(handle_);
deferred_ = false;
}
return handle_;
}
} // namespace sta
#endif // STA_RTOS_HANDLE_TPP