Skip to content

Latest commit

History

30 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

% containerof - Macros supporting intrusive data structures in Rust.

An intrusive structure is a general-purpose structure directly embedded within a containing structure, in order to add that general-purpose facility to the container. As an example, one might use an intrusive "link" structure to allow objects to be organized in a linked-list:

# #[macro_use]externcrate containerof;structLink{next:Option<ContainerLink>,}structList{head:Option<ContainerLink>,tail:Option<ContainerLink>,}structContainer{link:Link,}containerof_intrusive!(ContainerLink = Container:link::Link);
# fnmain(){}

While this module does not provide a linked-list implementation (for separation-of-concerns reasons, I believe a linked-list implementation belongs in a separate crate), it does provide some necessary abstractions for using intrusive structures:

  • The containerof_field_offset! macro, which identifies the location of a field in a containing structure. This isn't too useful in itself, but is necessary to support:
  • The containerof_intrusive! macro, which provides a newtype that describes the translation between the "intrusive" field and the "container" structure.

Usage

Here is an example implementation of Church-numerals using an intrusive linked-list:

#[macro_use]externcrate containerof;use containerof::*;structChurch{next:Option<ChurchLink>,}containerof_intrusive!(ChurchLink = Church:next::Option<ChurchLink>);implChurch{fnnew() -> OwnBox<Church>{unsafe{OwnBox::from_box(Box::new(Church{next:None}))}}fnpush(next:OwnBox<Church>) -> OwnBox<Church>{unsafe{OwnBox::from_box(Box::new(Church{next:Some(Intrusive::from_container(next))}))}}fnpop(me:OwnBox<Church>) -> Option<OwnBox<Church>>{let me = unsafe{ me.into_box()};match me.next{None => None,Some(x) => Some(unsafe{ x.into_container()}),}}}
# fnmain(){}

Concepts

containerof uses three main concepts for working with intrusive structures:

  1. The intrusive structure itself (Church.next in the above example);
  2. The containing structure (Church);
  3. The translation type, for getting a container from a field, or vice-versa (ChurchLink).

In addition, there are three auxiliary structures for managing ownership and borrowing of intrusive structures:

  1. OwnBox, which is a pointer type representing ownership of the container (even if all you have is a field reference).
  2. BorrowBox, which is a pointer type representing a borrow of the container.
  3. BorrowBoxMut, which is a pointer type representing a mutable borrow of the container.

Contributing

  1. Fork it ( https://github.com/aidancully/containerof/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

About

No description, website, or topics provided.

Resources

Stars

18 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages