https://github.com/nahratzah/cycle_ptr
Smart pointers that do the right thing with cycles.
https://github.com/nahratzah/cycle_ptr
cpp17 garbage-collection smart-pointer
Last synced: 11 months ago
JSON representation
Smart pointers that do the right thing with cycles.
- Host: GitHub
- URL: https://github.com/nahratzah/cycle_ptr
- Owner: nahratzah
- License: bsd-2-clause
- Created: 2018-05-31T19:18:38.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2023-02-10T21:05:45.000Z (about 3 years ago)
- Last Synced: 2023-03-29T13:41:25.526Z (almost 3 years ago)
- Topics: cpp17, garbage-collection, smart-pointer
- Language: C++
- Size: 188 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://travis-ci.org/nahratzah/cycle_ptr)
# Cycle Pointer library
This library is a smart pointer library, that allows for cycles in
datastructures.
Basically, if you have a case where:
class A;
class B;
class A {
public:
std::shared_ptr b;
};
class B {
public:
std::shared_ptr a;
};
int main() {
std::shared_ptr a_ptr = std::make_shared();
std::shared_ptr b_ptr = std::make_shared();
a_ptr->b = b_ptr;
b_ptr->a = a_ptr;
a_ptr.reset();
b_ptr.reset();
// We now leaked A and B!
}
is what you need, but you want to avoid the resulting memory leak, this library
may offer a solution.
The equivalent code in this library would be:
class A;
class B;
class A {
public:
cycle_ptr::cycle_member_ptr b;
};
class B {
public:
cycle_ptr::cycle_member_ptr a;
};
int main() {
cycle_ptr::cycle_gptr a_ptr = cycle_ptr::make_cycle();
cycle_ptr::cycle_gptr b_ptr = cycle_ptr::make_cycle();
a_ptr->b = b_ptr;
b_ptr->a = a_ptr;
a_ptr.reset();
b_ptr.reset();
// A and B are now unreachable, so cycle_ptr cleans them up properly.
}
## Reference
Doxygen output is [viewable online](https://www.stack.nl/~ariane/cycle_ptr/).
## Overview
This library contains three pointers, which form the core of its interface.
1. ``cycle_ptr::cycle_member_ptr`` represents a relationship between two
objects.
2. ``cycle_ptr::cycle_gptr`` represents a global pointer
(that's what the ``g`` stands for... I should not be allowed to come up
with names).
This pointer is also used for function arguments and variables at function
scope.
3. ``cycle_ptr::cycle_weak_ptr`` represents a weak pointer to an object.
``cycle_ptr::cycle_member_ptr`` and ``cycle_ptr::cycle_gptr`` operate similar
to ``std::shared_ptr``.
``cycle_ptr::cycle_weak_ptr`` is the equivalent of ``std::weak_ptr``.
## Dealing With Collections
Consider a collection: ``std::vector>``.
This collection is not suitable for use inside an object that participates
in the cycle\_ptr graph, as the link would not be modeled.
The alternative is to use ``std::vector>``,
but this would not be usable outside of an object participating in the graph.
The solution to this, is to use ``cycle_ptr::cycle_allocator``.
This allocator adapts an allocator ``Alloc``, by allowing cycle\_member\_ptr
to deduce its owner at construction.
class MyClass;
using MyClassVector = std::vector<
cycle_ptr::cycle_gptr,
cycle_ptr::cycle_allocator>>>;
class MyClass
: public cycle_ptr::cycle_base // Used as argument to allocator.
{
// Vector instantiated with allocator that enforces ownership from *this.
MyClassVector data = MyClassVector(MyClassVector::allocator_type(*this));
};
// Create a MyClassVector that does not have an owner object.
MyClassVector notAMember = MyClassVector(MyClassVector::allocator_type(cycle_ptr::unowned_cycle));
void example(cycle_ptr::cycle_gptr ptr) {
MyClass.data = notAMember; // Using copy assignment from std::vector.
}
With this allocator, copy construction should *always* supply an allocator
such that ownership is explicitly stated.
While move constructor silently succeeds, care should be taken not to break
ownership rules.
The vector in this example uses pointers to demonstrate usage, but it works
equally well with structs or classes containing member pointers.
## Configuring
The library allows for limited control of the GC operations, using
``cycle_ptr::gc_operation`` and related functions.