Ptr.hpp

A wrapper for pointers that does careful memory tracking (but only in debug mode).

Ptr objects behave as normal pointers under most conditions. However, if a program is compiled with EMP_TRACK_MEM set, then these pointers perform extra tests to ensure that they point to valid memory and that memory is freed before pointers are released.

If you want to prevent pointers to pointers (a common source of errors, but MAY be done intentionally) you can define EMP_NO_PTR_TO_PTR

If you trip an assert, you can re-do the run a track a specific pointer by defining EMP_ABORT_PTR_NEW or EMP_ABORT_PTR_DELETE to the ID of the pointer in question.

For example: -DEMP_ABORT_PTR_NEW=1691

This will allow you to track the pointer more easily in a debugger.

Todo:

Track information about vector and array objects to make sure we don’t point directly into them? (A resize() could make such pointers invalid!) Or better, warn it vector memory could have moved.

Get working with threads

Note

Status: BETA

Enums

enum class PtrStatus

Values:

enumerator DELETED
enumerator ACTIVE
enumerator ARRAY

Functions

template<typename T>
inline void FillMemory(Ptr<unsigned char> mem_ptr, const size_t num_bytes, T fill_value)

Fill an array with the provided fill_value. If fill_value is a function, repeatedly call function.

template<typename T>
inline void FillMemoryFunction(Ptr<unsigned char> mem_ptr, const size_t num_bytes, T fill_fun)

Fill an array by repeatedly calling the provided fill functions.

inline void SetPtrDebug(bool _d = true)
inline bool GetPtrDebug()
template<typename T>
std::ostream &operator<<(std::ostream &out, const Ptr<T> &ptr)
template<typename T, typename ...Ts>
std::istream &operator>>(std::istream &is, Ptr<T> &ptr)
template<typename T>
Ptr<T> ToPtr(T *_in, bool own = false)

Convert a T* to a Ptr<T>. By default, don’t track.

template<typename T>
Ptr<T> TrackPtr(T *_in, bool own = true)

Convert a T* to a Ptr<T> that we DO track.

template<typename T, typename ...ARGS>
Ptr<T> NewPtr(ARGS&&... args)

Create a new Ptr of the target type; use the args in the constructor.

template<typename T>
Ptr<T> CopyPtr(Ptr<T> in)

Copy an object pointed to and return a Ptr to the copy.

template<typename T>
vector<Ptr<T>> CopyPtrs(const vector<Ptr<T>> &in)

Copy a vector of objects pointed to; return a vector of Ptrs to the new copies.

template<typename T>
vector<Ptr<T>> ClonePtrs(const vector<Ptr<T>> &in)

Copy a vector of objects pointed to by using their Clone() member function; return vector.

template<typename T>
Ptr<T> NewArrayPtr(size_t array_size)

Create a pointer to an array of objects.

template<typename T>
void CopyMemory(Ptr<T> from_ptr, Ptr<T> to_ptr, const size_t num_items)

Copy an array from the provided memory.

class PtrInfo
#include <Ptr.hpp>

Public Functions

inline PtrInfo(const void *_ptr)
inline PtrInfo(const void *_ptr, size_t _array_bytes)
PtrInfo(const PtrInfo&) = default
PtrInfo(PtrInfo&&) = default
PtrInfo &operator=(const PtrInfo&) & = default
PtrInfo &operator=(PtrInfo&&) & = default
inline ~PtrInfo()
inline const void *GetPtr() const noexcept

What pointer does this one hold information about?

inline int GetCount() const noexcept

How many Ptr objects point to the associated position?

inline size_t GetArrayBytes() const noexcept

If this ptr is to an array, how many bytes large is the array (may be different from size!)

inline bool IsActive() const noexcept

Is this pointer currently valid to access?

inline bool IsArray() const noexcept

Is this pointer pointing to an array?

inline void SetArray(size_t bytes) noexcept

Denote that this pointer is an array.

inline void Inc([[maybe_unused]] const size_t id)

Add one more pointer.

inline void Dec([[maybe_unused]] const size_t id)

Remove a pointer.

inline void MarkDeleted()

Indicate that the associated position has been deleted.

inline bool OK() const noexcept

Debug utility to determine if everything looks okay with this pointer’s information.

Private Members

const void *ptr

Which pointer are we keeping data on?

int count

How many of this pointer do we have?

PtrStatus status

Has this pointer been deleted? (i.e., if so, don’t access it!)

size_t array_bytes

How big is the array pointed to (in bytes)?

class PtrTracker
#include <Ptr.hpp>

Facilitate tracking of all Ptr objects in this run.

Public Functions

inline ~PtrTracker()
inline PtrInfo &GetInfo(const void *ptr)

Get the info associated with an existing pointer.

inline PtrInfo &GetInfo(size_t id)
inline bool HasPtr(const void *ptr) const

Determine if a pointer is being tracked.

inline size_t GetCurID(const void *ptr)

Retrieve the ID associated with a pointer.

inline size_t GetNumIDs() const

Lookup how many pointers are being tracked.

inline size_t GetArrayBytes(size_t id) const

How big is an array associated with an ID?

inline bool IsDeleted(size_t id) const

