GEGELATI
Loading...
Searching...
No Matches
arrayWrapper.h
1
37#ifndef ARRAY_WRAPPER_H
38#define ARRAY_WRAPPER_H
39
40#include <functional>
41#include <map>
42#include <regex>
43#include <sstream>
44#include <stdexcept>
45#include <typeindex>
46#include <typeinfo>
47
48#include "data/constant.h"
49#include "data/dataHandler.h"
50#include "data/demangle.h"
51#include "data/hash.h"
52
53namespace Data {
54
68 template <class T> class ArrayWrapper : public DataHandler
69 {
70 static_assert(std::is_fundamental<T>::value ||
71 std::is_same<T, Data::Constant>(),
72 "Template class PrimitiveTypeArray<T> can only be used "
73 "for primitive types.");
74
75 private:
88 mutable std::map<std::type_index, size_t> cachedAddressSpace;
89
90 protected:
99 const size_t nbElements;
100
105 std::vector<T>* containerPtr;
106
118 void checkAddressAndType(const std::type_info& type,
119 const size_t& address) const;
120
124 virtual size_t updateHash() const override;
125
126 public:
137 ArrayWrapper(size_t size = 8, std::vector<T>* ptr = nullptr)
138 : nbElements{size}
139 {
140 this->setPointer(ptr);
141 };
142
144 virtual ~ArrayWrapper() = default;
145
148
158 ArrayWrapper(const DataHandler& other, size_t size);
159
166 virtual DataHandler* clone() const override;
167
169 virtual bool canHandle(const std::type_info& type) const override;
170
172 virtual size_t getAddressSpace(
173 const std::type_info& type) const override;
174
176 virtual size_t getLargestAddressSpace(void) const override;
177
186
188 void resetData() override;
189
201 void setPointer(std::vector<T>* ptr);
202
204 virtual UntypedSharedPtr getDataAt(const std::type_info& type,
205 const size_t address) const override;
206
208 virtual std::vector<size_t> getAddressesAccessed(
209 const std::type_info& type, const size_t address) const override;
210
211#ifdef CODE_GENERATION
213 virtual const std::type_info& getNativeType() const override;
214
216 virtual std::vector<size_t> getDimensionsSize() const override;
217#endif
218 };
219
220 template <class T>
221 bool ArrayWrapper<T>::canHandle(const std::type_info& type) const
222 {
223 if (typeid(T) == type) {
224 return true;
225 }
226
227 // Use the code in getAddressSpace to check if the type is supported.
228 return (this->getAddressSpace(type) > 0);
229 }
230
231 template <class T>
232 void ArrayWrapper<T>::checkAddressAndType(const std::type_info& type,
233 const size_t& address) const
234 {
235 size_t addressSpace = this->getAddressSpace(type);
236 // check type
237 if (addressSpace == 0) {
238 std::stringstream message;
239 message << "Data type " << DEMANGLE_TYPEID_NAME(type.name())
240 << " cannot be accessed in a "
241 << DEMANGLE_TYPEID_NAME(typeid(*this).name()) << ".";
242 throw std::invalid_argument(message.str());
243 }
244
245 // check location
246 if (address >= addressSpace) {
247 std::stringstream message;
248 message << "Data type " << DEMANGLE_TYPEID_NAME(type.name())
249 << " cannot be accessed at address " << address
250 << ", address space size is " << addressSpace << ".";
251 throw std::out_of_range(message.str());
252 }
253 }
254
255 template <class T>
257 : DataHandler(other), containerPtr{nullptr}, nbElements(size)
258 {
259 this->setPointer(nullptr);
260 }
261
262 // Declare class for clone method
263 template <class T> class PrimitiveTypeArray;
264
265 template <class T> inline DataHandler* ArrayWrapper<T>::clone() const
266 {
267 // Create a constantCopy of the ArrayWrapper content.
268 DataHandler* result = new PrimitiveTypeArray<T>(*this);
269
270 return result;
271 }
272
273 template <class T>
274 size_t ArrayWrapper<T>::getAddressSpace(const std::type_info& type) const
275 {
276 // Has the addresSpaceSize been cached
277 auto iter = this->cachedAddressSpace.find(type);
278 if (iter != this->cachedAddressSpace.end()) {
279 return iter->second;
280 }
281
282 if (type == typeid(T)) {
283 this->cachedAddressSpace.emplace(type, this->nbElements);
284 return this->nbElements;
285 }
286
287 // If the type is an array of the primitive type
288 // with a size inferior to the container.
289 std::string typeName = DEMANGLE_TYPEID_NAME(type.name());
290 std::string regex{DEMANGLE_TYPEID_NAME(typeid(T).name())};
291 regex.append("\\s*(const\\s*)?\\[([0-9]+)\\]");
292 std::regex arrayType(regex);
293 std::cmatch cm;
294 if (std::regex_match(typeName.c_str(), cm, arrayType)) {
295 int size = std::atoi(cm[2].str().c_str());
297 size_t result = this->nbElements - size + 1;
298 this->cachedAddressSpace.emplace(type, result);
299 return result;
300 }
301 }
302 // Default case
303 return 0;
304 }
305
306 template <class T>
308 const std::type_info& type, const size_t address) const
309 {
310 // Initialize the result
311 std::vector<size_t> result;
312
313 // If the accessed address is valid fill the result.
314 const size_t space = this->getAddressSpace(type);
315 if (space > address) {
316 // For the native type.
317 if (type == typeid(T)) {
318 result.push_back(address);
319 }
320 else {
321 // Else, the type is the array type.
322 for (int i = 0; i < (this->nbElements - space + 1); i++) {
323 result.push_back(address + i);
324 }
325 }
326 }
327 return result;
328 }
329
330 template <class T>
332 const std::type_info& type, const size_t address) const
333 {
334 if (this->containerPtr == nullptr) {
335 throw std::runtime_error("Null pointer access.");
336 }
337#ifndef NDEBUG
338 // Throw exception in case of invalid arguments.
340#endif
341
342 if (type == typeid(T)) {
343 UntypedSharedPtr result(
344 &(this->containerPtr->at(address)),
345 UntypedSharedPtr::emptyDestructor<const T>());
346 return result;
347 }
348
349 // Else, the only other supported type is cstyle array.
350
351 // Allocate the array
352 size_t arraySize = this->nbElements - this->getAddressSpace(type) + 1;
353 T* array = new T[arraySize];
354
355 // Copy its content
356 for (size_t idx = 0; idx < arraySize; idx++) {
357 array[idx] = this->containerPtr->at(address + idx);
358 }
359
360 // Create the UntypedSharedPtr
361 UntypedSharedPtr result{
362 std::make_shared<UntypedSharedPtr::Model<const T[]>>(array)};
363 return result;
364 }
365
366 template <class T> size_t ArrayWrapper<T>::getLargestAddressSpace() const
367 {
368 // Currently, largest addres space is for the template Type T.
369 return this->nbElements;
370 }
371
373 {
374 this->invalidCachedHash = true;
375 }
376
377 template <class T> void ArrayWrapper<T>::resetData()
378 {
379 // Does nothing;
380 }
381
382 template <class T>
383 inline void ArrayWrapper<T>::setPointer(std::vector<T>* ptr)
384 {
385 // Null ptr case
386 if (ptr == nullptr) {
387 this->containerPtr = ptr;
388 this->invalidCachedHash = true;
389 return;
390 }
391
392 // Else
393 // Check the size of the given vector
394 if (ptr->size() != nbElements) {
395 std::stringstream message;
396 message << "Size of pointed data (" << ptr->size()
397 << ") does not correspond to the size of the ArrayWrapper ("
398 << this->nbElements << ").";
399 throw std::domain_error(message.str());
400 }
401
402 // Else
403 this->containerPtr = ptr;
404 this->invalidCachedHash = true;
405 }
406
407 template <class T> inline size_t ArrayWrapper<T>::updateHash() const
408 {
409 // Null pointer case
410 if (this->containerPtr == nullptr) {
411 return this->cachedHash = 0;
412 }
413
414 // reset
415 this->cachedHash = Data::Hash<size_t>()(this->id);
416
417 // hasher
419
420 for (T dataElement : *(this->containerPtr)) {
421 // Rotate by 1 because otherwise, xor is comutative.
422 this->cachedHash =
423 (this->cachedHash >> 1) | (this->cachedHash << 63);
424 this->cachedHash ^= hasher((T)dataElement);
425 }
426
427 // Validate the cached hash value
428 this->invalidCachedHash = false;
429
430 return this->cachedHash;
431 }
432
433#ifdef CODE_GENERATION
434 template <class T>
435 const std::type_info& ArrayWrapper<T>::getNativeType() const
436 {
437 const std::type_info& a = typeid(T);
438 return a;
439 }
440
441 template <class T>
442 std::vector<size_t> ArrayWrapper<T>::getDimensionsSize() const
443 {
444 std::vector<size_t> sizes = {nbElements};
445 return sizes;
446 }
447#endif
448
449} // namespace Data
450#endif // !ARRAY_WRAPPER_H
451
452// Include PrimitiveTypeArray to ensure availability of the used clone method.
453#include "data/primitiveTypeArray.h"
size_t getAddressSpace(const std::type_info &type, size_t *dim1, size_t *dim2) const
Utility function for the class.
Definition array2DWrapper.h:217
Definition arrayWrapper.h:69
ArrayWrapper(const ArrayWrapper< T > &other)=default
Default copy constructor.
std::vector< T > * containerPtr
Pointer to the array containing the data accessed through the ArrayWrapper.
Definition arrayWrapper.h:105
virtual ~ArrayWrapper()=default
Default destructor.
ArrayWrapper(const DataHandler &other, size_t size)
Copy constructor for DataHandler.
Definition arrayWrapper.h:256
void resetData() override
Inherited from DataHandler. Does nothing.
Definition arrayWrapper.h:377
ArrayWrapper(size_t size=8, std::vector< T > *ptr=nullptr)
Constructor for the ArrayWrapper class.
Definition arrayWrapper.h:137
void invalidateCachedHash()
Invalidate the hash of the container.
Definition arrayWrapper.h:372
const size_t nbElements
Number of elements contained pointer vector.
Definition arrayWrapper.h:99
virtual size_t getLargestAddressSpace(void) const override
Inherited from DataHandler.
Definition arrayWrapper.h:366
virtual DataHandler * clone() const override
Return a PrimitiveTypeArray<T> where all data of the ArrayWrapper has been copied.
Definition arrayWrapper.h:265
virtual std::vector< size_t > getDimensionsSize() const override
Inherited from DataHandler.
Definition arrayWrapper.h:442
virtual size_t getAddressSpace(const std::type_info &type) const override
Inherited from DataHandler.
Definition arrayWrapper.h:274
virtual size_t updateHash() const override
Implementation of the updateHash method.
Definition arrayWrapper.h:407
virtual UntypedSharedPtr getDataAt(const std::type_info &type, const size_t address) const override
Inherited from DataHandler.
Definition arrayWrapper.h:331
virtual std::vector< size_t > getAddressesAccessed(const std::type_info &type, const size_t address) const override
Inherited from DataHandler.
Definition arrayWrapper.h:307
void setPointer(std::vector< T > *ptr)
Set the pointer of the ArrayWrapper.
Definition arrayWrapper.h:383
virtual const std::type_info & getNativeType() const override
Inherited from DataHandler.
Definition arrayWrapper.h:435
void checkAddressAndType(const std::type_info &type, const size_t &address) const
Definition arrayWrapper.h:232
virtual bool canHandle(const std::type_info &type) const override
Inherited from DataHandler.
Definition arrayWrapper.h:221
Base class for all sources of data to be accessed by a TPG Instruction executed within a Program.
Definition dataHandler.h:55
bool invalidCachedHash
Boolean value indicating whether the current cachedValue is valid, or not.
Definition dataHandler.h:90
size_t cachedHash
Cached value returned by the getHash() function.
Definition dataHandler.h:78
const size_t id
Identifier of each DataHandler.
Definition dataHandler.h:70
DataHandler for 2D arrays of primitive types.
Definition primitiveTypeArray2D.h:69
PrimitiveTypeArray2D(const size_t w=2, const size_t h=4)
Constructor for the 2D array.
Definition primitiveTypeArray2D.h:142
Definition primitiveTypeArray.h:55
Class behaving as a std::shared_ptr whose type is not templated.
Definition untypedSharedPtr.h:72
Definition array2DWrapper.h:44