Skip to content

Commit 27b7bf8

Browse files
author
Tage Johansson
committed
Add support for custom allocators by the allocator-api2 crate.
This commit adds allocator-api2 (a drop-in replacement for the `Allocator` trait on stable) as a dependency. The underlying `Vec` is replaced by `allocator_api2::vec::Vec`, and the type signiture of `VecMap<T>` is changed to `VecMap<T, A: Allocator = Global>`. It adds the methods `new_in()` and `with_capacity_in()` which creates a `VecMap` with a custom allocator. The old `new()` and `with_capacity()` methods are not removed and defaults to the default global allocator. I think that this commit is backwards compatable.
1 parent 5a1457d commit 27b7bf8

File tree

2 files changed

+79
-49
lines changed

2 files changed

+79
-49
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ exclude = ["/.travis.yml", "/deploy-docs.sh"]
4343
eders = [ "serde" ]
4444

4545
[dependencies]
46+
allocator-api2 = "0.2.20"
4647
serde = { version = "1.0", features = [ "derive" ], optional = true }

src/lib.rs

Lines changed: 78 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,17 @@ extern crate serde;
2222

2323
use self::Entry::*;
2424

25+
use allocator_api2::{
26+
alloc::{Allocator, Global},
27+
vec::{self, Vec},
28+
};
2529
use std::cmp::{max, Ordering};
2630
use std::fmt;
2731
use std::hash::{Hash, Hasher};
2832
use std::iter::{Enumerate, FilterMap, FromIterator};
2933
use std::mem::{replace, swap};
3034
use std::ops::{Index, IndexMut};
3135
use std::slice;
32-
use std::vec;
3336

