Home

Awesome

trackable_ptr

Trackable pointer. When trackable object moved/destroyed, trackers updated with new object's pointer.

Live example

Allow to have stable pointer on any movable object (in single-threaded environment). Like:

struct Data{
    int x,y,z;
};

std::vector< trackable<Data> > list1;

list1.emplace_back();

	trackable_ptr<Data> data {list1.back()};	//  store pointer to element

list1.emplace_back();
list1.emplace_back();
list1.emplace_back();
list1.emplace_back();
// list 1 now uses another memory chuck. All pointers/iterators invalidated.

// data still alive and accessible;
std::cout << data->x;

Does not increase object lifetime (like shared_ptr)

Also, kinda replacement for weak_ptr in terms of object aliveness track. Dead elements have nullptr trackable_ptr's.

Interaction with std::vector

#include <vector>
#include <iostream>

#include "trackable_ptr_extensions.h"

struct Data{
    int value;
    Data(int value) :value(value) {}
};

int main() {
    std::vector<trackable<Data>> vec;

    // fill
    trackable<Data>& d1 = vec.emplace_back(1);
    trackable_ptr<Data> p_i1{d1};

    trackable_ptr<Data> p_i2{vec.emplace_back(2)};

    // erase
    vec.erase(get_iterator(vec, p_i1));

    // insert
    trackable_ptr<Data> p_i3 = *vec.insert(get_iterator(vec, p_i2), 3);

    std::cout << "dead " << !p_i1 << std::endl;
    std::cout << p_i2->value << std::endl;
    std::cout << p_i3->value << std::endl;

    return 0;
}

get_iterator / get_index allow you to get iterator / index from trackable_ptr. And in this way have "non-invalidatable iterators" for std::vector.

trackable

trackable is basically:

template<class T>
struct trackable : trackable_base, T {}

So you can access trackable<T> the same way as T. And if you need exactly class T, you can just cast to it. This have some drawbacks... So if you have a better idea, fill an issue.

Inheriting trackable_base

Instead of wrapping your class with trackable, like trackable<MyClass>; you may inerit trackable_base, instead:

struct MyClass : trackable_base{}

std::vector<MyClass> vec;
trackable_ptr<MyClass> first = {vec.emplace_back()};

trackable_wrapper<T>

trackable_wrapper<T> is a simple helper class:

template<class T>
struct trackable_wrapper : trackable_base{
    T value;
}

Useful for cases when you can't inherit T, or don't want to use trackable.

Usage:

    trackable_wrapper<int> i;
    i.value = 100;

    trackable_ptr< trackable_wrapper<int> > p_i = {i};

    std::cout << p_i->value;

Overhead