From 94a3d1981e416ed42a2e5fcbe88718d549a470c2 Mon Sep 17 00:00:00 2001 From: Henrik Stickann <4376396-Mithradir@users.noreply.gitlab.com> Date: Fri, 2 Dec 2022 16:41:56 +0100 Subject: [PATCH] Add handle wrapper class --- include/sta/rtos/handle.hpp | 74 +++++++++++++++++++++++++++++++++++++ include/sta/rtos/handle.tpp | 46 +++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 include/sta/rtos/handle.hpp create mode 100644 include/sta/rtos/handle.tpp diff --git a/include/sta/rtos/handle.hpp b/include/sta/rtos/handle.hpp new file mode 100644 index 0000000..2b92e8e --- /dev/null +++ b/include/sta/rtos/handle.hpp @@ -0,0 +1,74 @@ +#ifndef STA_RTOS_HANDLE_HPP +#define STA_RTOS_HANDLE_HPP + +#include + + +namespace sta +{ + /** + * @brief Helper for managing access to RTOS handles. + * + * @tparam T CMSIS RTOS2 handle type + * + * @ingroup STA_RTOS_API + */ + template + class RtosHandle + { + public: + using handle_type = T; /**< Handle type */ + + // TODO Support integer type with sizeof(T) == sizeof(void *) + static_assert(std::is_same::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 + + +#endif // STA_RTOS_HANDLE_HPP diff --git a/include/sta/rtos/handle.tpp b/include/sta/rtos/handle.tpp new file mode 100644 index 0000000..6c6927c --- /dev/null +++ b/include/sta/rtos/handle.tpp @@ -0,0 +1,46 @@ +#ifndef STA_RTOS_HANDLE_TPP +#define STA_RTOS_HANDLE_TPP + +#ifndef STA_RTOS_HANDLE_HPP +# error "Internal header. Use instead." +#endif // !STA_RTOS_HANDLE_HPP + +#include + + +namespace sta +{ + template + RtosHandle::Deferred::Deferred(handle_type * handlePointer) + : pointer{handlePointer} + {} + + + template + RtosHandle::RtosHandle(handle_type handle) + : handle_{handle}, deferred_{false} + {} + + template + RtosHandle::RtosHandle(Deferred handle) + : handle_{handle.pointer}, deferred_{true} + { + STA_ASSERT(handle.pointer != nullptr); + } + + template + typename RtosHandle::handle_type RtosHandle::get() + { + if (deferred_) + { + // Dereference void ** in handle + handle_ = *reinterpret_cast(handle_); + deferred_ = false; + } + + return handle_; + } +} // namespace sta + + +#endif // STA_RTOS_HANDLE_TPP