Struct rclite::Arc

source ·
pub struct Arc<T> { /* private fields */ }
Expand description

The Arc<T> type represents a thread-safe reference-counting pointer, where “Arc” stands for “Atomically Reference Counted”. It provides shared ownership of a value of type T, stored on the heap. When you call the clone method on Arc, a new instance of Arc is created that points to the same heap allocation as the original Arc, and the reference count is increased. Once the last Arc pointer to a given allocation is destroyed, the inner value stored in that allocation is also dropped.

Because shared references in Rust are read-only by default, you cannot modify the value stored inside an Arc. If you need to modify it, use the Mutex, RwLock, or one of the Atomic types.

Please note that this type is only available on platforms that support atomic loads and stores of pointers, which includes all platforms that support the std crate but not those that only support the alloc crate. You can check if a platform supports this type at compile time by using the #[cfg(target_has_atomic =“ptr”)] attribute.

Thread Safety

Arc<T> is a thread-safe reference-counting pointer, meaning it’s safe to use in multithreaded environments. However, this comes at a cost, as atomic operations are slower than regular memory accesses. If you’re not sharing reference-counted values between threads, consider using Rc<T> instead, which has lower overhead.

Arc<T> can be used with Send and Sync types only, so make sure that the type T you’re using with it implements these traits. Keep in mind that Arc<T> only ensures thread safety for the reference count, not the data stored in it. To make the data itself thread-safe, you may need to pair Arc<T> with a Send+Sync type, such as rclite::Mutex<T>.

Cloning references

Creating a new reference from an existing reference-counted pointer is done using the Clone trait implemented for Arc<T>

use rclite::Arc;
let foo = Arc::new(vec![1.0, 2.0, 3.0]);
// The two syntaxes below are equivalent.
let a = foo.clone();
let b = Arc::clone(&foo);
// a, b, and foo are all Arcs that point to the same memory location
use rclite::Arc;

let arc = Arc::new(());
// Method-call syntax
let arc2 = arc.clone();
// Fully qualified syntax
let arc3 = Arc::clone(&arc);

Implementations§

source§

impl<T> Arc<T>

source

pub fn new(data: T) -> Arc<T>

Constructs a new Arc<T>.

Examples
use rclite::Arc;

let tada = Arc::new("Tada!".to_string());
source

pub fn pin(data: T) -> Pin<Arc<T>>

Constructs a new Pin<Arc<T>>. If T does not implement Unpin, then data will be pinned in memory and unable to be moved.

source

pub fn as_ptr(&self) -> *const T

Gives you a pointer to the data. The reference count stays the same and the Arc<T> isn’t used up. The pointer stays valid as long as there are strong references to the Arc<T>.

Examples
use rclite::Arc;

let x = Arc::new("hello".to_owned());
let y = Arc::clone(&x);
let x_ptr = Arc::as_ptr(&x);
assert_eq!(x_ptr, Arc::as_ptr(&y));
assert_eq!(unsafe { &*x_ptr }, "hello");
source

pub fn into_raw(this: Self) -> *const T

Turns Arc<T> into a raw pointer, must be converted back to Arc<T> with Arc::from_raw to avoid memory leak.

Examples
use rclite::Arc;

let x = Arc::new("hello".to_owned());
let x_ptr = Arc::into_raw(x);
assert_eq!(unsafe { &*x_ptr }, "hello");
// reconstruct arc to drop the reference and avoid memory leaks
unsafe { Arc::from_raw(x_ptr) };
source

pub unsafe fn from_raw(ptr: *const T) -> Self

Constructs an Arc<T> from a raw pointer. The raw pointer must have been from Arc<U>::into_raw where U and T must have the same size and alignment. Improper use may lead to memory unsafe operations.

Safety

It’s only safe to construct back references that are generated with Arc::into_raw, converting any other references may lead to undefined behaivior.

Examples
use rclite::Arc;

let x = Arc::new("hello".to_owned());
let x_ptr = Arc::into_raw(x);

unsafe {
    // Convert back to an [`Arc<T>`] to prevent leak.
    let x = Arc::from_raw(x_ptr);
    assert_eq!(&*x, "hello");

    // Further calls to [`Arc::from_raw(x_ptr)`] would be memory-unsafe.
}