3437
/// A map optimized for small integer keys.
3538
///
@@ -64,29 +67,29 @@ use std::vec;
6467
/// assert!(months.is_empty());
6568
/// ```
6669
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
67-
pub struct VecMap<V> {
70+
pub struct VecMap<V, A: Allocator = Global> {
6871
n: usize,
69-
v: Vec<Option<V>>,
72+
v: Vec<Option<V>, A>,
7073
}
7174

7275
/// A view into a single entry in a map, which may either be vacant or occupied.
73-
pub enum Entry<'a, V> {
76+
pub enum Entry<'a, V, A: Allocator = Global> {
7477
/// A vacant Entry
75-
Vacant(VacantEntry<'a, V>),
78+
Vacant(VacantEntry<'a, V, A>),
7679

7780
/// An occupied Entry
78-
Occupied(OccupiedEntry<'a, V>),
81+
Occupied(OccupiedEntry<'a, V, A>),
7982
}
8083

8184
/// A vacant Entry.
82-
pub struct VacantEntry<'a, V> {
83-
map: &'a mut VecMap<V>,
85+
pub struct VacantEntry<'a, V, A: Allocator = Global> {
86+
map: &'a mut VecMap<V, A>,
8487
index: usize,
8588
}
8689

8790
/// An occupied Entry.
88-
pub struct OccupiedEntry<'a, V> {
89-
map: &'a mut VecMap<V>,
91+
pub struct OccupiedEntry<'a, V, A: Allocator = Global> {
92+
map: &'a mut VecMap<V, A>,
9093
index: usize,
9194
}
9295

@@ -97,7 +100,7 @@ impl<V> Default for VecMap<V> {
97100
}
98101
}
99102

100-
impl<V: Hash> Hash for VecMap<V> {
103+
impl<V: Hash, A: Allocator> Hash for VecMap<V, A> {
101104
fn hash<H: Hasher>(&self, state: &mut H) {
102105
// In order to not traverse the `VecMap` twice, count the elements
103106
// during iteration.
@@ -120,7 +123,7 @@ impl<V> VecMap<V> {
120123
/// let mut map: VecMap<&str> = VecMap::new();
121124
/// ```
122125
pub fn new() -> Self {
123-
VecMap { n: 0, v: vec![] }
126+
VecMap::new_in(Default::default())
124127
}
125128

126129
/// Creates an empty `VecMap` with space for at least `capacity`
@@ -133,9 +136,25 @@ impl<V> VecMap<V> {
133136
/// let mut map: VecMap<&str> = VecMap::with_capacity(10);
134137
/// ```
135138
pub fn with_capacity(capacity: usize) -> Self {
139+
VecMap::with_capacity_in(capacity, Default::default())
140+
}
141+
}
142+
143+
impl<V, A: Allocator> VecMap<V, A> {
144+
/// Creates an empty `VecMap` with a custom allocator.
145+
pub fn new_in(alloc: A) -> Self {
136146
VecMap {
137147
n: 0,
138-
v: Vec::with_capacity(capacity),
148+
v: Vec::new_in(alloc),
149+
}
150+
}
151+
152+
/// Creates an empty `VecMap` with space for at least `capacity`
153+
/// elements before resizing, in a custom allocator.
154+
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
155+
VecMap {
156+
n: 0,
157+
v: Vec::with_capacity_in(capacity, alloc),
139158
}
140159
}
141160

@@ -221,6 +240,11 @@ impl<V> VecMap<V> {
221240
self.v.shrink_to_fit()
222241
}
223242

243+
/// Returns a reference to the allocator for the `VecMap`.
244+
pub fn allocator(&self) -> &A {
245+
self.v.allocator()
246+
}
247+
224248
/// Returns an iterator visiting all keys in ascending order of the keys.
225249
/// The iterator's element type is `usize`.
226250
pub fn keys(&self) -> Keys<'_, V> {
@@ -355,8 +379,11 @@ impl<V> VecMap<V> {
355379
/// assert_eq!(b[3], "c");
356380
/// assert_eq!(b[4], "d");
357381
/// ```
358-
pub fn split_off(&mut self, at: usize) -> Self {
359-
let mut other = VecMap::new();
382+
pub fn split_off(&mut self, at: usize) -> Self
383+
where
384+
A: Copy,
385+
{
386+
let mut other = VecMap::new_in(*self.allocator());
360387

361388
if at == 0 {
362389
// Move all elements to other
@@ -414,7 +441,7 @@ impl<V> VecMap<V> {
414441
///
415442
/// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
416443
/// ```
417-
pub fn drain(&mut self) -> Drain<'_, V> {
444+
pub fn drain(&mut self) -> Drain<'_, V, A> {
418445
fn filter<A>((i, v): (usize, Option<A>)) -> Option<(usize, A)> {
419446
v.map(|v| (i, v))
420447
}
@@ -603,7 +630,7 @@ impl<V> VecMap<V> {
603630
///
604631
/// assert_eq!(count[1], 3);
605632
/// ```
606-
pub fn entry(&mut self, key: usize) -> Entry<'_, V> {
633+
pub fn entry(&mut self, key: usize) -> Entry<'_, V, A> {
607634
// FIXME(Gankro): this is basically the dumbest implementation of
608635
// entry possible, because weird non-lexical borrows issues make it
609636
// completely insane to do any other way. That said, Entry is a border-line
@@ -651,7 +678,7 @@ impl<V> VecMap<V> {
651678
}
652679
}
653680

654-
impl<'a, V> Entry<'a, V> {
681+
impl<'a, V, A: Allocator> Entry<'a, V, A> {
655682
/// Ensures a value is in the entry by inserting the default if empty, and
656683
/// returns a mutable reference to the value in the entry.
657684
pub fn or_insert(self, default: V) -> &'a mut V {
@@ -672,7 +699,7 @@ impl<'a, V> Entry<'a, V> {
672699
}
673700
}
674701

675-
impl<'a, V> VacantEntry<'a, V> {
702+
impl<'a, V, A: Allocator> VacantEntry<'a, V, A> {
676703
/// Sets the value of the entry with the VacantEntry's key,
677704
/// and returns a mutable reference to it.
678705
pub fn insert(self, value: V) -> &'a mut V {
@@ -682,7 +709,7 @@ impl<'a, V> VacantEntry<'a, V> {
682709
}
683710
}
684711

685-
impl<'a, V> OccupiedEntry<'a, V> {
712+
impl<'a, V, A: Allocator> OccupiedEntry<'a, V, A> {
686713
/// Gets a reference to the value in the entry.
687714
pub fn get(&self) -> &V {
688715
let index = self.index;
@@ -715,7 +742,7 @@ impl<'a, V> OccupiedEntry<'a, V> {
715742
}
716743
}
717744

718-
impl<V: Clone> Clone for VecMap<V> {
745+
impl<V: Clone, A: Allocator + Clone> Clone for VecMap<V, A> {
719746
#[inline]
720747
fn clone(&self) -> Self {
721748
VecMap {
@@ -731,29 +758,29 @@ impl<V: Clone> Clone for VecMap<V> {
731758
}
732759
}
733760

734-
impl<V: PartialEq> PartialEq for VecMap<V> {
761+
impl<V: PartialEq, A: Allocator> PartialEq for VecMap<V, A> {
735762
fn eq(&self, other: &Self) -> bool {
736763
self.n == other.n && self.iter().eq(other.iter())
737764
}
738765
}
739766

740-
impl<V: Eq> Eq for VecMap<V> {}
767+
impl<V: Eq, A: Allocator> Eq for VecMap<V, A> {}
741768

742-
impl<V: PartialOrd> PartialOrd for VecMap<V> {
769+
impl<V: PartialOrd, A: Allocator> PartialOrd for VecMap<V, A> {
743770
#[inline]
744771
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
745772
self.iter().partial_cmp(other.iter())
746773
}
747774
}
748775

749-
impl<V: Ord> Ord for VecMap<V> {
776+
impl<V: Ord, A: Allocator> Ord for VecMap<V, A> {
750777
#[inline]
751778
fn cmp(&self, other: &Self) -> Ordering {
752779
self.iter().cmp(other.iter())
753780
}
754781
}
755782

756-
impl<V: fmt::Debug> fmt::Debug for VecMap<V> {
783+
impl<V: fmt::Debug, A: Allocator> fmt::Debug for VecMap<V, A> {
757784
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
758785
f.debug_map().entries(self).finish()
759786
}
@@ -767,9 +794,9 @@ impl<V> FromIterator<(usize, V)> for VecMap<V> {
767794
}
768795
}
769796

770-
impl<T> IntoIterator for VecMap<T> {
797+
impl<T, A: Allocator> IntoIterator for VecMap<T, A> {
771798
type Item = (usize, T);
772-
type IntoIter = IntoIter<T>;
799+
type IntoIter = IntoIter<T, A>;
773800

774801
/// Returns an iterator visiting all key-value pairs in ascending order of
775802
/// the keys, consuming the original `VecMap`.
@@ -789,7 +816,7 @@ impl<T> IntoIterator for VecMap<T> {
789816
///
790817
/// assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
791818
/// ```
792-
fn into_iter(self) -> IntoIter<T> {
819+
fn into_iter(self) -> IntoIter<T, A> {
793820
IntoIter {
794821
n: self.n,
795822
yielded: 0,
@@ -798,7 +825,7 @@ impl<T> IntoIterator for VecMap<T> {
798825
}
799826
}
800827

801-
impl<'a, T> IntoIterator for &'a VecMap<T> {
828+
impl<'a, T, A: Allocator> IntoIterator for &'a VecMap<T, A> {
802829
type Item = (usize, &'a T);
803830
type IntoIter = Iter<'a, T>;
804831

@@ -807,7 +834,7 @@ impl<'a, T> IntoIterator for &'a VecMap<T> {
807834
}
808835
}
809836

810-
impl<'a, T> IntoIterator for &'a mut VecMap<T> {
837+
impl<'a, T, A: Allocator> IntoIterator for &'a mut VecMap<T, A> {
811838
type Item = (usize, &'a mut T);
812839
type IntoIter = IterMut<'a, T>;
813840

@@ -816,21 +843,21 @@ impl<'a, T> IntoIterator for &'a mut VecMap<T> {
816843
}
817844
}
818845

819-
impl<V> Extend<(usize, V)> for VecMap<V> {
846+
impl<V, A: Allocator> Extend<(usize, V)> for VecMap<V, A> {
820847
fn extend<I: IntoIterator<Item = (usize, V)>>(&mut self, iter: I) {
821848
for (k, v) in iter {
822849
self.insert(k, v);
823850
}
824851
}
825852
}
826853

827-
impl<'a, V: Copy> Extend<(usize, &'a V)> for VecMap<V> {
854+
impl<'a, V: Copy, A: Allocator> Extend<(usize, &'a V)> for VecMap<V, A> {
828855
fn extend<I: IntoIterator<Item = (usize, &'a V)>>(&mut self, iter: I) {
829856
self.extend(iter.into_iter().map(|(key, &value)| (key, value)));
830857
}
831858
}
832859

833-
impl<V> Index<usize> for VecMap<V> {
860+
impl<V, A: Allocator> Index<usize> for VecMap<V, A> {
834861
type Output = V;
835862

836863
#[inline]
@@ -839,7 +866,7 @@ impl<V> Index<usize> for VecMap<V> {
839866
}
840867
}
841868

842-
impl<'a, V> Index<&'a usize> for VecMap<V> {
869+
impl<'a, V, A: Allocator> Index<&'a usize> for VecMap<V, A> {
843870
type Output = V;
844871

845872
#[inline]
@@ -848,14 +875,14 @@ impl<'a, V> Index<&'a usize> for VecMap<V> {
848875
}
849876
}
850877

851-
impl<V> IndexMut<usize> for VecMap<V> {
878+
impl<V, A: Allocator> IndexMut<usize> for VecMap<V, A> {
852879
#[inline]
853880
fn index_mut(&mut self, i: usize) -> &mut V {
854881
self.get_mut(i).expect("key not present")
855882
}
856883
}
857884

858-
impl<'a, V> IndexMut<&'a usize> for VecMap<V> {
885+
impl<'a, V, A: Allocator> IndexMut<&'a usize> for VecMap<V, A> {
859886
#[inline]
860887
fn index_mut(&mut self, i: &usize) -> &mut V {
861888
self.get_mut(*i).expect("key not present")
@@ -985,21 +1012,21 @@ pub struct ValuesMut<'a, V> {
9851012
}
9861013

9871014
/// A consuming iterator over the key-value pairs of a map.
988-
pub struct IntoIter<V> {
1015+
pub struct IntoIter<V, A: Allocator = Global> {
9891016
n: usize,
9901017
yielded: usize,
991-
iter: Enumerate<vec::IntoIter<Option<V>>>,
1018+
iter: Enumerate<vec::IntoIter<Option<V>, A>>,
9921019
}
9931020

9941021
/// A draining iterator over the key-value pairs of a map.
995-
pub struct Drain<'a, V> {
1022+
pub struct Drain<'a, V, A: Allocator = Global> {
9961023
iter: FilterMap<
997-
Enumerate<vec::Drain<'a, Option<V>>>,
1024+
Enumerate<vec::Drain<'a, Option<V>, A>>,
9981025
fn((usize, Option<V>)) -> Option<(usize, V)>,
9991026
>,
10001027
}
10011028

1002-
impl<'a, V> Iterator for Drain<'a, V> {
1029+
impl<'a, V, A: Allocator> Iterator for Drain<'a, V, A> {
10031030
type Item = (usize, V);
10041031

10051032
fn next(&mut self) -> Option<(usize, V)> {
@@ -1010,9 +1037,9 @@ impl<'a, V> Iterator for Drain<'a, V> {
10101037
}
10111038
}
10121039

1013-
impl<'a, V> ExactSizeIterator for Drain<'a, V> {}
1040+
impl<'a, V, A: Allocator> ExactSizeIterator for Drain<'a, V, A> {}
10141041

1015-
impl<'a, V> DoubleEndedIterator for Drain<'a, V> {
1042+
impl<'a, V, A: Allocator> DoubleEndedIterator for Drain<'a, V, A> {
10161043
fn next_back(&mut self) -> Option<(usize, V)> {
10171044
self.iter.next_back()
10181045
}
@@ -1075,7 +1102,7 @@ impl<'a, V> DoubleEndedIterator for ValuesMut<'a, V> {
10751102
}
10761103
}
10771104

1078-
impl<V> Iterator for IntoIter<V> {
1105+
impl<V, A: Allocator> Iterator for IntoIter<V, A> {
10791106
type Item = (usize, V);
10801107

10811108
fn next(&mut self) -> Option<(usize, V)> {
@@ -1096,9 +1123,9 @@ impl<V> Iterator for IntoIter<V> {
10961123
}
10971124
}
10981125

1099-
impl<V> ExactSizeIterator for IntoIter<V> {}
1126+
impl<V, A: Allocator> ExactSizeIterator for IntoIter<V, A> {}
11001127

1101-
impl<V> DoubleEndedIterator for IntoIter<V> {
1128+
impl<V, A: Allocator> DoubleEndedIterator for IntoIter<V, A> {
11021129
fn next_back(&mut self) -> Option<(usize, V)> {
11031130
loop {
11041131
match self.iter.next_back() {
@@ -1112,11 +1139,13 @@ impl<V> DoubleEndedIterator for IntoIter<V> {
11121139

11131140
#[allow(dead_code)]
11141141
fn assert_properties() {
1115-
fn vec_map_covariant<'a, T>(map: VecMap<&'static T>) -> VecMap<&'a T> {
1142+
fn vec_map_covariant<'a, T, A: Allocator>(map: VecMap<&'static T, A>) -> VecMap<&'a T, A> {
11161143
map
11171144
}
11181145

1119-
fn into_iter_covariant<'a, T>(iter: IntoIter<&'static T>) -> IntoIter<&'a T> {
1146+
fn into_iter_covariant<'a, T, A: Allocator>(
1147+
iter: IntoIter<&'static T, A>,
1148+
) -> IntoIter<&'a T, A> {
11201149
iter
11211150
}
11221151

0 commit comments

Comments
 (0)