diff --git a/Cargo.toml b/Cargo.toml index 8fc916c..89c6835 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,11 @@ description = "Support for bumpalo in scoped threads & rayon" [dependencies] bumpalo = "~3" +# This dependency provides a version of the unstable nightly Rust `Allocator` +# trait on stable Rust. Enabling this feature means that `bumpalo` will +# implement its `Allocator` trait. +allocator-api2 = { version = "0.2.8", default-features = false, optional = true } + [dev-dependencies] bumpalo = "~3" crossbeam-utils = "~0.8" @@ -27,6 +32,6 @@ default = [ collections = ["bumpalo/collections"] boxed = ["bumpalo/boxed"] allocator_api = ["bumpalo/allocator_api"] -allocator-api2 = ["bumpalo/allocator-api2"] +allocator-api2 = ["bumpalo/allocator-api2", "dep:allocator-api2"] serde = ["bumpalo/serde"] std = ["bumpalo/std"] diff --git a/src/lib.rs b/src/lib.rs index 06fac08..22ad1cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![doc(test(attr(deny(warnings))))] #![warn(missing_docs)] +#![cfg_attr(feature = "allocator_api", feature(allocator_api))] //! The Bumpalo Herd //! @@ -86,6 +87,12 @@ use std::mem::ManuallyDrop; use std::ptr::NonNull; use std::sync::Mutex; +#[cfg(feature = "allocator_api")] +use std::alloc::{AllocError, Allocator}; + +#[cfg(all(feature = "allocator-api2", not(feature = "allocator_api")))] +use allocator_api2::alloc::{AllocError, Allocator}; + use bumpalo::Bump; type HerdInner = Vec>; @@ -263,6 +270,49 @@ impl Drop for Member<'_> { } } +#[cfg(any(feature = "allocator_api", feature = "allocator-api2"))] +unsafe impl Allocator for &Member<'_> { + #[inline] + fn allocate(&self, layout: Layout) -> Result, AllocError> { + self.as_bump().allocate(layout) + } + + #[inline] + unsafe fn deallocate(&self, ptr: NonNull, layout: Layout) { + self.as_bump().deallocate(ptr, layout) + } + + #[inline] + unsafe fn shrink( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + self.as_bump().shrink(ptr, old_layout, new_layout) + } + + #[inline] + unsafe fn grow( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + self.as_bump().grow(ptr, old_layout, new_layout) + } + + #[inline] + unsafe fn grow_zeroed( + &self, + ptr: NonNull, + old_layout: Layout, + new_layout: Layout, + ) -> Result, AllocError> { + self.as_bump().grow_zeroed(ptr, old_layout, new_layout) + } +} + #[cfg(test)] // We disable stuff on that platform and are lazy to disable all the imports too, this is shorter. #[cfg_attr(all(miri, target_os = "windows"), allow(unused_imports))]