// The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
source

pub fn strong_count(&self) -> usize

Gets the number of strong pointers to an allocation. Be careful as another thread can change the count at any time.

Examples
use rclite::Arc;

let five = Arc::new(5);
let _also_five = Arc::clone(&five);

// This assertion is deterministic because we haven't shared
// the [`Arc<T>`] between threads.
assert_eq!(2, Arc::strong_count(&five));
source

pub fn ptr_eq(this: &Self, other: &Self) -> bool

Compares if two Arcs reference the same allocation, similar to ptr::eq. Note: The same caveats apply when comparing dyn Trait pointers.

Examples
use rclite::Arc;

let five = Arc::new(5);
let same_five = Arc::clone(&five);
let other_five = Arc::new(5);

assert!(Arc::ptr_eq(&five, &same_five));
assert!(!Arc::ptr_eq(&five, &other_five));
source

pub fn try_unwrap(this: Self) -> Result<T, Self>

If there’s only one strong reference, returns the inner value. If not, returns an error with the Arc passed in.

Examples
use rclite::Arc;

let x = Arc::new(3);
assert_eq!(Arc::try_unwrap(x).unwrap(), 3);

let x = Arc::new(4);
let _y = Arc::clone(&x);
assert_eq!(*Arc::try_unwrap(x).unwrap_err(), 4);
source

pub fn get_mut(this: &mut Self) -> Option<&mut T>

Returns a mutable reference to the inner value of the given Arc if this is the only Arc pointing to it.

Returns None otherwise because it is not safe to mutate a shared value.

See also make_mut, which clones the inner value when there are other Arc pointers.

Examples
use rclite::Arc;

let mut x = Arc::new(3);

// Get a mutable reference to the inner value.
*Arc::get_mut(&mut x).unwrap() = 4;
assert_eq!(*x, 4);

// There are now two Arcs pointing to the same value, so `get_mut()` returns `None`.
let _y = Arc::clone(&x);
assert!(Arc::get_mut(&mut x).is_none());
source

pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T

Returns a mutable reference into the given Arc without checking if it is safe to do so.

This method is faster than get_mut since it avoids any runtime checks. However, it is unsafe to use unless you can guarantee that no other Arc pointers to the same allocation exist and that they are not dereferenced or have active borrows for the duration of the returned borrow.

Safety

You can use get_mut_unchecked if all of the following conditions are met:

  • No other Arc pointers to the same allocation exist.
  • The inner type of all Arc pointers is exactly the same (including lifetimes).
  • No other Arc pointers are dereferenced or have active borrows for the duration of the returned mutable borrow.

These conditions are trivially satisfied immediately after creating a new Arc with Arc::new.

Examples
use rclite::Arc;

let mut x = Arc::new(String::new());
unsafe {
    Arc::get_mut_unchecked(&mut x).push_str("foo")
}
assert_eq!(*x, "foo");
source

pub fn into_inner(this: Self) -> Option<T>

Returns the inner value of the Arc if it’s the only strong reference.

If the Arc has multiple strong references, None is returned. If Arc::into_inner is called on every clone of this Arc, exactly one of the calls will return the inner value, ensuring it’s not dropped.

Example
use rclite::Arc;

let x = Arc::new(3);
let y = Arc::clone(&x);

let x_thread = std::thread::spawn(|| Arc::into_inner(x));
let y_thread = std::thread::spawn(|| Arc::into_inner(y));

let x_inner_value = x_thread.join().unwrap();
let y_inner_value = y_thread.join().unwrap();

assert!(matches!(
    (x_inner_value, y_inner_value),
    (None, Some(3)) | (Some(3), None)
));
source§

impl<T: Clone> Arc<T>

source

pub fn unwrap_or_clone(this: Self) -> T

If there is only one reference to T, removes it and returns it. Otherwise, creates a copy of T and returns it. If rc_t is an Arc<T>, this function behaves like calling (*rc_t).clone(), but avoids copying the value if possible.

Examples
use rclite::Arc;

let inner = String::from("test");
let ptr = inner.as_ptr();

