placement fact update

This commit is contained in:
Robin Müller 2020-10-01 11:07:20 +02:00
parent aed2d7fc93
commit 43b44c57b6

View File

@ -3,26 +3,62 @@
#include "../storagemanager/StorageManagerIF.h" #include "../storagemanager/StorageManagerIF.h"
#include <utility> #include <utility>
/**
* The Placement Factory is used to create objects at runtime in a specific pool.
* In general, this should be avoided and it should only be used if you know what you are doing.
* You are not allowed to use this container with a type that allocates memory internally like ArrayList.
*
* Also, you have to check the returned pointer in generate against nullptr!
*
* A backend of Type StorageManagerIF must be given as a place to store the new objects.
* Therefore ThreadSafety is only provided by your StorageManager Implementation.
*
* Objects must be destroyed by the user with "destroy"! Otherwise the pool will not be cleared.
*
* The concept is based on the placement new operator.
*
* @warning Do not use with any Type that allocates memory internally!
* @ingroup container
*/
class PlacementFactory { class PlacementFactory {
public: public:
PlacementFactory(StorageManagerIF* backend) : PlacementFactory(StorageManagerIF* backend) :
dataBackend(backend) { dataBackend(backend) {
} }
/***
* Generates an object of type T in the backend storage.
*
* @warning Do not use with any Type that allocates memory internally!
*
* @tparam T Type of Object
* @param args Constructor Arguments to be passed
* @return A pointer to the new object or a nullptr in case of failure
*/
template<typename T, typename ... Args> template<typename T, typename ... Args>
T* generate(Args&&... args) { T* generate(Args&&... args) {
store_address_t tempId; store_address_t tempId;
uint8_t* pData = NULL; uint8_t* pData = nullptr;
ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T), ReturnValue_t result = dataBackend->getFreeElement(&tempId, sizeof(T),
&pData); &pData);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return NULL; return nullptr;
} }
T* temp = new (pData) T(std::forward<Args>(args)...); T* temp = new (pData) T(std::forward<Args>(args)...);
return temp; return temp;
} }
/***
* Function to destroy the object allocated with generate and free space in backend.
* This must be called by the user.
*
* @param thisElement Element to be destroyed
* @return RETURN_OK if the element was destroyed, different errors on failure
*/
template<typename T> template<typename T>
ReturnValue_t destroy(T* thisElement) { ReturnValue_t destroy(T* thisElement) {
if (thisElement == nullptr){
return HasReturnvaluesIF::RETURN_FAILED;
}
//Need to call destructor first, in case something was allocated by the object (shouldn't do that, however). //Need to call destructor first, in case something was allocated by the object (shouldn't do that, however).
thisElement->~T(); thisElement->~T();
uint8_t* pointer = (uint8_t*) (thisElement); uint8_t* pointer = (uint8_t*) (thisElement);