Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tower120/trackable_ptr
Smart pointer for any movable objects. When trackable object moved/destroyed, trackers updated with new object's pointer.
https://github.com/tower120/trackable_ptr
cpp pointer smart-pointer
Last synced: 3 months ago
JSON representation
Smart pointer for any movable objects. When trackable object moved/destroyed, trackers updated with new object's pointer.
- Host: GitHub
- URL: https://github.com/tower120/trackable_ptr
- Owner: tower120
- License: mit
- Created: 2017-08-30T19:43:47.000Z (about 7 years ago)
- Default Branch: trackable_base
- Last Pushed: 2019-05-18T08:59:59.000Z (over 5 years ago)
- Last Synced: 2024-04-16T21:28:52.566Z (7 months ago)
- Topics: cpp, pointer, smart-pointer
- Language: C++
- Homepage:
- Size: 65.4 KB
- Stars: 24
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- AwesomeCppGameDev - trackable_ptr
README
[![Build Status](https://travis-ci.org/tower120/trackable_ptr.svg?branch=trackable_base)](https://travis-ci.org/tower120/trackable_ptr)
# trackable_ptr
Trackable pointer. When `trackable` object moved/destroyed, `trackable_ptr`s updated with new object's location.
Allow to have stable pointer on any movable object (in single-threaded environment). Objects may be stack allocated.
Header only. You need only "include" folder.
**Warning!** Performance-wise it is not faster then using heap allocated objects (probably due to size grow). See benchmarks, your mileage may vary.
```c++
struct Data{
int x,y,z;
};std::vector< unique_trackable > list1;
list1.emplace_back();
trackable_ptr ptr {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.// ptr still alive and accessible;
std::cout << ptr->x;
``````cpp
struct Box;struct Corner{
explicit Corner(Box* box) : box(box) {}trackable_ptr box;
int x = 0;
int y = 0;
};struct Box : trackable_base {
Corner lt{this};
Corner rb{this};
};std::vector boxes;
// Box can be moved around. Corner::box always valid.
// trackable_ptr can be stored in lambda callback.Box& active_box = boxes[i];
on_some_event([box = trackable_ptr(&active_box)](){
if (!box) return;
std::cout << box->lt.x;
});
```#### Behavior
On `trackable` destruction - all `trackable_ptr`s becomes nullptr.
On `trackable` move - all `trackable_ptr`s updates with new object location.
On `trackable` copy - `trackable_ptr`s unaffected.
#### `trackable_base`
Inherit this, if you want your class to be compatible with `trackable_ptr`.
```cpp
struct MyClass : trackable_base {}MyClass m;
trackable_ptr p = &m;
```#### `trackable`
```cpp
trackable i;
trackable_ptr p = &i;auto i2 = std::move(i);
assert(p.get() == i2.get());
```For the sake of sanity, `trackable` is forbidden, use `const trackable` instead.
* `trackable()` - construct object with default constructor, if possible.
* `trackable(T&&)` - conversion constructor.
* `trackable(Args&&... args)` - in-place construct object.
* `trackable(trackable&& other)`
* `trackable(const trackable&)`
* `trackable& operator=(trackable&&)`
* `trackable& operator=(const trackable&)`
* `T* get()` - return object pointer.
* `const T* get() const`
* `T* operator->()`
* `const T* operator->() const`
* `T& operator*()`
* `const T& operator*() const`
* `~trackable()` - update all `trackable_ptr`'s with new nullptr.#### `unique_trackable`
Same as `trackable`, but move-only.
Useful for use in containers. For example, it is not required for `std::vector` implementation to use move instead copy, when both copy and move constructor are available. Though all tested implementations currently prefer move, whenever possible.
#### `trackable_ptr`
* `trackable_ptr()` - construct with nullptr
* `trackable_ptr(T*)`
* `trackable_ptr(trackable*)`
* `auto* get_trackable() const` - return address of `trackable`, which holds object (return `get()` otherwise).
* `operator bool() const` - return true if not nullptr
* `T* get() const` - return object pointer.
* `T* operator->() const`
* `T& operator*() const`
* `~trackable_ptr()` - exclude this from trackers list.#### "trackable_ptr_extensions.h"
```c++
#include#include
int main() {
std::vector> vec = {1, 2, 3, 4};trackable_ptr p{vec.begin()};
assert(get_iterator(vec, p) == vec.begin());
return 0;
}
```
Work with contiguous containers only.* `in_container(const Container&, const trackable_ptr &)` - check if trackable_ptr stored inside contiguous container.
* `get_index(const Container&, const trackable_ptr&)` - return index of element in contiguous container. trackable_ptr must exists inside contiguous container.
* `get_iterator(Container&&, const trackable_ptr &)` - return iterator of element in contiguous container. if trackable_ptr does not exists inside contiguous container, return end().### Overhead
* 1 ptr for `trackable`
* 3 ptr for `trackable_ptr`
* O(n) complexity for moving/destroying `trackable`. Where n = `tracker_ptr`s per `trackable`
* O(1) complexity for moving/destroying `trackable_ptr`