let rc = Arc::new(inner);
let inner = Arc::unwrap_or_clone(rc);
// The inner value was not cloned
assert_eq!(ptr, inner.as_ptr());

let rc = Arc::new(inner);
let rc2 = rc.clone();
let inner = Arc::unwrap_or_clone(rc);
// Because there were 2 references, we had to clone the inner value.
assert_ne!(ptr, inner.as_ptr());
// `rc2` is the last reference, so when we unwrap it we get back
// the original `String`.
let inner = Arc::unwrap_or_clone(rc2);
assert_eq!(ptr, inner.as_ptr());
source

pub fn make_mut(this: &mut Arc<T>) -> &mut T

Returns a mutable reference to the inner value of the given Arc, ensuring that it has unique ownership.

If there are other Arc pointers to the same allocation, then make_mut will clone the inner value to a new allocation to ensure unique ownership. This is also referred to as “clone-on-write”.

Unlike get_mut, which only returns a mutable reference if there are no other pointers to the same allocation, make_mut always returns a mutable reference to the unique allocation.

Examples
use rclite::Arc;

let mut data = Arc::new(5);

*Arc::make_mut(&mut data) += 1;         // Won't clone anything
let mut other_data = Arc::clone(&data); // Won't clone inner data
*Arc::make_mut(&mut data) += 1;         // Clones inner data
*Arc::make_mut(&mut data) += 1;         // Won't clone anything
*Arc::make_mut(&mut other_data) *= 2;   // Won't clone anything

// Now `data` and `other_data` point to different allocations.
assert_eq!(*data, 8);
assert_eq!(*other_data, 12);
See also
  • get_mut: Returns a mutable reference to the inner value of the given Arc, but only if there are no other pointers to the same allocation.
  • clone: Clones the Arc pointer, but not the inner value.

Trait Implementations§

source§

impl<T> AsRef<T> for Arc<T>

An implementation of the AsRef trait for Arc<T>.

This allows an Arc<T> to be treated as a reference to T.

Examples

use rclite::Arc;

let data = Arc::new(42);
let reference: &i32 = data.as_ref();
assert_eq!(*reference, 42);
source§

fn as_ref(&self) -> &T

Returns a reference to the inner value of the Arc<T>.

Examples
use rclite::Arc;

let data = Arc::new("Hello, world!".to_string());
let reference: &String = data.as_ref();
assert_eq!(reference, "Hello, world!");
source§

impl<T> Borrow<T> for Arc<T>

This trait allows for a value to be borrowed as a reference to a given type. It is typically used for generic code that can work with borrowed values of different types.

This implementation for Rc<T> allows for an Rc<T> to be borrowed as a shared reference to T.

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> Clone for Arc<T>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Arc<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Default> Default for Arc<T>

source§

fn default() -> Arc<T>

Returns the “default value” for a type. Read more
source§

impl<T> Deref for Arc<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T: Display> Display for Arc<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Drop for Arc<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<T> From<T> for Arc<T>

source§

fn from(value: T) -> Self

Converts to this type from the input type.
source§

impl<T: Hash> Hash for Arc<T>

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T: Ord> Ord for Arc<T>

source§

fn cmp(&self, other: &Arc<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere Self: Sized + PartialOrd<Self>,

Restrict a value to a certain interval. Read more
source§

impl<T: PartialEq> PartialEq<Arc<T>> for Arc<T>

source§

fn eq(&self, other: &Arc<T>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd> PartialOrd<Arc<T>> for Arc<T>

source§

fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
source§

fn lt(&self, other: &Arc<T>) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
source§

fn le(&self, other: &Arc<T>) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
source§

fn gt(&self, other: &Arc<T>) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
source§

fn ge(&self, other: &Arc<T>) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl<T> Pointer for Arc<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl<T: Eq> Eq for Arc<T>

source§

impl<T: Sync + Send> Send for Arc<T>

source§

impl<T: Sync + Send> Sync for Arc<T>

source§

impl<T> Unpin for Arc<T>

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Arc<T>

§

impl<T> !UnwindSafe for Arc<T>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<!> for T

source§

fn from(t: !) -> T

Converts to this type from the input type.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for Twhere T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.