Skip to content

Add clone instances for arenas #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions stack-graphs/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,20 @@ impl<T> Drop for Arena<T> {
}
}

impl<T> Clone for Arena<T>
where
T: Clone,
{
fn clone(&self) -> Self {
let mut items = Vec::with_capacity(self.items.len());
items.extend((0..self.items.len()).map(|_| MaybeUninit::uninit()));
unsafe {
std::ptr::copy_nonoverlapping(self.items.as_ptr(), items.as_mut_ptr(), self.items.len())
};
Self { items }
}
}

impl<T> Arena<T> {
/// Creates a new arena.
pub fn new() -> Arena<T> {
Expand Down Expand Up @@ -271,6 +285,23 @@ impl<H, T> Drop for SupplementalArena<H, T> {
}
}

impl<H, T> Clone for SupplementalArena<H, T>
where
T: Clone,
{
fn clone(&self) -> Self {
let mut items = Vec::with_capacity(self.items.len());
items.extend((0..self.items.len()).map(|_| MaybeUninit::uninit()));
unsafe {
std::ptr::copy_nonoverlapping(self.items.as_ptr(), items.as_mut_ptr(), self.items.len())
};
Self {
items,
_phantom: PhantomData::default(),
}
}
}

impl<H, T> SupplementalArena<H, T> {
/// Creates a new, empty supplemental arena.
pub fn new() -> SupplementalArena<H, T> {
Expand Down Expand Up @@ -374,6 +405,15 @@ pub struct HandleSet<T> {
_phantom: PhantomData<T>,
}

impl<T> Clone for HandleSet<T> {
fn clone(&self) -> Self {
Self {
elements: self.elements.clone(),
_phantom: PhantomData::default(),
}
}
}

impl<T> HandleSet<T> {
/// Creates a new, empty handle set.
pub fn new() -> HandleSet<T> {
Expand Down Expand Up @@ -457,6 +497,7 @@ pub struct List<T> {

#[doc(hidden)]
#[repr(C)]
#[derive(Clone)]
pub struct ListCell<T> {
head: T,
// The value of this handle will be EMPTY_LIST_HANDLE if this is the last element of the list.
Expand Down Expand Up @@ -610,6 +651,7 @@ pub struct ReversibleList<T> {

#[repr(C)]
#[doc(hidden)]
#[derive(Clone)]
pub struct ReversibleListCell<T> {
head: T,
tail: Handle<ReversibleListCell<T>>,
Expand Down
1 change: 1 addition & 0 deletions stack-graphs/src/partial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2610,6 +2610,7 @@ struct Join {

/// Manages the state of a collection of partial paths built up as part of the partial-path-finding
/// algorithm or path-stitching algorithm.
#[derive(Clone)]
pub struct PartialPaths {
pub(crate) partial_symbol_stacks: DequeArena<PartialScopedSymbol>,
pub(crate) partial_scope_stacks: DequeArena<Handle<Node>>,
Expand Down
1 change: 1 addition & 0 deletions stack-graphs/src/stitching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ impl Candidates<Edge> for GraphEdges {
/// We've written the path-stitching algorithm so that you have a chance to only load in the
/// partial paths that are actually needed, placing them into a `Database` instance as they're
/// needed.
#[derive(Clone)]
pub struct Database {
pub(crate) partial_paths: Arena<PartialPath>,
pub(crate) local_nodes: HandleSet<Node>,
Expand Down