Files CCore/inc/gadget/Place.h CCore/src/gadget/Place.cpp
This file contains a collection of tools to work with raw memory pointers.
byte is a memory atom. It is always defined as the unsigned char, according the C++ standard.
using byte = unsigned char ;
inline byte * CastPtr(void *ptr) { return static_cast<byte *>(ptr); } inline const byte * CastPtr(const void *ptr) { return static_cast<const byte *>(ptr); }
CastPtr() converts a raw pointer to a byte pointer.
inline void * PtrAdd(void *ptr,ulen delta) { return CastPtr(ptr)+delta; } inline const void * PtrAdd(const void *ptr,ulen delta) { return CastPtr(ptr)+delta; } inline void * PtrSub(void *ptr,ulen delta) { return CastPtr(ptr)-delta; } inline const void * PtrSub(const void *ptr,ulen delta) { return CastPtr(ptr)-delta; }
PtrAdd() and PtrSub() moves a raw pointer up and down on the given number of bytes.
inline ulen PtrDist(const void *from,const void *to) { return ulen( CastPtr(to)-CastPtr(from) ); }
PtrDist() calculates the distance from the one raw pointer to another. Both pointers must be in the same "memory segment" and to must be after from.
Place is a simple wrapper around a raw pointer.
template <class Void>
class Place
{
Void *ptr;
public:
explicit Place(Void *ptr_) : ptr(ptr_) {}
template <class T>
Place<Void> operator + (T delta) const { return Place<Void>(PtrAdd(ptr,delta)); }
template <class T>
Place<Void> operator - (T delta) const { return Place<Void>(PtrSub(ptr,delta)); }
template <class T>
Place<Void> operator += (T delta) { return Replace(*this,*this+delta); }
template <class T>
Place<Void> operator -= (T delta) { return Replace(*this,*this-delta); }
template <class T>
operator T * () const { return static_cast<T *>(ptr); }
};
You can move Place on the given number of bytes and auto-cast to the desired type.
Place<void> place=....; place+=delta1; place-=delta2; C *ptr=place; C1 *ptr1=place+delta3;
Be warned, unlike for integral types, operators += and -= return the previous value, not the new one. Using these operators you can dispense a raw memory block to store multiple objects:
Place<void> place=....; C1 *ptr1=(place+=size1); // placed at the begining of the block C2 *ptr2=(place+=size2); // follows ....
PlaceAt() is a Creator function for Place:
inline Place<void> PlaceAt(void *ptr) { return Place<void>(ptr); } inline Place<const void> PlaceAt(const void *ptr) { return Place<const void>(ptr); }
Finally, a placement new and delete is defined for the type Place<void>:
inline void * operator new(std::size_t,CCore::Place<void> place) { return place; } inline void operator delete(void *,CCore::Place<void>) {}
void *mem=....; C *obj=new(PlaceAt(mem)) C(....); // more verbose than the standard placement new