Check if an ID is for a pointer that has been deleted.

inline bool IsActive(const void *ptr)

Is a pointer active and ready to be used?

inline bool IsActiveID(size_t id)

Is a pointer id associated with a pointer that’s active and ready to be used?

inline bool IsArrayID(size_t id)

Is an ID associated with an array?

inline int GetIDCount(size_t id) const

How many Ptr objects are associated with an ID?

inline size_t New(const void *ptr)

This pointer was just created as a Ptr!

inline size_t NewArray(const void *ptr, size_t array_bytes)

This pointer was just created as a Ptr ARRAY!

inline void IncID(size_t id)

Increment the number of Pointers associated with an ID.

inline void DecID(size_t id)

Decrement the number of Pointers associated with an ID.

inline void MarkDeleted(size_t id)

Mark the pointers associated with this ID as deleted.

Public Static Functions

static inline PtrTracker &Get()

Treat this class as a singleton with a single Get() method to retrieve it.

Private Functions

inline PtrTracker()
PtrTracker(const PtrTracker&) = delete
PtrTracker(PtrTracker&&) = delete
PtrTracker &operator=(const PtrTracker&) = delete
PtrTracker &operator=(PtrTracker&&) = delete

Private Members

std::unordered_map<const void*, size_t> ptr_id

Associate raw pointers with unique IDs.

vector<PtrInfo> id_info

Associate IDs with pointer information.

Private Static Attributes

static constexpr size_t UNTRACKED_ID = (size_t)-1
template<typename TYPE>
class BasePtr
#include <Ptr.hpp>

Subclassed by Ptr< TYPE >

Public Functions

inline BasePtr(TYPE *in_ptr)
inline TYPE &operator*() const
inline TYPE *operator->() const
inline TYPE &operator[](size_t pos) const

Protected Attributes

TYPE *ptr

The raw pointer associated with this Ptr object.

template<>
class BasePtr<void>
#include <Ptr.hpp>

Base class with functionality only needed in void pointers.

Public Functions

inline BasePtr(void *in_ptr)

Protected Attributes

void *ptr

The raw pointer associated with this Ptr object.

template<>
class BasePtr<const void>
#include <Ptr.hpp>

Public Functions

inline BasePtr(const void *in_ptr)

Protected Attributes

const void *ptr

The raw pointer associated with this Ptr object.

template<typename TYPE>
class Ptr : public BasePtr<TYPE>
#include <Ptr.hpp>

Public Types

using element_type = TYPE

Public Functions

inline Ptr()

Default constructor.

inline Ptr(const Ptr<TYPE> &_in)

Copy constructor.

template<typename T2>
inline Ptr(T2 *in_ptr, bool = false)

Construct from raw ptr.

template<typename T2>
inline Ptr(T2 *_ptr, size_t, bool)

Construct from array.

template<typename T2>
inline Ptr(Ptr<T2> _in)

From compatible Ptr.

inline Ptr(std::nullptr_t)

From nullptr.

inline ~Ptr()

Destructor.

inline bool IsNull() const
inline TYPE *Raw() const
inline TYPE *Raw(size_t pos) const
template<typename T2>
inline Ptr<T2> Cast() const
template<typename T2>
inline Ptr<T2> ConstCast() const
template<typename T2>
inline Ptr<T2> DynamicCast() const
template<typename T2>
inline Ptr<T2> ReinterpretCast() const
template<typename ...T>
inline void New(T&&... args)
inline void NewArray(size_t array_size)
inline void Delete()
inline void DeleteArray()
inline size_t Hash() const noexcept
inline Ptr<TYPE> &operator=(const Ptr<TYPE> &_in) &
template<typename T2>
inline Ptr<TYPE> &operator=(T2 *_in) &
template<typename T2>
inline Ptr<TYPE> &operator=(Ptr<T2> _in) &
inline operator TYPE*()
inline operator bool()
inline operator bool() const
template<typename T>
inline bool operator==(const T &in_ptr) const
template<typename T>
inline bool operator!=(const T &in_ptr) const
template<typename T>
inline bool operator<(const T &in_ptr) const
template<typename T>
inline bool operator>(const T &in_ptr) const
template<typename T>
inline bool operator<=(const T &in_ptr) const
template<typename T>
inline bool operator>=(const T &in_ptr) const
inline Ptr<TYPE> operator+(int value) const
inline Ptr<TYPE> operator-(int value) const
inline Ptr<TYPE> operator+(size_t value) const
inline Ptr<TYPE> operator-(size_t value) const
template<typename T>
inline void FillMemoryFunction(const size_t num_bytes, T fill_fun)

Fill an array with the provided fill_value. If fill_value is a function, repeatedly call function.

template<typename T>
inline void FillMemory(const size_t num_bytes, T fill_value)

Fill an array with the provided fill_value. If fill_value is a function, repeatedly call function.

inline int DebugGetCount() const
inline bool DebugIsArray() const
inline size_t DebugGetArrayBytes() const
inline bool DebugIsActive() const
inline bool OK() const
struct hash_t
#include <Ptr.hpp>

Public Functions

inline size_t operator()(const Ptr<TYPE> &t) const noexcept