# AtomPtr
A safe wrapper around `std::sync::atomic::AtomPtr`, improving its
ergonomics, enforcing safety and indirection checks, and bringing some
extra tricks for more granular concurrent datastructure design.
## Quickstart
```rust
use atomptr::AtomPtr;
// Create some complex data and create an AtomPtr around it
let my_data = String::from("std::sync::atomic::AtomicPtr");
let p = AtomPtr::new(my_data);
// A 'Ref' is a snapshot of the inner 'AtomPtr' value. Even if the
// unner value were to change, a Ref keeps an old value alive until
// the last instance of it is dropped.
let p_ref = p.get_ref();
// 'AtomPtr' is copy-on-write, so we perform 'take_clone' (or 'take_copy') to
// get a snapshot of the data referenced by the snapshot. We can then
// freely make changes to the data.
let my_data2 = p_ref
.take_clone()
.split("::")
.filter_map(|segmnt| match segmnt {
"std" => Some("atomptr"),
"sync" => Some("AtomPtr"),
_ => None,
})
.collect::<Vec<_>>()
.join("::");
// Use either `swap()` or `compare_exchange()` to replace the data
let _ = p.compare_exchange(p_ref, my_data2.clone()).unwrap_ref();
let p_ref = p.get_ref();
assert_eq!(p_ref.count(), 2);
assert_eq!(p_ref.take_clone(), my_data2);
```
## Migrating from 2.x versions
- `uwu_copy` was renamed to `take_copy`
- `uwu_clone` was renamed to `take_clone`
- This library was relicensed from `GPL-3.0` to `EUPL-1.2` or `Apache-2.0`
## Migrating from 1.x versions
Due to a few API changes the version was suddenly from `1.4.x` to `2.0.0`, not
giving any deprecation time for the newly removed items. To allow a
smoother upgrade path for existing consumers when upgrading can enable
the `stable` feature, which will opt-out of the code-breaking changes
of the API, giving them time to port over their usage.
Furthermore deprecations have been made with this bump. Warnings turn
to errors in version `2.1.0`, and the `stable` feature is removed in
version `2.2.0`
This crate wraps a given `T` into an `Arc<T>`, then stores an "owned
reference" into the `AtomicPtr`.
A safe wrapper around atomic pointers to build datastructures and
lock-free algorithms on top of. Only uses `std` as a dependency.
The standard library contains an `AtomicPtr` type, which by itself is
very unergonomic to use, because it deals with raw pointers. It is
very easy to misuse this API and get memory leaks or double-free.
This library makes some assumptions about how you would like to use
your data. Furthermore, it is dangerous to use raw pointers without
some other memory management strategy. This crate uses `Arc<T>` to
handle reference lifetime management. Data in an `AtomPtr<T>` is also
_always_ heap allocated.
Following is a simple example.
```rust
use atomptr::AtomPtr;
struct MyData { name: String }
let data = MyData { name: "Kookie".into() };
let a = AtomPtr::new(data);
println!("Name is: {}", a.get_ref().name);
let old_ref = a.swap(MyData { name: "Bob".into() });
println!("Name now is: {}, was {}", a.get_ref().name, old_ref.name);
```
Because all data is wrapped by `Arc<T>` internally, returning a
reference of the underlying data doesn't mean it is removed from the
pointer itself, or de-allocated after `Ref<T>` goes out of scope.
Another thread _can_ of course swap the data contained in the pointer,
which is why `compare_exchange` requires a previously held data
reference.