trackable_ptr + std::vector = non-invalidatable iterator

Though it is obvious, that using trackable_ptr allow container’s element access without need of iterator,or index. It may not come at first glance, that you can use trackable_ptr to do same things, you do with regular iterator (or index access) of any container with contiguous elements storage, like std::vector.

std::vector being contiguous, allow us, to calculate index element from its pointer:

template<class T>
std::size_t get_index(T* ptr_to_element, std::vector<T>& vec){
    return ptr_to_element - vec.dat();
}

And as you can see, it is pretty fast. https://godbolt.org/g/PiyE45

It is not very useful, when dealing with regular pointers, because they invalidates, after almost each interaction with std::vector. But trackable_ptr - is another thing. It always have pointer to element or null, if element was destroyed. So we can get iterator from trackable_ptr:

template<class T, class R>
auto get_iterator(const std::vector<T>& vec, const trackable_ptr<R>& ptr){
    return vec.begin() + get_index(ptr.get(), vec);
}

Now we can use trackable_ptr to do anything, we can do with std::vectors iterator:

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

    // insert after element
    vec.insert(get_iterator(vec, my_trackable_ptr), 3);

Source code

Comments