pull out allocator_api feature

This commit is contained in:
Corwin 2024-05-14 22:35:50 +01:00
parent b316ce2cbc
commit a2c127b72b
No known key found for this signature in database
5 changed files with 100 additions and 10 deletions

View file

@ -6,6 +6,9 @@ license = "MPL-2.0"
description = "A simple no_std hashmap implementation intended for use in the `agb` library" description = "A simple no_std hashmap implementation intended for use in the `agb` library"
repository = "https://github.com/agbrs/agb" repository = "https://github.com/agbrs/agb"
[features]
allocator_api = []
[dependencies] [dependencies]
rustc-hash = { version = "1", default-features = false } rustc-hash = { version = "1", default-features = false }

View file

@ -1,7 +1,7 @@
//! A lot of the documentation for this module was copied straight out of the rust //! A lot of the documentation for this module was copied straight out of the rust
//! standard library. The implementation however is not. //! standard library. The implementation however is not.
#![no_std] #![no_std]
#![feature(allocator_api)] #![cfg_attr(feature = "allocator_api", feature(allocator_api))]
#![deny(clippy::all)] #![deny(clippy::all)]
#![deny(clippy::must_use_candidate)] #![deny(clippy::must_use_candidate)]
#![deny(missing_docs)] #![deny(missing_docs)]
@ -26,9 +26,25 @@
extern crate alloc; extern crate alloc;
use alloc::{alloc::Global, vec::Vec}; pub(crate) use allocate::{Allocator, Global};
#[cfg(not(feature = "allocator_api"))]
mod allocate {
pub trait Allocator {}
#[derive(Copy, Clone)]
pub struct Global;
impl Allocator for Global {}
}
#[cfg(feature = "allocator_api")]
mod allocate {
pub(crate) use alloc::alloc::Global;
pub(crate) use core::alloc::Allocator;
}
use core::{ use core::{
alloc::Allocator,
borrow::Borrow, borrow::Borrow,
fmt::Debug, fmt::Debug,
hash::{BuildHasher, BuildHasherDefault, Hash}, hash::{BuildHasher, BuildHasherDefault, Hash},
@ -577,7 +593,8 @@ impl<K, V, ALLOCATOR: ClonableAllocator> IntoIterator for HashMap<K, V, ALLOCATO
} }
mod entries { mod entries {
use core::{alloc::Allocator, hash::Hash}; use crate::allocate::Allocator;
use core::hash::Hash;
use super::{ClonableAllocator, HashMap, HashType}; use super::{ClonableAllocator, HashMap, HashType};
@ -942,6 +959,8 @@ impl core::ops::Add<i32> for HashType {
mod test { mod test {
use core::{cell::RefCell, hash::Hasher}; use core::{cell::RefCell, hash::Hasher};
use alloc::vec::Vec;
use super::*; use super::*;
#[test] #[test]

View file

@ -1,12 +1,14 @@
use core::{alloc::Allocator, borrow::Borrow, mem}; use core::{borrow::Borrow, mem};
use alloc::{alloc::Global, vec::Vec};
use crate::allocate::{Allocator, Global};
use crate::{node::Node, number_before_resize, ClonableAllocator, HashType}; use crate::{node::Node, number_before_resize, ClonableAllocator, HashType};
mod vec;
use vec::MyVec;
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct NodeStorage<K, V, ALLOCATOR: Allocator = Global> { pub(crate) struct NodeStorage<K, V, ALLOCATOR: Allocator = Global> {
nodes: Vec<Node<K, V>, ALLOCATOR>, nodes: MyVec<Node<K, V>, ALLOCATOR>,
max_distance_to_initial_bucket: i32, max_distance_to_initial_bucket: i32,
number_of_items: usize, number_of_items: usize,
@ -17,7 +19,7 @@ impl<K, V, ALLOCATOR: ClonableAllocator> NodeStorage<K, V, ALLOCATOR> {
pub(crate) fn with_size_in(capacity: usize, alloc: ALLOCATOR) -> Self { pub(crate) fn with_size_in(capacity: usize, alloc: ALLOCATOR) -> Self {
assert!(capacity.is_power_of_two(), "Capacity must be a power of 2"); assert!(capacity.is_power_of_two(), "Capacity must be a power of 2");
let mut nodes = Vec::with_capacity_in(capacity, alloc); let mut nodes = MyVec::with_capacity_in(capacity, alloc);
for _ in 0..capacity { for _ in 0..capacity {
nodes.push(Node::new()); nodes.push(Node::new());
} }

View file

@ -0,0 +1,66 @@
use core::ops::{Deref, DerefMut};
use alloc::vec::Vec;
use crate::{Allocator, Global};
pub(crate) use inner::MyVec;
#[cfg(not(feature = "allocator_api"))]
mod inner {
use super::*;
#[derive(Clone)]
pub(crate) struct MyVec<T, A: Allocator = Global>(Vec<T>, A);
impl<T, A: Allocator> MyVec<T, A> {
pub(crate) fn with_capacity_in(capacity: usize, allocator: A) -> Self {
Self(Vec::with_capacity(capacity), allocator)
}
pub(crate) fn allocator(&self) -> &A {
&self.1
}
}
impl<T, A: Allocator> Deref for MyVec<T, A> {
type Target = Vec<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T, A: Allocator> DerefMut for MyVec<T, A> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
}
#[cfg(feature = "allocator_api")]
mod inner {
use super::*;
#[derive(Clone)]
pub(crate) struct MyVec<T, A: Allocator = Global>(Vec<T, A>);
impl<T, A: Allocator> MyVec<T, A> {
pub(crate) fn with_capacity_in(capacity: usize, allocator: A) -> Self {
Self(Vec::with_capacity_in(capacity, allocator))
}
}
impl<T, A: Allocator> Deref for MyVec<T, A> {
type Target = Vec<T, A>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T, A: Allocator> DerefMut for MyVec<T, A> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
}

View file

@ -19,7 +19,7 @@ agb_image_converter = { version = "0.19.1", path = "../agb-image-converter" }
agb_sound_converter = { version = "0.19.1", path = "../agb-sound-converter" } agb_sound_converter = { version = "0.19.1", path = "../agb-sound-converter" }
agb_macros = { version = "0.19.1", path = "../agb-macros" } agb_macros = { version = "0.19.1", path = "../agb-macros" }
agb_fixnum = { version = "0.19.1", path = "../agb-fixnum" } agb_fixnum = { version = "0.19.1", path = "../agb-fixnum" }
agb_hashmap = { version = "0.19.1", path = "../agb-hashmap" } agb_hashmap = { version = "0.19.1", path = "../agb-hashmap", features = ["allocator_api"] }
bilge = "0.2" bilge = "0.2"
qrcodegen-no-heap = { version = "1.8", optional = true } qrcodegen-no-heap = { version = "1.8", optional = true }
portable-atomic = { version = "1.6.0", default-features = false, features = ["unsafe-assume-single-core"] } portable-atomic = { version = "1.6.0", default-features = false, features = ["unsafe-assume-single-core"] }