1
Fork 0

BTreeMap: Add alloc param

This commit is contained in:
Jacob Hughes 2022-03-10 04:55:24 -05:00
parent 872503d918
commit dc5951a6e5
11 changed files with 676 additions and 340 deletions

View file

@ -1,5 +1,6 @@
use super::merge_iter::MergeIterInner; use super::merge_iter::MergeIterInner;
use super::node::{self, Root}; use super::node::{self, Root};
use core::alloc::Allocator;
use core::iter::FusedIterator; use core::iter::FusedIterator;
impl<K, V> Root<K, V> { impl<K, V> Root<K, V> {
@ -14,8 +15,13 @@ impl<K, V> Root<K, V> {
/// a `BTreeMap`, both iterators should produce keys in strictly ascending /// a `BTreeMap`, both iterators should produce keys in strictly ascending
/// order, each greater than all keys in the tree, including any keys /// order, each greater than all keys in the tree, including any keys
/// already in the tree upon entry. /// already in the tree upon entry.
pub fn append_from_sorted_iters<I>(&mut self, left: I, right: I, length: &mut usize) pub fn append_from_sorted_iters<I, A: Allocator>(
where &mut self,
left: I,
right: I,
length: &mut usize,
alloc: &A,
) where
K: Ord, K: Ord,
I: Iterator<Item = (K, V)> + FusedIterator, I: Iterator<Item = (K, V)> + FusedIterator,
{ {
@ -23,13 +29,13 @@ impl<K, V> Root<K, V> {
let iter = MergeIter(MergeIterInner::new(left, right)); let iter = MergeIter(MergeIterInner::new(left, right));
// Meanwhile, we build a tree from the sorted sequence in linear time. // Meanwhile, we build a tree from the sorted sequence in linear time.
self.bulk_push(iter, length) self.bulk_push(iter, length, alloc)
} }
/// Pushes all key-value pairs to the end of the tree, incrementing a /// Pushes all key-value pairs to the end of the tree, incrementing a
/// `length` variable along the way. The latter makes it easier for the /// `length` variable along the way. The latter makes it easier for the
/// caller to avoid a leak when the iterator panicks. /// caller to avoid a leak when the iterator panicks.
pub fn bulk_push<I>(&mut self, iter: I, length: &mut usize) pub fn bulk_push<I, A: Allocator>(&mut self, iter: I, length: &mut usize, alloc: &A)
where where
I: Iterator<Item = (K, V)>, I: Iterator<Item = (K, V)>,
{ {
@ -58,7 +64,7 @@ impl<K, V> Root<K, V> {
} }
Err(_) => { Err(_) => {
// We are at the top, create a new root node and push there. // We are at the top, create a new root node and push there.
open_node = self.push_internal_level(); open_node = self.push_internal_level(alloc);
break; break;
} }
} }
@ -66,9 +72,9 @@ impl<K, V> Root<K, V> {
// Push key-value pair and new right subtree. // Push key-value pair and new right subtree.
let tree_height = open_node.height() - 1; let tree_height = open_node.height() - 1;
let mut right_tree = Root::new(); let mut right_tree = Root::new(alloc);
for _ in 0..tree_height { for _ in 0..tree_height {
right_tree.push_internal_level(); right_tree.push_internal_level(alloc);
} }
open_node.push(key, value, right_tree); open_node.push(key, value, right_tree);

View file

@ -1,13 +1,15 @@
use super::map::MIN_LEN; use super::map::MIN_LEN;
use super::node::{marker, ForceResult::*, Handle, LeftOrRight::*, NodeRef, Root}; use super::node::{marker, ForceResult::*, Handle, LeftOrRight::*, NodeRef, Root};
use core::alloc::Allocator;
impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
/// Stocks up a possibly underfull node by merging with or stealing from a /// Stocks up a possibly underfull node by merging with or stealing from a
/// sibling. If successful but at the cost of shrinking the parent node, /// sibling. If successful but at the cost of shrinking the parent node,
/// returns that shrunk parent node. Returns an `Err` if the node is /// returns that shrunk parent node. Returns an `Err` if the node is
/// an empty root. /// an empty root.
fn fix_node_through_parent( fn fix_node_through_parent<A: Allocator>(
self, self,
alloc: &A,
) -> Result<Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>>, Self> { ) -> Result<Option<NodeRef<marker::Mut<'a>, K, V, marker::Internal>>, Self> {
let len = self.len(); let len = self.len();
if len >= MIN_LEN { if len >= MIN_LEN {
@ -16,7 +18,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
match self.choose_parent_kv() { match self.choose_parent_kv() {
Ok(Left(mut left_parent_kv)) => { Ok(Left(mut left_parent_kv)) => {
if left_parent_kv.can_merge() { if left_parent_kv.can_merge() {
let parent = left_parent_kv.merge_tracking_parent(); let parent = left_parent_kv.merge_tracking_parent(alloc);
Ok(Some(parent)) Ok(Some(parent))
} else { } else {
left_parent_kv.bulk_steal_left(MIN_LEN - len); left_parent_kv.bulk_steal_left(MIN_LEN - len);
@ -25,7 +27,7 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
} }
Ok(Right(mut right_parent_kv)) => { Ok(Right(mut right_parent_kv)) => {
if right_parent_kv.can_merge() { if right_parent_kv.can_merge() {
let parent = right_parent_kv.merge_tracking_parent(); let parent = right_parent_kv.merge_tracking_parent(alloc);
Ok(Some(parent)) Ok(Some(parent))
} else { } else {
right_parent_kv.bulk_steal_right(MIN_LEN - len); right_parent_kv.bulk_steal_right(MIN_LEN - len);
@ -52,9 +54,9 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
/// ///
/// This method does not expect ancestors to already be underfull upon entry /// This method does not expect ancestors to already be underfull upon entry
/// and panics if it encounters an empty ancestor. /// and panics if it encounters an empty ancestor.
pub fn fix_node_and_affected_ancestors(mut self) -> bool { pub fn fix_node_and_affected_ancestors<A: Allocator>(mut self, alloc: &A) -> bool {
loop { loop {
match self.fix_node_through_parent() { match self.fix_node_through_parent(alloc) {
Ok(Some(parent)) => self = parent.forget_type(), Ok(Some(parent)) => self = parent.forget_type(),
Ok(None) => return true, Ok(None) => return true,
Err(_) => return false, Err(_) => return false,
@ -65,29 +67,29 @@ impl<'a, K: 'a, V: 'a> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
impl<K, V> Root<K, V> { impl<K, V> Root<K, V> {
/// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty. /// Removes empty levels on the top, but keeps an empty leaf if the entire tree is empty.
pub fn fix_top(&mut self) { pub fn fix_top<A: Allocator>(&mut self, alloc: &A) {
while self.height() > 0 && self.len() == 0 { while self.height() > 0 && self.len() == 0 {
self.pop_internal_level(); self.pop_internal_level(alloc);
} }
} }
/// Stocks up or merge away any underfull nodes on the right border of the /// Stocks up or merge away any underfull nodes on the right border of the
/// tree. The other nodes, those that are not the root nor a rightmost edge, /// tree. The other nodes, those that are not the root nor a rightmost edge,
/// must already have at least MIN_LEN elements. /// must already have at least MIN_LEN elements.
pub fn fix_right_border(&mut self) { pub fn fix_right_border<A: Allocator>(&mut self, alloc: &A) {
self.fix_top(); self.fix_top(alloc);
if self.len() > 0 { if self.len() > 0 {
self.borrow_mut().last_kv().fix_right_border_of_right_edge(); self.borrow_mut().last_kv().fix_right_border_of_right_edge(alloc);
self.fix_top(); self.fix_top(alloc);
} }
} }
/// The symmetric clone of `fix_right_border`. /// The symmetric clone of `fix_right_border`.
pub fn fix_left_border(&mut self) { pub fn fix_left_border<A: Allocator>(&mut self, alloc: &A) {
self.fix_top(); self.fix_top(alloc);
if self.len() > 0 { if self.len() > 0 {
self.borrow_mut().first_kv().fix_left_border_of_left_edge(); self.borrow_mut().first_kv().fix_left_border_of_left_edge(alloc);
self.fix_top(); self.fix_top(alloc);
} }
} }
@ -113,16 +115,16 @@ impl<K, V> Root<K, V> {
} }
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> { impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
fn fix_left_border_of_left_edge(mut self) { fn fix_left_border_of_left_edge<A: Allocator>(mut self, alloc: &A) {
while let Internal(internal_kv) = self.force() { while let Internal(internal_kv) = self.force() {
self = internal_kv.fix_left_child().first_kv(); self = internal_kv.fix_left_child(alloc).first_kv();
debug_assert!(self.reborrow().into_node().len() > MIN_LEN); debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
} }
} }
fn fix_right_border_of_right_edge(mut self) { fn fix_right_border_of_right_edge<A: Allocator>(mut self, alloc: &A) {
while let Internal(internal_kv) = self.force() { while let Internal(internal_kv) = self.force() {
self = internal_kv.fix_right_child().last_kv(); self = internal_kv.fix_right_child(alloc).last_kv();
debug_assert!(self.reborrow().into_node().len() > MIN_LEN); debug_assert!(self.reborrow().into_node().len() > MIN_LEN);
} }
} }
@ -133,12 +135,15 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
/// provisions an extra element to allow merging its children in turn /// provisions an extra element to allow merging its children in turn
/// without becoming underfull. /// without becoming underfull.
/// Returns the left child. /// Returns the left child.
fn fix_left_child(self) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { fn fix_left_child<A: Allocator>(
self,
alloc: &A,
) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
let mut internal_kv = self.consider_for_balancing(); let mut internal_kv = self.consider_for_balancing();
let left_len = internal_kv.left_child_len(); let left_len = internal_kv.left_child_len();
debug_assert!(internal_kv.right_child_len() >= MIN_LEN); debug_assert!(internal_kv.right_child_len() >= MIN_LEN);
if internal_kv.can_merge() { if internal_kv.can_merge() {
internal_kv.merge_tracking_child() internal_kv.merge_tracking_child(alloc)
} else { } else {
// `MIN_LEN + 1` to avoid readjust if merge happens on the next level. // `MIN_LEN + 1` to avoid readjust if merge happens on the next level.
let count = (MIN_LEN + 1).saturating_sub(left_len); let count = (MIN_LEN + 1).saturating_sub(left_len);
@ -153,12 +158,15 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
/// provisions an extra element to allow merging its children in turn /// provisions an extra element to allow merging its children in turn
/// without becoming underfull. /// without becoming underfull.
/// Returns wherever the right child ended up. /// Returns wherever the right child ended up.
fn fix_right_child(self) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { fn fix_right_child<A: Allocator>(
self,
alloc: &A,
) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
let mut internal_kv = self.consider_for_balancing(); let mut internal_kv = self.consider_for_balancing();
let right_len = internal_kv.right_child_len(); let right_len = internal_kv.right_child_len();
debug_assert!(internal_kv.left_child_len() >= MIN_LEN); debug_assert!(internal_kv.left_child_len() >= MIN_LEN);
if internal_kv.can_merge() { if internal_kv.can_merge() {
internal_kv.merge_tracking_child() internal_kv.merge_tracking_child(alloc)
} else { } else {
// `MIN_LEN + 1` to avoid readjust if merge happens on the next level. // `MIN_LEN + 1` to avoid readjust if merge happens on the next level.
let count = (MIN_LEN + 1).saturating_sub(right_len); let count = (MIN_LEN + 1).saturating_sub(right_len);

View file

@ -9,6 +9,8 @@ use core::mem::{self, ManuallyDrop};
use core::ops::{Index, RangeBounds}; use core::ops::{Index, RangeBounds};
use core::ptr; use core::ptr;
use crate::alloc::{Allocator, Global};
use super::borrow::DormantMutRef; use super::borrow::DormantMutRef;
use super::dedup_sorted_iter::DedupSortedIter; use super::dedup_sorted_iter::DedupSortedIter;
use super::navigate::{LazyLeafRange, LeafRange}; use super::navigate::{LazyLeafRange, LeafRange};
@ -163,31 +165,41 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeMap")] #[cfg_attr(not(test), rustc_diagnostic_item = "BTreeMap")]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]
pub struct BTreeMap<K, V> { pub struct BTreeMap<
K,
V,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
root: Option<Root<K, V>>, root: Option<Root<K, V>>,
length: usize, length: usize,
pub(super) alloc: ManuallyDrop<A>,
} }
#[stable(feature = "btree_drop", since = "1.7.0")] #[stable(feature = "btree_drop", since = "1.7.0")]
unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for BTreeMap<K, V> { unsafe impl<#[may_dangle] K, #[may_dangle] V, A: Allocator> Drop for BTreeMap<K, V, A> {
fn drop(&mut self) { fn drop(&mut self) {
drop(unsafe { ptr::read(self) }.into_iter()) drop(unsafe { ptr::read(self) }.into_iter())
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> { impl<K: Clone, V: Clone, A: Clone + Allocator> Clone for BTreeMap<K, V, A> {
fn clone(&self) -> BTreeMap<K, V> { fn clone(&self) -> BTreeMap<K, V, A> {
fn clone_subtree<'a, K: Clone, V: Clone>( fn clone_subtree<'a, K: Clone, V: Clone, A: Clone + Allocator>(
node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>, node: NodeRef<marker::Immut<'a>, K, V, marker::LeafOrInternal>,
) -> BTreeMap<K, V> alloc: &A,
) -> BTreeMap<K, V, A>
where where
K: 'a, K: 'a,
V: 'a, V: 'a,
{ {
match node.force() { match node.force() {
Leaf(leaf) => { Leaf(leaf) => {
let mut out_tree = BTreeMap { root: Some(Root::new()), length: 0 }; let mut out_tree = BTreeMap {
root: Some(Root::new(alloc)),
length: 0,
alloc: ManuallyDrop::new((*alloc).clone()),
};
{ {
let root = out_tree.root.as_mut().unwrap(); // unwrap succeeds because we just wrapped let root = out_tree.root.as_mut().unwrap(); // unwrap succeeds because we just wrapped
@ -209,11 +221,11 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
out_tree out_tree
} }
Internal(internal) => { Internal(internal) => {
let mut out_tree = clone_subtree(internal.first_edge().descend()); let mut out_tree = clone_subtree(internal.first_edge().descend(), alloc);
{ {
let out_root = out_tree.root.as_mut().unwrap(); let out_root = out_tree.root.as_mut().unwrap();
let mut out_node = out_root.push_internal_level(); let mut out_node = out_root.push_internal_level(alloc);
let mut in_edge = internal.first_edge(); let mut in_edge = internal.first_edge();
while let Ok(kv) = in_edge.right_kv() { while let Ok(kv) = in_edge.right_kv() {
let (k, v) = kv.into_kv(); let (k, v) = kv.into_kv();
@ -221,7 +233,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
let k = (*k).clone(); let k = (*k).clone();
let v = (*v).clone(); let v = (*v).clone();
let subtree = clone_subtree(in_edge.descend()); let subtree = clone_subtree(in_edge.descend(), alloc);
// We can't destructure subtree directly // We can't destructure subtree directly
// because BTreeMap implements Drop // because BTreeMap implements Drop
@ -232,7 +244,7 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
(root, length) (root, length)
}; };
out_node.push(k, v, subroot.unwrap_or_else(Root::new)); out_node.push(k, v, subroot.unwrap_or_else(|| Root::new(alloc)));
out_tree.length += 1 + sublength; out_tree.length += 1 + sublength;
} }
} }
@ -243,14 +255,14 @@ impl<K: Clone, V: Clone> Clone for BTreeMap<K, V> {
} }
if self.is_empty() { if self.is_empty() {
BTreeMap::new() BTreeMap::new_in(ManuallyDrop::into_inner(self.alloc.clone()))
} else { } else {
clone_subtree(self.root.as_ref().unwrap().reborrow()) // unwrap succeeds because not empty clone_subtree(self.root.as_ref().unwrap().reborrow(), &*self.alloc) // unwrap succeeds because not empty
} }
} }
} }
impl<K, Q: ?Sized> super::Recover<Q> for BTreeMap<K, ()> impl<K, Q: ?Sized, A: Allocator> super::Recover<Q> for BTreeMap<K, (), A>
where where
K: Borrow<Q> + Ord, K: Borrow<Q> + Ord,
Q: Ord, Q: Ord,
@ -269,21 +281,29 @@ where
let (map, dormant_map) = DormantMutRef::new(self); let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.borrow_mut(); let root_node = map.root.as_mut()?.borrow_mut();
match root_node.search_tree(key) { match root_node.search_tree(key) {
Found(handle) => { Found(handle) => Some(
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_kv().0) OccupiedEntry { handle, dormant_map, alloc: &*map.alloc, _marker: PhantomData }
} .remove_kv()
.0,
),
GoDown(_) => None, GoDown(_) => None,
} }
} }
fn replace(&mut self, key: K) -> Option<K> { fn replace(&mut self, key: K) -> Option<K> {
let (map, dormant_map) = DormantMutRef::new(self); let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.get_or_insert_with(Root::new).borrow_mut(); let root_node = map.root.get_or_insert_with(|| Root::new(&*map.alloc)).borrow_mut();
match root_node.search_tree::<K>(&key) { match root_node.search_tree::<K>(&key) {
Found(mut kv) => Some(mem::replace(kv.key_mut(), key)), Found(mut kv) => Some(mem::replace(kv.key_mut(), key)),
GoDown(handle) => { GoDown(handle) => {
VacantEntry { key, handle: Some(handle), dormant_map, _marker: PhantomData } VacantEntry {
.insert(()); key,
handle: Some(handle),
dormant_map,
alloc: &*map.alloc,
_marker: PhantomData,
}
.insert(());
None None
} }
} }
@ -343,12 +363,17 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> {
/// [`IntoIterator`]: core::iter::IntoIterator /// [`IntoIterator`]: core::iter::IntoIterator
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]
pub struct IntoIter<K, V> { pub struct IntoIter<
K,
V,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
range: LazyLeafRange<marker::Dying, K, V>, range: LazyLeafRange<marker::Dying, K, V>,
length: usize, length: usize,
alloc: A,
} }
impl<K, V> IntoIter<K, V> { impl<K, V, A: Allocator> IntoIter<K, V, A> {
/// Returns an iterator of references over the remaining items. /// Returns an iterator of references over the remaining items.
#[inline] #[inline]
pub(super) fn iter(&self) -> Iter<'_, K, V> { pub(super) fn iter(&self) -> Iter<'_, K, V> {
@ -357,7 +382,7 @@ impl<K, V> IntoIter<K, V> {
} }
#[stable(feature = "collection_debug", since = "1.17.0")] #[stable(feature = "collection_debug", since = "1.17.0")]
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> { impl<K: Debug, V: Debug, A: Allocator> Debug for IntoIter<K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish() f.debug_list().entries(self.iter()).finish()
} }
@ -371,7 +396,7 @@ impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
/// [`keys`]: BTreeMap::keys /// [`keys`]: BTreeMap::keys
#[must_use = "iterators are lazy and do nothing unless consumed"] #[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Keys<'a, K: 'a, V: 'a> { pub struct Keys<'a, K, V> {
inner: Iter<'a, K, V>, inner: Iter<'a, K, V>,
} }
@ -390,7 +415,7 @@ impl<K: fmt::Debug, V> fmt::Debug for Keys<'_, K, V> {
/// [`values`]: BTreeMap::values /// [`values`]: BTreeMap::values
#[must_use = "iterators are lazy and do nothing unless consumed"] #[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Values<'a, K: 'a, V: 'a> { pub struct Values<'a, K, V> {
inner: Iter<'a, K, V>, inner: Iter<'a, K, V>,
} }
@ -409,7 +434,7 @@ impl<K, V: fmt::Debug> fmt::Debug for Values<'_, K, V> {
/// [`values_mut`]: BTreeMap::values_mut /// [`values_mut`]: BTreeMap::values_mut
#[must_use = "iterators are lazy and do nothing unless consumed"] #[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "map_values_mut", since = "1.10.0")] #[stable(feature = "map_values_mut", since = "1.10.0")]
pub struct ValuesMut<'a, K: 'a, V: 'a> { pub struct ValuesMut<'a, K, V> {
inner: IterMut<'a, K, V>, inner: IterMut<'a, K, V>,
} }
@ -428,12 +453,12 @@ impl<K, V: fmt::Debug> fmt::Debug for ValuesMut<'_, K, V> {
/// [`into_keys`]: BTreeMap::into_keys /// [`into_keys`]: BTreeMap::into_keys
#[must_use = "iterators are lazy and do nothing unless consumed"] #[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
pub struct IntoKeys<K, V> { pub struct IntoKeys<K, V, A: Allocator = Global> {
inner: IntoIter<K, V>, inner: IntoIter<K, V, A>,
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K: fmt::Debug, V> fmt::Debug for IntoKeys<K, V> { impl<K: fmt::Debug, V, A: Allocator> fmt::Debug for IntoKeys<K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter().map(|(key, _)| key)).finish() f.debug_list().entries(self.inner.iter().map(|(key, _)| key)).finish()
} }
@ -447,12 +472,16 @@ impl<K: fmt::Debug, V> fmt::Debug for IntoKeys<K, V> {
/// [`into_values`]: BTreeMap::into_values /// [`into_values`]: BTreeMap::into_values
#[must_use = "iterators are lazy and do nothing unless consumed"] #[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
pub struct IntoValues<K, V> { pub struct IntoValues<
inner: IntoIter<K, V>, K,
V,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
inner: IntoIter<K, V, A>,
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V: fmt::Debug> fmt::Debug for IntoValues<K, V> { impl<K, V: fmt::Debug, A: Allocator> fmt::Debug for IntoValues<K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish() f.debug_list().entries(self.inner.iter().map(|(_, val)| val)).finish()
} }
@ -521,9 +550,11 @@ impl<K, V> BTreeMap<K, V> {
#[rustc_const_unstable(feature = "const_btree_new", issue = "71835")] #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")]
#[must_use] #[must_use]
pub const fn new() -> BTreeMap<K, V> { pub const fn new() -> BTreeMap<K, V> {
BTreeMap { root: None, length: 0 } BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(Global) }
} }
}
impl<K, V, A: Allocator> BTreeMap<K, V, A> {
/// Clears the map, removing all elements. /// Clears the map, removing all elements.
/// ///
/// # Examples /// # Examples
@ -540,9 +571,37 @@ impl<K, V> BTreeMap<K, V> {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) { pub fn clear(&mut self) {
*self = BTreeMap::new(); let alloc = unsafe {
// drop all elements and retrieve allocator
ptr::read(self).into_iter().into_alloc()
};
*self = BTreeMap::new_in(alloc);
} }
/// Makes a new empty BTreeMap with a reasonable choice for B.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # #![feature(allocator_api)]
/// # #![feature(btreemap_alloc)]
/// use std::collections::BTreeMap;
/// use std::alloc::Global;
///
/// let mut map = BTreeMap::new_in(Global);
///
/// // entries can now be inserted into the empty map
/// map.insert(1, "a");
/// ```
#[unstable(feature = "btreemap_alloc", issue = "32838")]
pub fn new_in(alloc: A) -> BTreeMap<K, V, A> {
BTreeMap { root: None, length: 0, alloc: ManuallyDrop::new(alloc) }
}
}
impl<K, V, A: Allocator> BTreeMap<K, V, A> {
/// Returns a reference to the value corresponding to the key. /// Returns a reference to the value corresponding to the key.
/// ///
/// The key may be any borrowed form of the map's key type, but the ordering /// The key may be any borrowed form of the map's key type, but the ordering
@ -648,14 +707,19 @@ impl<K, V> BTreeMap<K, V> {
/// assert_eq!(*map.get(&2).unwrap(), "b"); /// assert_eq!(*map.get(&2).unwrap(), "b");
/// ``` /// ```
#[unstable(feature = "map_first_last", issue = "62924")] #[unstable(feature = "map_first_last", issue = "62924")]
pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, K, V, A>>
where where
K: Ord, K: Ord,
{ {
let (map, dormant_map) = DormantMutRef::new(self); let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.borrow_mut(); let root_node = map.root.as_mut()?.borrow_mut();
let kv = root_node.first_leaf_edge().right_kv().ok()?; let kv = root_node.first_leaf_edge().right_kv().ok()?;
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData }) Some(OccupiedEntry {
handle: kv.forget_node_type(),
dormant_map,
alloc: &*map.alloc,
_marker: PhantomData,
})
} }
/// Removes and returns the first element in the map. /// Removes and returns the first element in the map.
@ -731,14 +795,19 @@ impl<K, V> BTreeMap<K, V> {
/// assert_eq!(*map.get(&2).unwrap(), "last"); /// assert_eq!(*map.get(&2).unwrap(), "last");
/// ``` /// ```
#[unstable(feature = "map_first_last", issue = "62924")] #[unstable(feature = "map_first_last", issue = "62924")]
pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V>> pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, K, V, A>>
where where
K: Ord, K: Ord,
{ {
let (map, dormant_map) = DormantMutRef::new(self); let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.borrow_mut(); let root_node = map.root.as_mut()?.borrow_mut();
let kv = root_node.last_leaf_edge().left_kv().ok()?; let kv = root_node.last_leaf_edge().left_kv().ok()?;
Some(OccupiedEntry { handle: kv.forget_node_type(), dormant_map, _marker: PhantomData }) Some(OccupiedEntry {
handle: kv.forget_node_type(),
dormant_map,
alloc: &*map.alloc,
_marker: PhantomData,
})
} }
/// Removes and returns the last element in the map. /// Removes and returns the last element in the map.
@ -891,7 +960,7 @@ impl<K, V> BTreeMap<K, V> {
/// assert_eq!(err.value, "b"); /// assert_eq!(err.value, "b");
/// ``` /// ```
#[unstable(feature = "map_try_insert", issue = "82766")] #[unstable(feature = "map_try_insert", issue = "82766")]
pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V>> pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V, A>>
where where
K: Ord, K: Ord,
{ {
@ -955,9 +1024,10 @@ impl<K, V> BTreeMap<K, V> {
let (map, dormant_map) = DormantMutRef::new(self); let (map, dormant_map) = DormantMutRef::new(self);
let root_node = map.root.as_mut()?.borrow_mut(); let root_node = map.root.as_mut()?.borrow_mut();
match root_node.search_tree(key) { match root_node.search_tree(key) {
Found(handle) => { Found(handle) => Some(
Some(OccupiedEntry { handle, dormant_map, _marker: PhantomData }.remove_entry()) OccupiedEntry { handle, dormant_map, alloc: &*map.alloc, _marker: PhantomData }
} .remove_entry(),
),
GoDown(_) => None, GoDown(_) => None,
} }
} }
@ -1019,6 +1089,7 @@ impl<K, V> BTreeMap<K, V> {
pub fn append(&mut self, other: &mut Self) pub fn append(&mut self, other: &mut Self)
where where
K: Ord, K: Ord,
A: Clone,
{ {
// Do we have to append anything at all? // Do we have to append anything at all?
if other.is_empty() { if other.is_empty() {
@ -1031,10 +1102,14 @@ impl<K, V> BTreeMap<K, V> {
return; return;
} }
let self_iter = mem::take(self).into_iter(); let self_iter =
let other_iter = mem::take(other).into_iter(); mem::replace(self, Self::new_in(ManuallyDrop::into_inner(self.alloc.clone())))
let root = self.root.get_or_insert_with(Root::new); .into_iter();
root.append_from_sorted_iters(self_iter, other_iter, &mut self.length) let other_iter =
mem::replace(other, Self::new_in(ManuallyDrop::into_inner(self.alloc.clone())))
.into_iter();
let root = self.root.get_or_insert_with(|| Root::new(&*self.alloc));
root.append_from_sorted_iters(self_iter, other_iter, &mut self.length, &*self.alloc)
} }
/// Constructs a double-ended iterator over a sub-range of elements in the map. /// Constructs a double-ended iterator over a sub-range of elements in the map.
@ -1141,21 +1216,31 @@ impl<K, V> BTreeMap<K, V> {
/// assert_eq!(count["a"], 3); /// assert_eq!(count["a"], 3);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn entry(&mut self, key: K) -> Entry<'_, K, V> pub fn entry(&mut self, key: K) -> Entry<'_, K, V, A>
where where
K: Ord, K: Ord,
{ {
let (map, dormant_map) = DormantMutRef::new(self); let (map, dormant_map) = DormantMutRef::new(self);
match map.root { match map.root {
None => Vacant(VacantEntry { key, handle: None, dormant_map, _marker: PhantomData }), None => Vacant(VacantEntry {
key,
handle: None,
dormant_map,
alloc: &*map.alloc,
_marker: PhantomData,
}),
Some(ref mut root) => match root.borrow_mut().search_tree(&key) { Some(ref mut root) => match root.borrow_mut().search_tree(&key) {
Found(handle) => { Found(handle) => Occupied(OccupiedEntry {
Occupied(OccupiedEntry { handle, dormant_map, _marker: PhantomData }) handle,
} dormant_map,
alloc: &*map.alloc,
_marker: PhantomData,
}),
GoDown(handle) => Vacant(VacantEntry { GoDown(handle) => Vacant(VacantEntry {
key, key,
handle: Some(handle), handle: Some(handle),
dormant_map, dormant_map,
alloc: &*map.alloc,
_marker: PhantomData, _marker: PhantomData,
}), }),
}, },
@ -1195,20 +1280,25 @@ impl<K, V> BTreeMap<K, V> {
pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self
where where
K: Borrow<Q> + Ord, K: Borrow<Q> + Ord,
A: Clone,
{ {
if self.is_empty() { if self.is_empty() {
return Self::new(); return Self::new_in(ManuallyDrop::into_inner(self.alloc.clone()));
} }
let total_num = self.len(); let total_num = self.len();
let left_root = self.root.as_mut().unwrap(); // unwrap succeeds because not empty let left_root = self.root.as_mut().unwrap(); // unwrap succeeds because not empty
let right_root = left_root.split_off(key); let right_root = left_root.split_off(key, &*self.alloc);
let (new_left_len, right_len) = Root::calc_split_length(total_num, &left_root, &right_root); let (new_left_len, right_len) = Root::calc_split_length(total_num, &left_root, &right_root);
self.length = new_left_len; self.length = new_left_len;
BTreeMap { root: Some(right_root), length: right_len } BTreeMap {
root: Some(right_root),
length: right_len,
alloc: ManuallyDrop::new((*self.alloc).clone()),
}
} }
/// Creates an iterator that visits all elements (key-value pairs) in /// Creates an iterator that visits all elements (key-value pairs) in
@ -1244,28 +1334,39 @@ impl<K, V> BTreeMap<K, V> {
/// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), [1, 3, 5, 7]); /// assert_eq!(odds.keys().copied().collect::<Vec<_>>(), [1, 3, 5, 7]);
/// ``` /// ```
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F> pub fn drain_filter<F>(&mut self, pred: F) -> DrainFilter<'_, K, V, F, &A>
where where
K: Ord, K: Ord,
F: FnMut(&K, &mut V) -> bool, F: FnMut(&K, &mut V) -> bool,
{ {
DrainFilter { pred, inner: self.drain_filter_inner() } let (inner, alloc) = self.drain_filter_inner();
DrainFilter { pred, inner, alloc }
} }
pub(super) fn drain_filter_inner(&mut self) -> DrainFilterInner<'_, K, V> pub(super) fn drain_filter_inner(&mut self) -> (DrainFilterInner<'_, K, V>, &A)
where where
K: Ord, K: Ord,
{ {
if let Some(root) = self.root.as_mut() { if let Some(root) = self.root.as_mut() {
let (root, dormant_root) = DormantMutRef::new(root); let (root, dormant_root) = DormantMutRef::new(root);
let front = root.borrow_mut().first_leaf_edge(); let front = root.borrow_mut().first_leaf_edge();
DrainFilterInner { (
length: &mut self.length, DrainFilterInner {
dormant_root: Some(dormant_root), length: &mut self.length,
cur_leaf_edge: Some(front), dormant_root: Some(dormant_root),
} cur_leaf_edge: Some(front),
},
&*self.alloc,
)
} else { } else {
DrainFilterInner { length: &mut self.length, dormant_root: None, cur_leaf_edge: None } (
DrainFilterInner {
length: &mut self.length,
dormant_root: None,
cur_leaf_edge: None,
},
&*self.alloc,
)
} }
} }
@ -1287,7 +1388,7 @@ impl<K, V> BTreeMap<K, V> {
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
pub fn into_keys(self) -> IntoKeys<K, V> { pub fn into_keys(self) -> IntoKeys<K, V, A> {
IntoKeys { inner: self.into_iter() } IntoKeys { inner: self.into_iter() }
} }
@ -1309,25 +1410,25 @@ impl<K, V> BTreeMap<K, V> {
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
pub fn into_values(self) -> IntoValues<K, V> { pub fn into_values(self) -> IntoValues<K, V, A> {
IntoValues { inner: self.into_iter() } IntoValues { inner: self.into_iter() }
} }
/// Makes a `BTreeMap` from a sorted iterator. /// Makes a `BTreeMap` from a sorted iterator.
pub(crate) fn bulk_build_from_sorted_iter<I>(iter: I) -> Self pub(crate) fn bulk_build_from_sorted_iter<I>(iter: I, alloc: A) -> Self
where where
K: Ord, K: Ord,
I: IntoIterator<Item = (K, V)>, I: IntoIterator<Item = (K, V)>,
{ {
let mut root = Root::new(); let mut root = Root::new(&alloc);
let mut length = 0; let mut length = 0;
root.bulk_push(DedupSortedIter::new(iter.into_iter()), &mut length); root.bulk_push(DedupSortedIter::new(iter.into_iter()), &mut length, &alloc);
BTreeMap { root: Some(root), length } BTreeMap { root: Some(root), length, alloc: ManuallyDrop::new(alloc) }
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> IntoIterator for &'a BTreeMap<K, V> { impl<'a, K, V, A: Allocator> IntoIterator for &'a BTreeMap<K, V, A> {
type Item = (&'a K, &'a V); type Item = (&'a K, &'a V);
type IntoIter = Iter<'a, K, V>; type IntoIter = Iter<'a, K, V>;
@ -1396,7 +1497,7 @@ impl<K, V> Clone for Iter<'_, K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> { impl<'a, K, V, A: Allocator> IntoIterator for &'a mut BTreeMap<K, V, A> {
type Item = (&'a K, &'a mut V); type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>; type IntoIter = IterMut<'a, K, V>;
@ -1406,7 +1507,7 @@ impl<'a, K, V> IntoIterator for &'a mut BTreeMap<K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> { impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V); type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<(&'a K, &'a mut V)> { fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
@ -1436,7 +1537,7 @@ impl<'a, K: 'a, V: 'a> Iterator for IterMut<'a, K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K: 'a, V: 'a> DoubleEndedIterator for IterMut<'a, K, V> { impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> { fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
if self.length == 0 { if self.length == 0 {
None None
@ -1466,28 +1567,41 @@ impl<'a, K, V> IterMut<'a, K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> IntoIterator for BTreeMap<K, V> { impl<K, V, A: Allocator> IntoIterator for BTreeMap<K, V, A> {
type Item = (K, V); type Item = (K, V);
type IntoIter = IntoIter<K, V>; type IntoIter = IntoIter<K, V, A>;
fn into_iter(self) -> IntoIter<K, V> { fn into_iter(self) -> IntoIter<K, V, A> {
let mut me = ManuallyDrop::new(self); let mut me = ManuallyDrop::new(self);
if let Some(root) = me.root.take() { if let Some(root) = me.root.take() {
let full_range = root.into_dying().full_range(); let full_range = root.into_dying().full_range();
IntoIter { range: full_range, length: me.length } IntoIter {
range: full_range,
length: me.length,
alloc: unsafe { ManuallyDrop::take(&mut me.alloc) },
}
} else { } else {
IntoIter { range: LazyLeafRange::none(), length: 0 } IntoIter {
range: LazyLeafRange::none(),
length: 0,
alloc: unsafe { ManuallyDrop::take(&mut me.alloc) },
}
} }
} }
} }
#[stable(feature = "btree_drop", since = "1.7.0")] #[stable(feature = "btree_drop", since = "1.7.0")]
impl<K, V> Drop for IntoIter<K, V> { impl<K, V, A: Allocator> Drop for IntoIter<K, V, A> {
fn drop(&mut self) { fn drop(&mut self) {
struct DropGuard<'a, K, V>(&'a mut IntoIter<K, V>); self.dealloc()
}
}
impl<K, V, A: Allocator> IntoIter<K, V, A> {
fn dealloc(&mut self) {
struct DropGuard<'a, K, V, A: Allocator>(&'a mut IntoIter<K, V, A>);
impl<'a, K, V> Drop for DropGuard<'a, K, V> { impl<'a, K, V, A: Allocator> Drop for DropGuard<'a, K, V, A> {
fn drop(&mut self) { fn drop(&mut self) {
// Continue the same loop we perform below. This only runs when unwinding, so we // Continue the same loop we perform below. This only runs when unwinding, so we
// don't have to care about panics this time (they'll abort). // don't have to care about panics this time (they'll abort).
@ -1507,18 +1621,18 @@ impl<K, V> Drop for IntoIter<K, V> {
} }
} }
impl<K, V> IntoIter<K, V> { impl<K, V, A: Allocator> IntoIter<K, V, A> {
/// Core of a `next` method returning a dying KV handle, /// Core of a `next` method returning a dying KV handle,
/// invalidated by further calls to this function and some others. /// invalidated by further calls to this function and some others.
fn dying_next( fn dying_next(
&mut self, &mut self,
) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> { ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
if self.length == 0 { if self.length == 0 {
self.range.deallocating_end(); self.range.deallocating_end(&self.alloc);
None None
} else { } else {
self.length -= 1; self.length -= 1;
Some(unsafe { self.range.deallocating_next_unchecked() }) Some(unsafe { self.range.deallocating_next_unchecked(&self.alloc) })
} }
} }
@ -1528,17 +1642,22 @@ impl<K, V> IntoIter<K, V> {
&mut self, &mut self,
) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> { ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
if self.length == 0 { if self.length == 0 {
self.range.deallocating_end(); self.range.deallocating_end(&self.alloc);
None None
} else { } else {
self.length -= 1; self.length -= 1;
Some(unsafe { self.range.deallocating_next_back_unchecked() }) Some(unsafe { self.range.deallocating_next_back_unchecked(&self.alloc) })
} }
} }
fn into_alloc(mut self) -> A {
self.dealloc(); // Deallocate, then don't drop as drop will also call dealloc
let iter = ManuallyDrop::new(self);
unsafe { ptr::read(&iter.alloc) }
}
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> Iterator for IntoIter<K, V> { impl<K, V, A: Allocator> Iterator for IntoIter<K, V, A> {
type Item = (K, V); type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> { fn next(&mut self) -> Option<(K, V)> {
@ -1552,7 +1671,7 @@ impl<K, V> Iterator for IntoIter<K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> DoubleEndedIterator for IntoIter<K, V> { impl<K, V, A: Allocator> DoubleEndedIterator for IntoIter<K, V, A> {
fn next_back(&mut self) -> Option<(K, V)> { fn next_back(&mut self) -> Option<(K, V)> {
// SAFETY: we consume the dying handle immediately. // SAFETY: we consume the dying handle immediately.
self.dying_next_back().map(unsafe { |kv| kv.into_key_val() }) self.dying_next_back().map(unsafe { |kv| kv.into_key_val() })
@ -1560,14 +1679,14 @@ impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> ExactSizeIterator for IntoIter<K, V> { impl<K, V, A: Allocator> ExactSizeIterator for IntoIter<K, V, A> {
fn len(&self) -> usize { fn len(&self) -> usize {
self.length self.length
} }
} }
#[stable(feature = "fused", since = "1.26.0")] #[stable(feature = "fused", since = "1.26.0")]
impl<K, V> FusedIterator for IntoIter<K, V> {} impl<K, V, A: Allocator> FusedIterator for IntoIter<K, V, A> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Keys<'a, K, V> { impl<'a, K, V> Iterator for Keys<'a, K, V> {
@ -1661,18 +1780,22 @@ impl<K, V> Clone for Values<'_, K, V> {
/// An iterator produced by calling `drain_filter` on BTreeMap. /// An iterator produced by calling `drain_filter` on BTreeMap.
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
pub struct DrainFilter<'a, K, V, F> pub struct DrainFilter<
where 'a,
K: 'a, K,
V: 'a, V,
F,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> where
F: 'a + FnMut(&K, &mut V) -> bool, F: 'a + FnMut(&K, &mut V) -> bool,
{ {
pred: F, pred: F,
inner: DrainFilterInner<'a, K, V>, inner: DrainFilterInner<'a, K, V>,
alloc: A,
} }
/// Most of the implementation of DrainFilter are generic over the type /// Most of the implementation of DrainFilter are generic over the type
/// of the predicate, thus also serving for BTreeSet::DrainFilter. /// of the predicate, thus also serving for BTreeSet::DrainFilter.
pub(super) struct DrainFilterInner<'a, K: 'a, V: 'a> { pub(super) struct DrainFilterInner<'a, K, V> {
/// Reference to the length field in the borrowed map, updated live. /// Reference to the length field in the borrowed map, updated live.
length: &'a mut usize, length: &'a mut usize,
/// Buried reference to the root field in the borrowed map. /// Buried reference to the root field in the borrowed map.
@ -1685,7 +1808,7 @@ pub(super) struct DrainFilterInner<'a, K: 'a, V: 'a> {
} }
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
impl<K, V, F> Drop for DrainFilter<'_, K, V, F> impl<K, V, F, A: Allocator> Drop for DrainFilter<'_, K, V, F, A>
where where
F: FnMut(&K, &mut V) -> bool, F: FnMut(&K, &mut V) -> bool,
{ {
@ -1707,14 +1830,14 @@ where
} }
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
impl<K, V, F> Iterator for DrainFilter<'_, K, V, F> impl<K, V, F, A: Allocator> Iterator for DrainFilter<'_, K, V, F, A>
where where
F: FnMut(&K, &mut V) -> bool, F: FnMut(&K, &mut V) -> bool,
{ {
type Item = (K, V); type Item = (K, V);
fn next(&mut self) -> Option<(K, V)> { fn next(&mut self) -> Option<(K, V)> {
self.inner.next(&mut self.pred) self.inner.next(&mut self.pred, &self.alloc)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
@ -1722,7 +1845,7 @@ where
} }
} }
impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> { impl<'a, K, V> DrainFilterInner<'a, K, V> {
/// Allow Debug implementations to predict the next element. /// Allow Debug implementations to predict the next element.
pub(super) fn peek(&self) -> Option<(&K, &V)> { pub(super) fn peek(&self) -> Option<(&K, &V)> {
let edge = self.cur_leaf_edge.as_ref()?; let edge = self.cur_leaf_edge.as_ref()?;
@ -1730,7 +1853,7 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
} }
/// Implementation of a typical `DrainFilter::next` method, given the predicate. /// Implementation of a typical `DrainFilter::next` method, given the predicate.
pub(super) fn next<F>(&mut self, pred: &mut F) -> Option<(K, V)> pub(super) fn next<F, A: Allocator>(&mut self, pred: &mut F, alloc: &A) -> Option<(K, V)>
where where
F: FnMut(&K, &mut V) -> bool, F: FnMut(&K, &mut V) -> bool,
{ {
@ -1738,13 +1861,16 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
let (k, v) = kv.kv_mut(); let (k, v) = kv.kv_mut();
if pred(k, v) { if pred(k, v) {
*self.length -= 1; *self.length -= 1;
let (kv, pos) = kv.remove_kv_tracking(|| { let (kv, pos) = kv.remove_kv_tracking(
// SAFETY: we will touch the root in a way that will not || {
// invalidate the position returned. // SAFETY: we will touch the root in a way that will not
let root = unsafe { self.dormant_root.take().unwrap().awaken() }; // invalidate the position returned.
root.pop_internal_level(); let root = unsafe { self.dormant_root.take().unwrap().awaken() };
self.dormant_root = Some(DormantMutRef::new(root).1); root.pop_internal_level(alloc);
}); self.dormant_root = Some(DormantMutRef::new(root).1);
},
alloc,
);
self.cur_leaf_edge = Some(pos); self.cur_leaf_edge = Some(pos);
return Some(kv); return Some(kv);
} }
@ -1822,7 +1948,7 @@ impl<K, V> ExactSizeIterator for ValuesMut<'_, K, V> {
impl<K, V> FusedIterator for ValuesMut<'_, K, V> {} impl<K, V> FusedIterator for ValuesMut<'_, K, V> {}
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> Iterator for IntoKeys<K, V> { impl<K, V, A: Allocator> Iterator for IntoKeys<K, V, A> {
type Item = K; type Item = K;
fn next(&mut self) -> Option<K> { fn next(&mut self) -> Option<K> {
@ -1847,24 +1973,24 @@ impl<K, V> Iterator for IntoKeys<K, V> {
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> DoubleEndedIterator for IntoKeys<K, V> { impl<K, V, A: Allocator> DoubleEndedIterator for IntoKeys<K, V, A> {
fn next_back(&mut self) -> Option<K> { fn next_back(&mut self) -> Option<K> {
self.inner.next_back().map(|(k, _)| k) self.inner.next_back().map(|(k, _)| k)
} }
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> ExactSizeIterator for IntoKeys<K, V> { impl<K, V, A: Allocator> ExactSizeIterator for IntoKeys<K, V, A> {
fn len(&self) -> usize { fn len(&self) -> usize {
self.inner.len() self.inner.len()
} }
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> FusedIterator for IntoKeys<K, V> {} impl<K, V, A: Allocator> FusedIterator for IntoKeys<K, V, A> {}
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> Iterator for IntoValues<K, V> { impl<K, V, A: Allocator> Iterator for IntoValues<K, V, A> {
type Item = V; type Item = V;
fn next(&mut self) -> Option<V> { fn next(&mut self) -> Option<V> {
@ -1881,21 +2007,21 @@ impl<K, V> Iterator for IntoValues<K, V> {
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> DoubleEndedIterator for IntoValues<K, V> { impl<K, V, A: Allocator> DoubleEndedIterator for IntoValues<K, V, A> {
fn next_back(&mut self) -> Option<V> { fn next_back(&mut self) -> Option<V> {
self.inner.next_back().map(|(_, v)| v) self.inner.next_back().map(|(_, v)| v)
} }
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> ExactSizeIterator for IntoValues<K, V> { impl<K, V, A: Allocator> ExactSizeIterator for IntoValues<K, V, A> {
fn len(&self) -> usize { fn len(&self) -> usize {
self.inner.len() self.inner.len()
} }
} }
#[stable(feature = "map_into_keys_values", since = "1.54.0")] #[stable(feature = "map_into_keys_values", since = "1.54.0")]
impl<K, V> FusedIterator for IntoValues<K, V> {} impl<K, V, A: Allocator> FusedIterator for IntoValues<K, V, A> {}
#[stable(feature = "btree_range", since = "1.17.0")] #[stable(feature = "btree_range", since = "1.17.0")]
impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> { impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> {
@ -1956,12 +2082,12 @@ impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
// use stable sort to preserve the insertion order. // use stable sort to preserve the insertion order.
inputs.sort_by(|a, b| a.0.cmp(&b.0)); inputs.sort_by(|a, b| a.0.cmp(&b.0));
BTreeMap::bulk_build_from_sorted_iter(inputs) BTreeMap::bulk_build_from_sorted_iter(inputs, Global)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> { impl<K: Ord, V, A: Allocator> Extend<(K, V)> for BTreeMap<K, V, A> {
#[inline] #[inline]
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
iter.into_iter().for_each(move |(k, v)| { iter.into_iter().for_each(move |(k, v)| {
@ -1976,7 +2102,7 @@ impl<K: Ord, V> Extend<(K, V)> for BTreeMap<K, V> {
} }
#[stable(feature = "extend_ref", since = "1.2.0")] #[stable(feature = "extend_ref", since = "1.2.0")]
impl<'a, K: Ord + Copy, V: Copy> Extend<(&'a K, &'a V)> for BTreeMap<K, V> { impl<'a, K: Ord + Copy, V: Copy, A: Allocator> Extend<(&'a K, &'a V)> for BTreeMap<K, V, A> {
fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
self.extend(iter.into_iter().map(|(&key, &value)| (key, value))); self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
} }
@ -1988,7 +2114,7 @@ impl<'a, K: Ord + Copy, V: Copy> Extend<(&'a K, &'a V)> for BTreeMap<K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: Hash, V: Hash> Hash for BTreeMap<K, V> { impl<K: Hash, V: Hash, A: Allocator> Hash for BTreeMap<K, V, A> {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
state.write_length_prefix(self.len()); state.write_length_prefix(self.len());
for elt in self { for elt in self {
@ -2006,40 +2132,40 @@ impl<K, V> Default for BTreeMap<K, V> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: PartialEq, V: PartialEq> PartialEq for BTreeMap<K, V> { impl<K: PartialEq, V: PartialEq, A: Allocator> PartialEq for BTreeMap<K, V, A> {
fn eq(&self, other: &BTreeMap<K, V>) -> bool { fn eq(&self, other: &BTreeMap<K, V, A>) -> bool {
self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b) self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a == b)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: Eq, V: Eq> Eq for BTreeMap<K, V> {} impl<K: Eq, V: Eq, A: Allocator> Eq for BTreeMap<K, V, A> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: PartialOrd, V: PartialOrd> PartialOrd for BTreeMap<K, V> { impl<K: PartialOrd, V: PartialOrd, A: Allocator> PartialOrd for BTreeMap<K, V, A> {
#[inline] #[inline]
fn partial_cmp(&self, other: &BTreeMap<K, V>) -> Option<Ordering> { fn partial_cmp(&self, other: &BTreeMap<K, V, A>) -> Option<Ordering> {
self.iter().partial_cmp(other.iter()) self.iter().partial_cmp(other.iter())
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, V: Ord> Ord for BTreeMap<K, V> { impl<K: Ord, V: Ord, A: Allocator> Ord for BTreeMap<K, V, A> {
#[inline] #[inline]
fn cmp(&self, other: &BTreeMap<K, V>) -> Ordering { fn cmp(&self, other: &BTreeMap<K, V, A>) -> Ordering {
self.iter().cmp(other.iter()) self.iter().cmp(other.iter())
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> { impl<K: Debug, V: Debug, A: Allocator> Debug for BTreeMap<K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map().entries(self.iter()).finish() f.debug_map().entries(self.iter()).finish()
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<K, Q: ?Sized, V> Index<&Q> for BTreeMap<K, V> impl<K, Q: ?Sized, V, A: Allocator> Index<&Q> for BTreeMap<K, V, A>
where where
K: Borrow<Q> + Ord, K: Borrow<Q> + Ord,
Q: Ord, Q: Ord,
@ -2075,11 +2201,11 @@ impl<K: Ord, V, const N: usize> From<[(K, V); N]> for BTreeMap<K, V> {
// use stable sort to preserve the insertion order. // use stable sort to preserve the insertion order.
arr.sort_by(|a, b| a.0.cmp(&b.0)); arr.sort_by(|a, b| a.0.cmp(&b.0));
BTreeMap::bulk_build_from_sorted_iter(arr) BTreeMap::bulk_build_from_sorted_iter(arr, Global)
} }
} }
impl<K, V> BTreeMap<K, V> { impl<K, V, A: Allocator> BTreeMap<K, V, A> {
/// Gets an iterator over the entries of the map, sorted by key. /// Gets an iterator over the entries of the map, sorted by key.
/// ///
/// # Examples /// # Examples

View file

@ -2,6 +2,8 @@ use core::fmt::{self, Debug};
use core::marker::PhantomData; use core::marker::PhantomData;
use core::mem; use core::mem;
use crate::alloc::{Allocator, Global};
use super::super::borrow::DormantMutRef; use super::super::borrow::DormantMutRef;
use super::super::node::{marker, Handle, NodeRef}; use super::super::node::{marker, Handle, NodeRef};
use super::BTreeMap; use super::BTreeMap;
@ -15,18 +17,23 @@ use Entry::*;
/// [`entry`]: BTreeMap::entry /// [`entry`]: BTreeMap::entry
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeEntry")] #[cfg_attr(not(test), rustc_diagnostic_item = "BTreeEntry")]
pub enum Entry<'a, K: 'a, V: 'a> { pub enum Entry<
'a,
K: 'a,
V: 'a,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
/// A vacant entry. /// A vacant entry.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>), Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V, A>),
/// An occupied entry. /// An occupied entry.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>), Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V, A>),
} }
#[stable(feature = "debug_btree_map", since = "1.12.0")] #[stable(feature = "debug_btree_map", since = "1.12.0")]
impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> { impl<K: Debug + Ord, V: Debug, A: Allocator> Debug for Entry<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self { match *self {
Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
@ -38,18 +45,25 @@ impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> {
/// A view into a vacant entry in a `BTreeMap`. /// A view into a vacant entry in a `BTreeMap`.
/// It is part of the [`Entry`] enum. /// It is part of the [`Entry`] enum.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, K: 'a, V: 'a> { pub struct VacantEntry<
'a,
K,
V,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
pub(super) key: K, pub(super) key: K,
/// `None` for a (empty) map without root /// `None` for a (empty) map without root
pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>, pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V>>, pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
pub(super) alloc: &'a A,
// Be invariant in `K` and `V` // Be invariant in `K` and `V`
pub(super) _marker: PhantomData<&'a mut (K, V)>, pub(super) _marker: PhantomData<&'a mut (K, V)>,
} }
#[stable(feature = "debug_btree_map", since = "1.12.0")] #[stable(feature = "debug_btree_map", since = "1.12.0")]
impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> { impl<K: Debug + Ord, V, A: Allocator> Debug for VacantEntry<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("VacantEntry").field(self.key()).finish() f.debug_tuple("VacantEntry").field(self.key()).finish()
} }
@ -58,16 +72,23 @@ impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> {
/// A view into an occupied entry in a `BTreeMap`. /// A view into an occupied entry in a `BTreeMap`.
/// It is part of the [`Entry`] enum. /// It is part of the [`Entry`] enum.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct OccupiedEntry<'a, K: 'a, V: 'a> { pub struct OccupiedEntry<
'a,
K,
V,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>, pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V>>, pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
pub(super) alloc: &'a A,
// Be invariant in `K` and `V` // Be invariant in `K` and `V`
pub(super) _marker: PhantomData<&'a mut (K, V)>, pub(super) _marker: PhantomData<&'a mut (K, V)>,
} }
#[stable(feature = "debug_btree_map", since = "1.12.0")] #[stable(feature = "debug_btree_map", since = "1.12.0")]
impl<K: Debug + Ord, V: Debug> Debug for OccupiedEntry<'_, K, V> { impl<K: Debug + Ord, V: Debug, A: Allocator> Debug for OccupiedEntry<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish() f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish()
} }
@ -77,15 +98,15 @@ impl<K: Debug + Ord, V: Debug> Debug for OccupiedEntry<'_, K, V> {
/// ///
/// Contains the occupied entry, and the value that was not inserted. /// Contains the occupied entry, and the value that was not inserted.
#[unstable(feature = "map_try_insert", issue = "82766")] #[unstable(feature = "map_try_insert", issue = "82766")]
pub struct OccupiedError<'a, K: 'a, V: 'a> { pub struct OccupiedError<'a, K: 'a, V: 'a, A: Allocator = Global> {
/// The entry in the map that was already occupied. /// The entry in the map that was already occupied.
pub entry: OccupiedEntry<'a, K, V>, pub entry: OccupiedEntry<'a, K, V, A>,
/// The value which was not inserted, because the entry was already occupied. /// The value which was not inserted, because the entry was already occupied.
pub value: V, pub value: V,
} }
#[unstable(feature = "map_try_insert", issue = "82766")] #[unstable(feature = "map_try_insert", issue = "82766")]
impl<K: Debug + Ord, V: Debug> Debug for OccupiedError<'_, K, V> { impl<K: Debug + Ord, V: Debug, A: Allocator> Debug for OccupiedError<'_, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedError") f.debug_struct("OccupiedError")
.field("key", self.entry.key()) .field("key", self.entry.key())
@ -96,7 +117,7 @@ impl<K: Debug + Ord, V: Debug> Debug for OccupiedError<'_, K, V> {
} }
#[unstable(feature = "map_try_insert", issue = "82766")] #[unstable(feature = "map_try_insert", issue = "82766")]
impl<'a, K: Debug + Ord, V: Debug> fmt::Display for OccupiedError<'a, K, V> { impl<'a, K: Debug + Ord, V: Debug, A: Allocator> fmt::Display for OccupiedError<'a, K, V, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(
f, f,
@ -108,7 +129,7 @@ impl<'a, K: Debug + Ord, V: Debug> fmt::Display for OccupiedError<'a, K, V> {
} }
} }
impl<'a, K: Ord, V> Entry<'a, K, V> { impl<'a, K: Ord, V, A: Allocator> Entry<'a, K, V, A> {
/// Ensures a value is in the entry by inserting the default if empty, and returns /// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry. /// a mutable reference to the value in the entry.
/// ///
@ -236,7 +257,7 @@ impl<'a, K: Ord, V> Entry<'a, K, V> {
} }
} }
impl<'a, K: Ord, V: Default> Entry<'a, K, V> { impl<'a, K: Ord, V: Default, A: Allocator> Entry<'a, K, V, A> {
#[stable(feature = "entry_or_default", since = "1.28.0")] #[stable(feature = "entry_or_default", since = "1.28.0")]
/// Ensures a value is in the entry by inserting the default value if empty, /// Ensures a value is in the entry by inserting the default value if empty,
/// and returns a mutable reference to the value in the entry. /// and returns a mutable reference to the value in the entry.
@ -259,7 +280,7 @@ impl<'a, K: Ord, V: Default> Entry<'a, K, V> {
} }
} }
impl<'a, K: Ord, V> VacantEntry<'a, K, V> { impl<'a, K: Ord, V, A: Allocator> VacantEntry<'a, K, V, A> {
/// Gets a reference to the key that would be used when inserting a value /// Gets a reference to the key that would be used when inserting a value
/// through the VacantEntry. /// through the VacantEntry.
/// ///
@ -317,13 +338,13 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
None => { None => {
// SAFETY: There is no tree yet so no reference to it exists. // SAFETY: There is no tree yet so no reference to it exists.
let map = unsafe { self.dormant_map.awaken() }; let map = unsafe { self.dormant_map.awaken() };
let mut root = NodeRef::new_leaf(); let mut root = NodeRef::new_leaf(self.alloc);
let val_ptr = root.borrow_mut().push(self.key, value) as *mut V; let val_ptr = root.borrow_mut().push(self.key, value) as *mut V;
map.root = Some(root.forget_type()); map.root = Some(root.forget_type());
map.length = 1; map.length = 1;
val_ptr val_ptr
} }
Some(handle) => match handle.insert_recursing(self.key, value) { Some(handle) => match handle.insert_recursing(self.key, value, self.alloc) {
(None, val_ptr) => { (None, val_ptr) => {
// SAFETY: We have consumed self.handle. // SAFETY: We have consumed self.handle.
let map = unsafe { self.dormant_map.awaken() }; let map = unsafe { self.dormant_map.awaken() };
@ -336,7 +357,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
// remaining reference to the tree, ins.left. // remaining reference to the tree, ins.left.
let map = unsafe { self.dormant_map.awaken() }; let map = unsafe { self.dormant_map.awaken() };
let root = map.root.as_mut().unwrap(); // same as ins.left let root = map.root.as_mut().unwrap(); // same as ins.left
root.push_internal_level().push(ins.kv.0, ins.kv.1, ins.right); root.push_internal_level(self.alloc).push(ins.kv.0, ins.kv.1, ins.right);
map.length += 1; map.length += 1;
val_ptr val_ptr
} }
@ -348,7 +369,7 @@ impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
} }
} }
impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { impl<'a, K: Ord, V, A: Allocator> OccupiedEntry<'a, K, V, A> {
/// Gets a reference to the key in the entry. /// Gets a reference to the key in the entry.
/// ///
/// # Examples /// # Examples
@ -516,13 +537,14 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
// Body of `remove_entry`, probably separate because the name reflects the returned pair. // Body of `remove_entry`, probably separate because the name reflects the returned pair.
pub(super) fn remove_kv(self) -> (K, V) { pub(super) fn remove_kv(self) -> (K, V) {
let mut emptied_internal_root = false; let mut emptied_internal_root = false;
let (old_kv, _) = self.handle.remove_kv_tracking(|| emptied_internal_root = true); let (old_kv, _) =
self.handle.remove_kv_tracking(|| emptied_internal_root = true, self.alloc);
// SAFETY: we consumed the intermediate root borrow, `self.handle`. // SAFETY: we consumed the intermediate root borrow, `self.handle`.
let map = unsafe { self.dormant_map.awaken() }; let map = unsafe { self.dormant_map.awaken() };
map.length -= 1; map.length -= 1;
if emptied_internal_root { if emptied_internal_root {
let root = map.root.as_mut().unwrap(); let root = map.root.as_mut().unwrap();
root.pop_internal_level(); root.pop_internal_level(&*self.alloc);
} }
old_kv old_kv
} }

View file

@ -116,7 +116,11 @@ impl<K, V> BTreeMap<K, V> {
{ {
let iter = mem::take(self).into_iter(); let iter = mem::take(self).into_iter();
if !iter.is_empty() { if !iter.is_empty() {
self.root.insert(Root::new()).bulk_push(iter, &mut self.length); self.root.insert(Root::new(&*self.alloc)).bulk_push(
iter,
&mut self.length,
&*self.alloc,
);
} }
} }
} }

View file

@ -5,6 +5,7 @@ use core::ptr;
use super::node::{marker, ForceResult::*, Handle, NodeRef}; use super::node::{marker, ForceResult::*, Handle, NodeRef};
use crate::alloc::Allocator;
// `front` and `back` are always both `None` or both `Some`. // `front` and `back` are always both `None` or both `Some`.
pub struct LeafRange<BorrowType, K, V> { pub struct LeafRange<BorrowType, K, V> {
front: Option<Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>>, front: Option<Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::Edge>>,
@ -177,27 +178,29 @@ impl<K, V> LazyLeafRange<marker::Dying, K, V> {
} }
#[inline] #[inline]
pub unsafe fn deallocating_next_unchecked( pub unsafe fn deallocating_next_unchecked<A: Allocator>(
&mut self, &mut self,
alloc: &A,
) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> { ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
debug_assert!(self.front.is_some()); debug_assert!(self.front.is_some());
let front = self.init_front().unwrap(); let front = self.init_front().unwrap();
unsafe { front.deallocating_next_unchecked() } unsafe { front.deallocating_next_unchecked(alloc) }
} }
#[inline] #[inline]
pub unsafe fn deallocating_next_back_unchecked( pub unsafe fn deallocating_next_back_unchecked<A: Allocator>(
&mut self, &mut self,
alloc: &A,
) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> { ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
debug_assert!(self.back.is_some()); debug_assert!(self.back.is_some());
let back = self.init_back().unwrap(); let back = self.init_back().unwrap();
unsafe { back.deallocating_next_back_unchecked() } unsafe { back.deallocating_next_back_unchecked(alloc) }
} }
#[inline] #[inline]
pub fn deallocating_end(&mut self) { pub fn deallocating_end<A: Allocator>(&mut self, alloc: &A) {
if let Some(front) = self.take_front() { if let Some(front) = self.take_front() {
front.deallocating_end() front.deallocating_end(alloc)
} }
} }
} }
@ -441,18 +444,21 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
/// `deallocating_next_back`. /// `deallocating_next_back`.
/// - The returned KV handle is only valid to access the key and value, /// - The returned KV handle is only valid to access the key and value,
/// and only valid until the next call to a `deallocating_` method. /// and only valid until the next call to a `deallocating_` method.
unsafe fn deallocating_next( unsafe fn deallocating_next<A: Allocator>(
self, self,
alloc: &A,
) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)> ) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>
{ {
let mut edge = self.forget_node_type(); let mut edge = self.forget_node_type();
loop { loop {
edge = match edge.right_kv() { edge = match edge.right_kv() {
Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_leaf_edge(), kv)), Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_leaf_edge(), kv)),
Err(last_edge) => match unsafe { last_edge.into_node().deallocate_and_ascend() } { Err(last_edge) => {
Some(parent_edge) => parent_edge.forget_node_type(), match unsafe { last_edge.into_node().deallocate_and_ascend(alloc) } {
None => return None, Some(parent_edge) => parent_edge.forget_node_type(),
}, None => return None,
}
}
} }
} }
} }
@ -470,18 +476,21 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
/// `deallocating_next`. /// `deallocating_next`.
/// - The returned KV handle is only valid to access the key and value, /// - The returned KV handle is only valid to access the key and value,
/// and only valid until the next call to a `deallocating_` method. /// and only valid until the next call to a `deallocating_` method.
unsafe fn deallocating_next_back( unsafe fn deallocating_next_back<A: Allocator>(
self, self,
alloc: &A,
) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)> ) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>
{ {
let mut edge = self.forget_node_type(); let mut edge = self.forget_node_type();
loop { loop {
edge = match edge.left_kv() { edge = match edge.left_kv() {
Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_back_leaf_edge(), kv)), Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_back_leaf_edge(), kv)),
Err(last_edge) => match unsafe { last_edge.into_node().deallocate_and_ascend() } { Err(last_edge) => {
Some(parent_edge) => parent_edge.forget_node_type(), match unsafe { last_edge.into_node().deallocate_and_ascend(alloc) } {
None => return None, Some(parent_edge) => parent_edge.forget_node_type(),
}, None => return None,
}
}
} }
} }
} }
@ -492,9 +501,9 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
/// both sides of the tree, and have hit the same edge. As it is intended /// both sides of the tree, and have hit the same edge. As it is intended
/// only to be called when all keys and values have been returned, /// only to be called when all keys and values have been returned,
/// no cleanup is done on any of the keys or values. /// no cleanup is done on any of the keys or values.
fn deallocating_end(self) { fn deallocating_end<A: Allocator>(self, alloc: &A) {
let mut edge = self.forget_node_type(); let mut edge = self.forget_node_type();
while let Some(parent_edge) = unsafe { edge.into_node().deallocate_and_ascend() } { while let Some(parent_edge) = unsafe { edge.into_node().deallocate_and_ascend(alloc) } {
edge = parent_edge.forget_node_type(); edge = parent_edge.forget_node_type();
} }
} }
@ -569,10 +578,13 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
/// ///
/// The only safe way to proceed with the updated handle is to compare it, drop it, /// The only safe way to proceed with the updated handle is to compare it, drop it,
/// or call this method or counterpart `deallocating_next_back_unchecked` again. /// or call this method or counterpart `deallocating_next_back_unchecked` again.
unsafe fn deallocating_next_unchecked( unsafe fn deallocating_next_unchecked<A: Allocator>(
&mut self, &mut self,
alloc: &A,
) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> { ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
super::mem::replace(self, |leaf_edge| unsafe { leaf_edge.deallocating_next().unwrap() }) super::mem::replace(self, |leaf_edge| unsafe {
leaf_edge.deallocating_next(alloc).unwrap()
})
} }
/// Moves the leaf edge handle to the previous leaf edge and returns the key and value /// Moves the leaf edge handle to the previous leaf edge and returns the key and value
@ -587,11 +599,12 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
/// ///
/// The only safe way to proceed with the updated handle is to compare it, drop it, /// The only safe way to proceed with the updated handle is to compare it, drop it,
/// or call this method or counterpart `deallocating_next_unchecked` again. /// or call this method or counterpart `deallocating_next_unchecked` again.
unsafe fn deallocating_next_back_unchecked( unsafe fn deallocating_next_back_unchecked<A: Allocator>(
&mut self, &mut self,
alloc: &A,
) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> { ) -> Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV> {
super::mem::replace(self, |leaf_edge| unsafe { super::mem::replace(self, |leaf_edge| unsafe {
leaf_edge.deallocating_next_back().unwrap() leaf_edge.deallocating_next_back(alloc).unwrap()
}) })
} }
} }

View file

@ -36,7 +36,7 @@ use core::mem::{self, MaybeUninit};
use core::ptr::{self, NonNull}; use core::ptr::{self, NonNull};
use core::slice::SliceIndex; use core::slice::SliceIndex;
use crate::alloc::{Allocator, Global, Layout}; use crate::alloc::{Allocator, Layout};
use crate::boxed::Box; use crate::boxed::Box;
const B: usize = 6; const B: usize = 6;
@ -78,9 +78,9 @@ impl<K, V> LeafNode<K, V> {
} }
/// Creates a new boxed `LeafNode`. /// Creates a new boxed `LeafNode`.
fn new() -> Box<Self> { fn new<A: Allocator>(alloc: &A) -> Box<Self, &A> {
unsafe { unsafe {
let mut leaf = Box::new_uninit(); let mut leaf = Box::new_uninit_in(alloc);
LeafNode::init(leaf.as_mut_ptr()); LeafNode::init(leaf.as_mut_ptr());
leaf.assume_init() leaf.assume_init()
} }
@ -110,9 +110,9 @@ impl<K, V> InternalNode<K, V> {
/// An invariant of internal nodes is that they have at least one /// An invariant of internal nodes is that they have at least one
/// initialized and valid edge. This function does not set up /// initialized and valid edge. This function does not set up
/// such an edge. /// such an edge.
unsafe fn new() -> Box<Self> { unsafe fn new<A: Allocator>(alloc: &A) -> Box<Self, &A> {
unsafe { unsafe {
let mut node = Box::<Self>::new_uninit(); let mut node = Box::<Self, _>::new_uninit_in(alloc);
// We only need to initialize the data; the edges are MaybeUninit. // We only need to initialize the data; the edges are MaybeUninit.
LeafNode::init(ptr::addr_of_mut!((*node.as_mut_ptr()).data)); LeafNode::init(ptr::addr_of_mut!((*node.as_mut_ptr()).data));
node.assume_init() node.assume_init()
@ -213,25 +213,28 @@ unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Owned, K, V, Type>
unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Dying, K, V, Type> {} unsafe impl<K: Send, V: Send, Type> Send for NodeRef<marker::Dying, K, V, Type> {}
impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> { impl<K, V> NodeRef<marker::Owned, K, V, marker::Leaf> {
pub fn new_leaf() -> Self { pub fn new_leaf<A: Allocator>(alloc: &A) -> Self {
Self::from_new_leaf(LeafNode::new()) Self::from_new_leaf(LeafNode::new(alloc))
} }
fn from_new_leaf(leaf: Box<LeafNode<K, V>>) -> Self { fn from_new_leaf<A: Allocator>(leaf: Box<LeafNode<K, V>, A>) -> Self {
NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData } NodeRef { height: 0, node: NonNull::from(Box::leak(leaf)), _marker: PhantomData }
} }
} }
impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> { impl<K, V> NodeRef<marker::Owned, K, V, marker::Internal> {
fn new_internal(child: Root<K, V>) -> Self { fn new_internal<A: Allocator>(child: Root<K, V>, alloc: &A) -> Self {
let mut new_node = unsafe { InternalNode::new() }; let mut new_node = unsafe { InternalNode::new(alloc) };
new_node.edges[0].write(child.node); new_node.edges[0].write(child.node);
unsafe { NodeRef::from_new_internal(new_node, child.height + 1) } unsafe { NodeRef::from_new_internal(new_node, child.height + 1) }
} }
/// # Safety /// # Safety
/// `height` must not be zero. /// `height` must not be zero.
unsafe fn from_new_internal(internal: Box<InternalNode<K, V>>, height: usize) -> Self { unsafe fn from_new_internal<A: Allocator>(
internal: Box<InternalNode<K, V>, A>,
height: usize,
) -> Self {
debug_assert!(height > 0); debug_assert!(height > 0);
let node = NonNull::from(Box::leak(internal)).cast(); let node = NonNull::from(Box::leak(internal)).cast();
let mut this = NodeRef { height, node, _marker: PhantomData }; let mut this = NodeRef { height, node, _marker: PhantomData };
@ -387,14 +390,15 @@ impl<K, V> NodeRef<marker::Dying, K, V, marker::LeafOrInternal> {
/// Similar to `ascend`, gets a reference to a node's parent node, but also /// Similar to `ascend`, gets a reference to a node's parent node, but also
/// deallocates the current node in the process. This is unsafe because the /// deallocates the current node in the process. This is unsafe because the
/// current node will still be accessible despite being deallocated. /// current node will still be accessible despite being deallocated.
pub unsafe fn deallocate_and_ascend( pub unsafe fn deallocate_and_ascend<A: Allocator>(
self, self,
alloc: &A,
) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::Internal>, marker::Edge>> { ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::Internal>, marker::Edge>> {
let height = self.height; let height = self.height;
let node = self.node; let node = self.node;
let ret = self.ascend().ok(); let ret = self.ascend().ok();
unsafe { unsafe {
Global.deallocate( alloc.deallocate(
node.cast(), node.cast(),
if height > 0 { if height > 0 {
Layout::new::<InternalNode<K, V>>() Layout::new::<InternalNode<K, V>>()
@ -555,15 +559,18 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> { impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
/// Returns a new owned tree, with its own root node that is initially empty. /// Returns a new owned tree, with its own root node that is initially empty.
pub fn new() -> Self { pub fn new<A: Allocator>(alloc: &A) -> Self {
NodeRef::new_leaf().forget_type() NodeRef::new_leaf(alloc).forget_type()
} }
/// Adds a new internal node with a single edge pointing to the previous root node, /// Adds a new internal node with a single edge pointing to the previous root node,
/// make that new node the root node, and return it. This increases the height by 1 /// make that new node the root node, and return it. This increases the height by 1
/// and is the opposite of `pop_internal_level`. /// and is the opposite of `pop_internal_level`.
pub fn push_internal_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> { pub fn push_internal_level<A: Allocator>(
super::mem::take_mut(self, |old_root| NodeRef::new_internal(old_root).forget_type()); &mut self,
alloc: &A,
) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
super::mem::take_mut(self, |old_root| NodeRef::new_internal(old_root, alloc).forget_type());
// `self.borrow_mut()`, except that we just forgot we're internal now: // `self.borrow_mut()`, except that we just forgot we're internal now:
NodeRef { height: self.height, node: self.node, _marker: PhantomData } NodeRef { height: self.height, node: self.node, _marker: PhantomData }
@ -578,7 +585,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
/// it will not invalidate other handles or references to the root node. /// it will not invalidate other handles or references to the root node.
/// ///
/// Panics if there is no internal level, i.e., if the root node is a leaf. /// Panics if there is no internal level, i.e., if the root node is a leaf.
pub fn pop_internal_level(&mut self) { pub fn pop_internal_level<A: Allocator>(&mut self, alloc: &A) {
assert!(self.height > 0); assert!(self.height > 0);
let top = self.node; let top = self.node;
@ -593,7 +600,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
self.clear_parent_link(); self.clear_parent_link();
unsafe { unsafe {
Global.deallocate(top.cast(), Layout::new::<InternalNode<K, V>>()); alloc.deallocate(top.cast(), Layout::new::<InternalNode<K, V>>());
} }
} }
} }
@ -862,14 +869,19 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
/// this edge. This method splits the node if there isn't enough room. /// this edge. This method splits the node if there isn't enough room.
/// ///
/// The returned pointer points to the inserted value. /// The returned pointer points to the inserted value.
fn insert(mut self, key: K, val: V) -> (Option<SplitResult<'a, K, V, marker::Leaf>>, *mut V) { fn insert<A: Allocator>(
mut self,
key: K,
val: V,
alloc: &A,
) -> (Option<SplitResult<'a, K, V, marker::Leaf>>, *mut V) {
if self.node.len() < CAPACITY { if self.node.len() < CAPACITY {
let val_ptr = self.insert_fit(key, val); let val_ptr = self.insert_fit(key, val);
(None, val_ptr) (None, val_ptr)
} else { } else {
let (middle_kv_idx, insertion) = splitpoint(self.idx); let (middle_kv_idx, insertion) = splitpoint(self.idx);
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) }; let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
let mut result = middle.split(); let mut result = middle.split(alloc);
let mut insertion_edge = match insertion { let mut insertion_edge = match insertion {
LeftOrRight::Left(insert_idx) => unsafe { LeftOrRight::Left(insert_idx) => unsafe {
Handle::new_edge(result.left.reborrow_mut(), insert_idx) Handle::new_edge(result.left.reborrow_mut(), insert_idx)
@ -918,11 +930,12 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
/// Inserts a new key-value pair and an edge that will go to the right of that new pair /// Inserts a new key-value pair and an edge that will go to the right of that new pair
/// between this edge and the key-value pair to the right of this edge. This method splits /// between this edge and the key-value pair to the right of this edge. This method splits
/// the node if there isn't enough room. /// the node if there isn't enough room.
fn insert( fn insert<A: Allocator>(
mut self, mut self,
key: K, key: K,
val: V, val: V,
edge: Root<K, V>, edge: Root<K, V>,
alloc: &A,
) -> Option<SplitResult<'a, K, V, marker::Internal>> { ) -> Option<SplitResult<'a, K, V, marker::Internal>> {
assert!(edge.height == self.node.height - 1); assert!(edge.height == self.node.height - 1);
@ -932,7 +945,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
} else { } else {
let (middle_kv_idx, insertion) = splitpoint(self.idx); let (middle_kv_idx, insertion) = splitpoint(self.idx);
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) }; let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
let mut result = middle.split(); let mut result = middle.split(alloc);
let mut insertion_edge = match insertion { let mut insertion_edge = match insertion {
LeftOrRight::Left(insert_idx) => unsafe { LeftOrRight::Left(insert_idx) => unsafe {
Handle::new_edge(result.left.reborrow_mut(), insert_idx) Handle::new_edge(result.left.reborrow_mut(), insert_idx)
@ -955,19 +968,20 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
/// If the returned result is some `SplitResult`, the `left` field will be the root node. /// If the returned result is some `SplitResult`, the `left` field will be the root node.
/// The returned pointer points to the inserted value, which in the case of `SplitResult` /// The returned pointer points to the inserted value, which in the case of `SplitResult`
/// is in the `left` or `right` tree. /// is in the `left` or `right` tree.
pub fn insert_recursing( pub fn insert_recursing<A: Allocator>(
self, self,
key: K, key: K,
value: V, value: V,
alloc: &A,
) -> (Option<SplitResult<'a, K, V, marker::LeafOrInternal>>, *mut V) { ) -> (Option<SplitResult<'a, K, V, marker::LeafOrInternal>>, *mut V) {
let (mut split, val_ptr) = match self.insert(key, value) { let (mut split, val_ptr) = match self.insert(key, value, alloc) {
(None, val_ptr) => return (None, val_ptr), (None, val_ptr) => return (None, val_ptr),
(Some(split), val_ptr) => (split.forget_node_type(), val_ptr), (Some(split), val_ptr) => (split.forget_node_type(), val_ptr),
}; };
loop { loop {
split = match split.left.ascend() { split = match split.left.ascend() {
Ok(parent) => match parent.insert(split.kv.0, split.kv.1, split.right) { Ok(parent) => match parent.insert(split.kv.0, split.kv.1, split.right, alloc) {
None => return (None, val_ptr), None => return (None, val_ptr),
Some(split) => split.forget_node_type(), Some(split) => split.forget_node_type(),
}, },
@ -1112,8 +1126,8 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
/// - The key and value pointed to by this handle are extracted. /// - The key and value pointed to by this handle are extracted.
/// - All the key-value pairs to the right of this handle are put into a newly /// - All the key-value pairs to the right of this handle are put into a newly
/// allocated node. /// allocated node.
pub fn split(mut self) -> SplitResult<'a, K, V, marker::Leaf> { pub fn split<A: Allocator>(mut self, alloc: &A) -> SplitResult<'a, K, V, marker::Leaf> {
let mut new_node = LeafNode::new(); let mut new_node = LeafNode::new(alloc);
let kv = self.split_leaf_data(&mut new_node); let kv = self.split_leaf_data(&mut new_node);
@ -1144,10 +1158,10 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>,
/// - The key and value pointed to by this handle are extracted. /// - The key and value pointed to by this handle are extracted.
/// - All the edges and key-value pairs to the right of this handle are put into /// - All the edges and key-value pairs to the right of this handle are put into
/// a newly allocated node. /// a newly allocated node.
pub fn split(mut self) -> SplitResult<'a, K, V, marker::Internal> { pub fn split<A: Allocator>(mut self, alloc: &A) -> SplitResult<'a, K, V, marker::Internal> {
let old_len = self.node.len(); let old_len = self.node.len();
unsafe { unsafe {
let mut new_node = InternalNode::new(); let mut new_node = InternalNode::new(alloc);
let kv = self.split_leaf_data(&mut new_node.data); let kv = self.split_leaf_data(&mut new_node.data);
let new_len = usize::from(new_node.data.len); let new_len = usize::from(new_node.data.len);
move_to_slice( move_to_slice(
@ -1252,9 +1266,11 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>,
) -> R, ) -> R,
R, R,
A: Allocator,
>( >(
self, self,
result: F, result: F,
alloc: &A,
) -> R { ) -> R {
let Handle { node: mut parent_node, idx: parent_idx, _marker } = self.parent; let Handle { node: mut parent_node, idx: parent_idx, _marker } = self.parent;
let old_parent_len = parent_node.len(); let old_parent_len = parent_node.len();
@ -1299,9 +1315,9 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
left_node.correct_childrens_parent_links(old_left_len + 1..new_left_len + 1); left_node.correct_childrens_parent_links(old_left_len + 1..new_left_len + 1);
Global.deallocate(right_node.node.cast(), Layout::new::<InternalNode<K, V>>()); alloc.deallocate(right_node.node.cast(), Layout::new::<InternalNode<K, V>>());
} else { } else {
Global.deallocate(right_node.node.cast(), Layout::new::<LeafNode<K, V>>()); alloc.deallocate(right_node.node.cast(), Layout::new::<LeafNode<K, V>>());
} }
} }
result(parent_node, left_node) result(parent_node, left_node)
@ -1311,16 +1327,22 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
/// the left child node and returns the shrunk parent node. /// the left child node and returns the shrunk parent node.
/// ///
/// Panics unless we `.can_merge()`. /// Panics unless we `.can_merge()`.
pub fn merge_tracking_parent(self) -> NodeRef<marker::Mut<'a>, K, V, marker::Internal> { pub fn merge_tracking_parent<A: Allocator>(
self.do_merge(|parent, _child| parent) self,
alloc: &A,
) -> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
self.do_merge(|parent, _child| parent, alloc)
} }
/// Merges the parent's key-value pair and both adjacent child nodes into /// Merges the parent's key-value pair and both adjacent child nodes into
/// the left child node and returns that child node. /// the left child node and returns that child node.
/// ///
/// Panics unless we `.can_merge()`. /// Panics unless we `.can_merge()`.
pub fn merge_tracking_child(self) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> { pub fn merge_tracking_child<A: Allocator>(
self.do_merge(|_parent, child| child) self,
alloc: &A,
) -> NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal> {
self.do_merge(|_parent, child| child, alloc)
} }
/// Merges the parent's key-value pair and both adjacent child nodes into /// Merges the parent's key-value pair and both adjacent child nodes into
@ -1328,9 +1350,10 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
/// where the tracked child edge ended up, /// where the tracked child edge ended up,
/// ///
/// Panics unless we `.can_merge()`. /// Panics unless we `.can_merge()`.
pub fn merge_tracking_child_edge( pub fn merge_tracking_child_edge<A: Allocator>(
self, self,
track_edge_idx: LeftOrRight<usize>, track_edge_idx: LeftOrRight<usize>,
alloc: &A,
) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> { ) -> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::Edge> {
let old_left_len = self.left_child.len(); let old_left_len = self.left_child.len();
let right_len = self.right_child.len(); let right_len = self.right_child.len();
@ -1338,7 +1361,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> {
LeftOrRight::Left(idx) => idx <= old_left_len, LeftOrRight::Left(idx) => idx <= old_left_len,
LeftOrRight::Right(idx) => idx <= right_len, LeftOrRight::Right(idx) => idx <= right_len,
}); });
let child = self.merge_tracking_child(); let child = self.merge_tracking_child(alloc);
let new_idx = match track_edge_idx { let new_idx = match track_edge_idx {
LeftOrRight::Left(idx) => idx, LeftOrRight::Left(idx) => idx,
LeftOrRight::Right(idx) => old_left_len + 1 + idx, LeftOrRight::Right(idx) => old_left_len + 1 + idx,

View file

@ -1,5 +1,6 @@
use super::super::navigate; use super::super::navigate;
use super::*; use super::*;
use crate::alloc::Global;
use crate::fmt::Debug; use crate::fmt::Debug;
use crate::string::String; use crate::string::String;
@ -67,10 +68,10 @@ fn test_splitpoint() {
#[test] #[test]
fn test_partial_eq() { fn test_partial_eq() {
let mut root1 = NodeRef::new_leaf(); let mut root1 = NodeRef::new_leaf(&Global);
root1.borrow_mut().push(1, ()); root1.borrow_mut().push(1, ());
let mut root1 = NodeRef::new_internal(root1.forget_type()).forget_type(); let mut root1 = NodeRef::new_internal(root1.forget_type(), &Global).forget_type();
let root2 = Root::new(); let root2 = Root::new(&Global);
root1.reborrow().assert_back_pointers(); root1.reborrow().assert_back_pointers();
root2.reborrow().assert_back_pointers(); root2.reborrow().assert_back_pointers();
@ -86,9 +87,9 @@ fn test_partial_eq() {
assert!(top_edge_1 == top_edge_1); assert!(top_edge_1 == top_edge_1);
assert!(top_edge_1 != top_edge_2); assert!(top_edge_1 != top_edge_2);
root1.pop_internal_level(); root1.pop_internal_level(&Global);
unsafe { root1.into_dying().deallocate_and_ascend() }; unsafe { root1.into_dying().deallocate_and_ascend(&Global) };
unsafe { root2.into_dying().deallocate_and_ascend() }; unsafe { root2.into_dying().deallocate_and_ascend(&Global) };
} }
#[test] #[test]

View file

@ -1,26 +1,29 @@
use super::map::MIN_LEN; use super::map::MIN_LEN;
use super::node::{marker, ForceResult::*, Handle, LeftOrRight::*, NodeRef}; use super::node::{marker, ForceResult::*, Handle, LeftOrRight::*, NodeRef};
use core::alloc::Allocator;
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> { impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV> {
/// Removes a key-value pair from the tree, and returns that pair, as well as /// Removes a key-value pair from the tree, and returns that pair, as well as
/// the leaf edge corresponding to that former pair. It's possible this empties /// the leaf edge corresponding to that former pair. It's possible this empties
/// a root node that is internal, which the caller should pop from the map /// a root node that is internal, which the caller should pop from the map
/// holding the tree. The caller should also decrement the map's length. /// holding the tree. The caller should also decrement the map's length.
pub fn remove_kv_tracking<F: FnOnce()>( pub fn remove_kv_tracking<F: FnOnce(), A: Allocator>(
self, self,
handle_emptied_internal_root: F, handle_emptied_internal_root: F,
alloc: &A,
) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) { ) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
match self.force() { match self.force() {
Leaf(node) => node.remove_leaf_kv(handle_emptied_internal_root), Leaf(node) => node.remove_leaf_kv(handle_emptied_internal_root, alloc),
Internal(node) => node.remove_internal_kv(handle_emptied_internal_root), Internal(node) => node.remove_internal_kv(handle_emptied_internal_root, alloc),
} }
} }
} }
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> { impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV> {
fn remove_leaf_kv<F: FnOnce()>( fn remove_leaf_kv<F: FnOnce(), A: Allocator>(
self, self,
handle_emptied_internal_root: F, handle_emptied_internal_root: F,
alloc: &A,
) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) { ) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
let (old_kv, mut pos) = self.remove(); let (old_kv, mut pos) = self.remove();
let len = pos.reborrow().into_node().len(); let len = pos.reborrow().into_node().len();
@ -32,7 +35,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
Ok(Left(left_parent_kv)) => { Ok(Left(left_parent_kv)) => {
debug_assert!(left_parent_kv.right_child_len() == MIN_LEN - 1); debug_assert!(left_parent_kv.right_child_len() == MIN_LEN - 1);
if left_parent_kv.can_merge() { if left_parent_kv.can_merge() {
left_parent_kv.merge_tracking_child_edge(Right(idx)) left_parent_kv.merge_tracking_child_edge(Right(idx), alloc)
} else { } else {
debug_assert!(left_parent_kv.left_child_len() > MIN_LEN); debug_assert!(left_parent_kv.left_child_len() > MIN_LEN);
left_parent_kv.steal_left(idx) left_parent_kv.steal_left(idx)
@ -41,7 +44,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
Ok(Right(right_parent_kv)) => { Ok(Right(right_parent_kv)) => {
debug_assert!(right_parent_kv.left_child_len() == MIN_LEN - 1); debug_assert!(right_parent_kv.left_child_len() == MIN_LEN - 1);
if right_parent_kv.can_merge() { if right_parent_kv.can_merge() {
right_parent_kv.merge_tracking_child_edge(Left(idx)) right_parent_kv.merge_tracking_child_edge(Left(idx), alloc)
} else { } else {
debug_assert!(right_parent_kv.right_child_len() > MIN_LEN); debug_assert!(right_parent_kv.right_child_len() > MIN_LEN);
right_parent_kv.steal_right(idx) right_parent_kv.steal_right(idx)
@ -60,7 +63,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
// rearrange the parent through the grandparent, thus change the // rearrange the parent through the grandparent, thus change the
// link to the parent inside the leaf. // link to the parent inside the leaf.
if let Ok(parent) = unsafe { pos.reborrow_mut() }.into_node().ascend() { if let Ok(parent) = unsafe { pos.reborrow_mut() }.into_node().ascend() {
if !parent.into_node().forget_type().fix_node_and_affected_ancestors() { if !parent.into_node().forget_type().fix_node_and_affected_ancestors(alloc) {
handle_emptied_internal_root(); handle_emptied_internal_root();
} }
} }
@ -70,16 +73,17 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
} }
impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::KV> { impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::KV> {
fn remove_internal_kv<F: FnOnce()>( fn remove_internal_kv<F: FnOnce(), A: Allocator>(
self, self,
handle_emptied_internal_root: F, handle_emptied_internal_root: F,
alloc: &A,
) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) { ) -> ((K, V), Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>) {
// Remove an adjacent KV from its leaf and then put it back in place of // Remove an adjacent KV from its leaf and then put it back in place of
// the element we were asked to remove. Prefer the left adjacent KV, // the element we were asked to remove. Prefer the left adjacent KV,
// for the reasons listed in `choose_parent_kv`. // for the reasons listed in `choose_parent_kv`.
let left_leaf_kv = self.left_edge().descend().last_leaf_edge().left_kv(); let left_leaf_kv = self.left_edge().descend().last_leaf_edge().left_kv();
let left_leaf_kv = unsafe { left_leaf_kv.ok().unwrap_unchecked() }; let left_leaf_kv = unsafe { left_leaf_kv.ok().unwrap_unchecked() };
let (left_kv, left_hole) = left_leaf_kv.remove_leaf_kv(handle_emptied_internal_root); let (left_kv, left_hole) = left_leaf_kv.remove_leaf_kv(handle_emptied_internal_root, alloc);
// The internal node may have been stolen from or merged. Go back right // The internal node may have been stolen from or merged. Go back right
// to find where the original KV ended up. // to find where the original KV ended up.

View file

@ -3,16 +3,20 @@
use crate::vec::Vec; use crate::vec::Vec;
use core::borrow::Borrow; use core::borrow::Borrow;
use core::cmp::Ordering::{Equal, Greater, Less}; use core::cmp::Ordering::{self, Equal, Greater, Less};
use core::cmp::{max, min}; use core::cmp::{max, min};
use core::fmt::{self, Debug}; use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};
use core::iter::{FromIterator, FusedIterator, Peekable}; use core::iter::{FromIterator, FusedIterator, Peekable};
use core::mem::ManuallyDrop;
use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub}; use core::ops::{BitAnd, BitOr, BitXor, RangeBounds, Sub};
use super::map::{BTreeMap, Keys}; use super::map::{BTreeMap, Keys};
use super::merge_iter::MergeIterInner; use super::merge_iter::MergeIterInner;
use super::Recover; use super::Recover;
use crate::alloc::{Allocator, Global};
// FIXME(conventions): implement bounded iterators // FIXME(conventions): implement bounded iterators
/// An ordered set based on a B-Tree. /// An ordered set based on a B-Tree.
@ -71,15 +75,48 @@ use super::Recover;
/// ///
/// let set = BTreeSet::from([1, 2, 3]); /// let set = BTreeSet::from([1, 2, 3]);
/// ``` /// ```
#[derive(Hash, PartialEq, Eq, Ord, PartialOrd)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeSet")] #[cfg_attr(not(test), rustc_diagnostic_item = "BTreeSet")]
pub struct BTreeSet<T> { pub struct BTreeSet<
map: BTreeMap<T, ()>, T,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
map: BTreeMap<T, (), A>,
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone> Clone for BTreeSet<T> { impl<T: Hash, A: Allocator> Hash for BTreeSet<T, A> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.map.hash(state)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PartialEq, A: Allocator> PartialEq for BTreeSet<T, A> {
fn eq(&self, other: &BTreeSet<T, A>) -> bool {
self.map.eq(&other.map)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Eq, A: Allocator> Eq for BTreeSet<T, A> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: PartialOrd, A: Allocator> PartialOrd for BTreeSet<T, A> {
fn partial_cmp(&self, other: &BTreeSet<T, A>) -> Option<Ordering> {
self.map.partial_cmp(&other.map)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord, A: Allocator> Ord for BTreeSet<T, A> {
fn cmp(&self, other: &BTreeSet<T, A>) -> Ordering {
self.map.cmp(&other.map)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone, A: Allocator + Clone> Clone for BTreeSet<T, A> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
BTreeSet { map: self.map.clone() } BTreeSet { map: self.map.clone() }
} }
@ -117,8 +154,11 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
/// [`IntoIterator`]: core::iter::IntoIterator /// [`IntoIterator`]: core::iter::IntoIterator
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[derive(Debug)] #[derive(Debug)]
pub struct IntoIter<T> { pub struct IntoIter<
iter: super::map::IntoIter<T, ()>, T,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
iter: super::map::IntoIter<T, (), A>,
} }
/// An iterator over a sub-range of items in a `BTreeSet`. /// An iterator over a sub-range of items in a `BTreeSet`.
@ -143,11 +183,14 @@ pub struct Range<'a, T: 'a> {
#[must_use = "this returns the difference as an iterator, \ #[must_use = "this returns the difference as an iterator, \
without modifying either input set"] without modifying either input set"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Difference<'a, T: 'a> { pub struct Difference<
inner: DifferenceInner<'a, T>, 'a,
T: 'a,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
inner: DifferenceInner<'a, T, A>,
} }
#[derive(Debug)] enum DifferenceInner<'a, T: 'a, A: Allocator> {
enum DifferenceInner<'a, T: 'a> {
Stitch { Stitch {
// iterate all of `self` and some of `other`, spotting matches along the way // iterate all of `self` and some of `other`, spotting matches along the way
self_iter: Iter<'a, T>, self_iter: Iter<'a, T>,
@ -156,13 +199,32 @@ enum DifferenceInner<'a, T: 'a> {
Search { Search {
// iterate `self`, look up in `other` // iterate `self`, look up in `other`
self_iter: Iter<'a, T>, self_iter: Iter<'a, T>,
other_set: &'a BTreeSet<T>, other_set: &'a BTreeSet<T, A>,
}, },
Iterate(Iter<'a, T>), // simply produce all elements in `self` Iterate(Iter<'a, T>), // simply produce all elements in `self`
} }
// Explicit Debug impl necessary because of issue #26925
impl<T: Debug, A: Allocator> Debug for DifferenceInner<'_, T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DifferenceInner::Stitch { self_iter, other_iter } => f
.debug_struct("Stitch")
.field("self_iter", self_iter)
.field("other_iter", other_iter)
.finish(),
DifferenceInner::Search { self_iter, other_set } => f
.debug_struct("Search")
.field("self_iter", self_iter)
.field("other_iter", other_set)
.finish(),
DifferenceInner::Iterate(x) => f.debug_tuple("Iterate").field(x).finish(),
}
}
}
#[stable(feature = "collection_debug", since = "1.17.0")] #[stable(feature = "collection_debug", since = "1.17.0")]
impl<T: fmt::Debug> fmt::Debug for Difference<'_, T> { impl<T: fmt::Debug, A: Allocator> fmt::Debug for Difference<'_, T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Difference").field(&self.inner).finish() f.debug_tuple("Difference").field(&self.inner).finish()
} }
@ -195,11 +257,14 @@ impl<T: fmt::Debug> fmt::Debug for SymmetricDifference<'_, T> {
#[must_use = "this returns the intersection as an iterator, \ #[must_use = "this returns the intersection as an iterator, \
without modifying either input set"] without modifying either input set"]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Intersection<'a, T: 'a> { pub struct Intersection<
inner: IntersectionInner<'a, T>, 'a,
T: 'a,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> {
inner: IntersectionInner<'a, T, A>,
} }
#[derive(Debug)] enum IntersectionInner<'a, T: 'a, A: Allocator> {
enum IntersectionInner<'a, T: 'a> {
Stitch { Stitch {
// iterate similarly sized sets jointly, spotting matches along the way // iterate similarly sized sets jointly, spotting matches along the way
a: Iter<'a, T>, a: Iter<'a, T>,
@ -208,13 +273,30 @@ enum IntersectionInner<'a, T: 'a> {
Search { Search {
// iterate a small set, look up in the large set // iterate a small set, look up in the large set
small_iter: Iter<'a, T>, small_iter: Iter<'a, T>,
large_set: &'a BTreeSet<T>, large_set: &'a BTreeSet<T, A>,
}, },
Answer(Option<&'a T>), // return a specific element or emptiness Answer(Option<&'a T>), // return a specific element or emptiness
} }
// Explicit Debug impl necessary because of issue #26925
impl<T: Debug, A: Allocator> Debug for IntersectionInner<'_, T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
IntersectionInner::Stitch { a, b } => {
f.debug_struct("Stitch").field("a", a).field("b", b).finish()
}
IntersectionInner::Search { small_iter, large_set } => f
.debug_struct("Search")
.field("small_iter", small_iter)
.field("large_set", large_set)
.finish(),
IntersectionInner::Answer(x) => f.debug_tuple("Answer").field(x).finish(),
}
}
}
#[stable(feature = "collection_debug", since = "1.17.0")] #[stable(feature = "collection_debug", since = "1.17.0")]
impl<T: fmt::Debug> fmt::Debug for Intersection<'_, T> { impl<T: Debug, A: Allocator> Debug for Intersection<'_, T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Intersection").field(&self.inner).finish() f.debug_tuple("Intersection").field(&self.inner).finish()
} }
@ -265,6 +347,26 @@ impl<T> BTreeSet<T> {
pub const fn new() -> BTreeSet<T> { pub const fn new() -> BTreeSet<T> {
BTreeSet { map: BTreeMap::new() } BTreeSet { map: BTreeMap::new() }
} }
}
impl<T, A: Allocator> BTreeSet<T, A> {
/// Makes a new `BTreeSet` with a reasonable choice of B.
///
/// # Examples
///
/// ```
/// # #![allow(unused_mut)]
/// # #![feature(allocator_api)]
/// # #![feature(btreemap_alloc)]
/// use std::collections::BTreeSet;
/// use std::alloc::Global;
///
/// let mut set: BTreeSet<i32> = BTreeSet::new_in(Global);
/// ```
#[unstable(feature = "btreemap_alloc", issue = "32838")]
pub fn new_in(alloc: A) -> BTreeSet<T, A> {
BTreeSet { map: BTreeMap::new_in(alloc) }
}
/// Constructs a double-ended iterator over a sub-range of elements in the set. /// Constructs a double-ended iterator over a sub-range of elements in the set.
/// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will /// The simplest way is to use the range syntax `min..max`, thus `range(min..max)` will
@ -319,7 +421,7 @@ impl<T> BTreeSet<T> {
/// assert_eq!(diff, [1]); /// assert_eq!(diff, [1]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn difference<'a>(&'a self, other: &'a BTreeSet<T>) -> Difference<'a, T> pub fn difference<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Difference<'a, T, A>
where where
T: Ord, T: Ord,
{ {
@ -380,7 +482,10 @@ impl<T> BTreeSet<T> {
/// assert_eq!(sym_diff, [1, 3]); /// assert_eq!(sym_diff, [1, 3]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn symmetric_difference<'a>(&'a self, other: &'a BTreeSet<T>) -> SymmetricDifference<'a, T> pub fn symmetric_difference<'a>(
&'a self,
other: &'a BTreeSet<T, A>,
) -> SymmetricDifference<'a, T>
where where
T: Ord, T: Ord,
{ {
@ -408,7 +513,7 @@ impl<T> BTreeSet<T> {
/// assert_eq!(intersection, [2]); /// assert_eq!(intersection, [2]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T>) -> Intersection<'a, T> pub fn intersection<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Intersection<'a, T, A>
where where
T: Ord, T: Ord,
{ {
@ -459,7 +564,7 @@ impl<T> BTreeSet<T> {
/// assert_eq!(union, [1, 2]); /// assert_eq!(union, [1, 2]);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn union<'a>(&'a self, other: &'a BTreeSet<T>) -> Union<'a, T> pub fn union<'a>(&'a self, other: &'a BTreeSet<T, A>) -> Union<'a, T>
where where
T: Ord, T: Ord,
{ {
@ -479,7 +584,10 @@ impl<T> BTreeSet<T> {
/// assert!(v.is_empty()); /// assert!(v.is_empty());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) { pub fn clear(&mut self)
where
A: Clone,
{
self.map.clear() self.map.clear()
} }
@ -551,7 +659,7 @@ impl<T> BTreeSet<T> {
/// ``` /// ```
#[must_use] #[must_use]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn is_disjoint(&self, other: &BTreeSet<T>) -> bool pub fn is_disjoint(&self, other: &BTreeSet<T, A>) -> bool
where where
T: Ord, T: Ord,
{ {
@ -577,7 +685,7 @@ impl<T> BTreeSet<T> {
/// ``` /// ```
#[must_use] #[must_use]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn is_subset(&self, other: &BTreeSet<T>) -> bool pub fn is_subset(&self, other: &BTreeSet<T, A>) -> bool
where where
T: Ord, T: Ord,
{ {
@ -657,7 +765,7 @@ impl<T> BTreeSet<T> {
/// ``` /// ```
#[must_use] #[must_use]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn is_superset(&self, other: &BTreeSet<T>) -> bool pub fn is_superset(&self, other: &BTreeSet<T, A>) -> bool
where where
T: Ord, T: Ord,
{ {
@ -931,6 +1039,7 @@ impl<T> BTreeSet<T> {
pub fn append(&mut self, other: &mut Self) pub fn append(&mut self, other: &mut Self)
where where
T: Ord, T: Ord,
A: Clone,
{ {
self.map.append(&mut other.map); self.map.append(&mut other.map);
} }
@ -968,6 +1077,7 @@ impl<T> BTreeSet<T> {
pub fn split_off<Q: ?Sized + Ord>(&mut self, value: &Q) -> Self pub fn split_off<Q: ?Sized + Ord>(&mut self, value: &Q) -> Self
where where
T: Borrow<Q> + Ord, T: Borrow<Q> + Ord,
A: Clone,
{ {
BTreeSet { map: self.map.split_off(value) } BTreeSet { map: self.map.split_off(value) }
} }
@ -1002,12 +1112,13 @@ impl<T> BTreeSet<T> {
/// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7]); /// assert_eq!(odds.into_iter().collect::<Vec<_>>(), vec![1, 3, 5, 7]);
/// ``` /// ```
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
pub fn drain_filter<'a, F>(&'a mut self, pred: F) -> DrainFilter<'a, T, F> pub fn drain_filter<'a, F>(&'a mut self, pred: F) -> DrainFilter<'a, T, F, A>
where where
T: Ord, T: Ord,
F: 'a + FnMut(&T) -> bool, F: 'a + FnMut(&T) -> bool,
{ {
DrainFilter { pred, inner: self.map.drain_filter_inner() } let (inner, alloc) = self.map.drain_filter_inner();
DrainFilter { pred, inner, alloc }
} }
/// Gets an iterator that visits the elements in the `BTreeSet` in ascending /// Gets an iterator that visits the elements in the `BTreeSet` in ascending
@ -1093,14 +1204,14 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {
// use stable sort to preserve the insertion order. // use stable sort to preserve the insertion order.
inputs.sort(); inputs.sort();
BTreeSet::from_sorted_iter(inputs.into_iter()) BTreeSet::from_sorted_iter(inputs.into_iter(), Global)
} }
} }
impl<T: Ord> BTreeSet<T> { impl<T: Ord, A: Allocator> BTreeSet<T, A> {
fn from_sorted_iter<I: Iterator<Item = T>>(iter: I) -> BTreeSet<T> { fn from_sorted_iter<I: Iterator<Item = T>>(iter: I, alloc: A) -> BTreeSet<T, A> {
let iter = iter.map(|k| (k, ())); let iter = iter.map(|k| (k, ()));
let map = BTreeMap::bulk_build_from_sorted_iter(iter); let map = BTreeMap::bulk_build_from_sorted_iter(iter, alloc);
BTreeSet { map } BTreeSet { map }
} }
} }
@ -1124,15 +1235,15 @@ impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {
// use stable sort to preserve the insertion order. // use stable sort to preserve the insertion order.
arr.sort(); arr.sort();
let iter = IntoIterator::into_iter(arr).map(|k| (k, ())); let iter = IntoIterator::into_iter(arr).map(|k| (k, ()));
let map = BTreeMap::bulk_build_from_sorted_iter(iter); let map = BTreeMap::bulk_build_from_sorted_iter(iter, Global);
BTreeSet { map } BTreeSet { map }
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> IntoIterator for BTreeSet<T> { impl<T, A: Allocator> IntoIterator for BTreeSet<T, A> {
type Item = T; type Item = T;
type IntoIter = IntoIter<T>; type IntoIter = IntoIter<T, A>;
/// Gets an iterator for moving out the `BTreeSet`'s contents. /// Gets an iterator for moving out the `BTreeSet`'s contents.
/// ///
@ -1146,13 +1257,13 @@ impl<T> IntoIterator for BTreeSet<T> {
/// let v: Vec<_> = set.into_iter().collect(); /// let v: Vec<_> = set.into_iter().collect();
/// assert_eq!(v, [1, 2, 3, 4]); /// assert_eq!(v, [1, 2, 3, 4]);
/// ``` /// ```
fn into_iter(self) -> IntoIter<T> { fn into_iter(self) -> IntoIter<T, A> {
IntoIter { iter: self.map.into_iter() } IntoIter { iter: self.map.into_iter() }
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> IntoIterator for &'a BTreeSet<T> { impl<'a, T, A: Allocator> IntoIterator for &'a BTreeSet<T, A> {
type Item = &'a T; type Item = &'a T;
type IntoIter = Iter<'a, T>; type IntoIter = Iter<'a, T>;
@ -1163,17 +1274,22 @@ impl<'a, T> IntoIterator for &'a BTreeSet<T> {
/// An iterator produced by calling `drain_filter` on BTreeSet. /// An iterator produced by calling `drain_filter` on BTreeSet.
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
pub struct DrainFilter<'a, T, F> pub struct DrainFilter<
where 'a,
T,
F,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
> where
T: 'a, T: 'a,
F: 'a + FnMut(&T) -> bool, F: 'a + FnMut(&T) -> bool,
{ {
pred: F, pred: F,
inner: super::map::DrainFilterInner<'a, T, ()>, inner: super::map::DrainFilterInner<'a, T, ()>,
alloc: &'a A,
} }
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
impl<T, F> Drop for DrainFilter<'_, T, F> impl<T, F, A: Allocator> Drop for DrainFilter<'_, T, F, A>
where where
F: FnMut(&T) -> bool, F: FnMut(&T) -> bool,
{ {
@ -1183,7 +1299,7 @@ where
} }
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
impl<T, F> fmt::Debug for DrainFilter<'_, T, F> impl<T, F, A: Allocator> fmt::Debug for DrainFilter<'_, T, F, A>
where where
T: fmt::Debug, T: fmt::Debug,
F: FnMut(&T) -> bool, F: FnMut(&T) -> bool,
@ -1194,7 +1310,7 @@ where
} }
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
impl<'a, T, F> Iterator for DrainFilter<'_, T, F> impl<'a, T, F, A: Allocator> Iterator for DrainFilter<'_, T, F, A>
where where
F: 'a + FnMut(&T) -> bool, F: 'a + FnMut(&T) -> bool,
{ {
@ -1203,7 +1319,7 @@ where
fn next(&mut self) -> Option<T> { fn next(&mut self) -> Option<T> {
let pred = &mut self.pred; let pred = &mut self.pred;
let mut mapped_pred = |k: &T, _v: &mut ()| pred(k); let mut mapped_pred = |k: &T, _v: &mut ()| pred(k);
self.inner.next(&mut mapped_pred).map(|(k, _)| k) self.inner.next(&mut mapped_pred, &self.alloc).map(|(k, _)| k)
} }
fn size_hint(&self) -> (usize, Option<usize>) { fn size_hint(&self) -> (usize, Option<usize>) {
@ -1212,10 +1328,10 @@ where
} }
#[unstable(feature = "btree_drain_filter", issue = "70530")] #[unstable(feature = "btree_drain_filter", issue = "70530")]
impl<T, F> FusedIterator for DrainFilter<'_, T, F> where F: FnMut(&T) -> bool {} impl<T, F, A: Allocator> FusedIterator for DrainFilter<'_, T, F, A> where F: FnMut(&T) -> bool {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord> Extend<T> for BTreeSet<T> { impl<T: Ord, A: Allocator> Extend<T> for BTreeSet<T, A> {
#[inline] #[inline]
fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) { fn extend<Iter: IntoIterator<Item = T>>(&mut self, iter: Iter) {
iter.into_iter().for_each(move |elem| { iter.into_iter().for_each(move |elem| {
@ -1230,7 +1346,7 @@ impl<T: Ord> Extend<T> for BTreeSet<T> {
} }
#[stable(feature = "extend_ref", since = "1.2.0")] #[stable(feature = "extend_ref", since = "1.2.0")]
impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BTreeSet<T> { impl<'a, T: 'a + Ord + Copy, A: Allocator> Extend<&'a T> for BTreeSet<T, A> {
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().cloned()); self.extend(iter.into_iter().cloned());
} }
@ -1250,8 +1366,8 @@ impl<T> Default for BTreeSet<T> {
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord + Clone> Sub<&BTreeSet<T>> for &BTreeSet<T> { impl<T: Ord + Clone, A: Allocator + Clone> Sub<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T>; type Output = BTreeSet<T, A>;
/// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`. /// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
/// ///
@ -1266,14 +1382,17 @@ impl<T: Ord + Clone> Sub<&BTreeSet<T>> for &BTreeSet<T> {
/// let result = &a - &b; /// let result = &a - &b;
/// assert_eq!(result, BTreeSet::from([1, 2])); /// assert_eq!(result, BTreeSet::from([1, 2]));
/// ``` /// ```
fn sub(self, rhs: &BTreeSet<T>) -> BTreeSet<T> { fn sub(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(self.difference(rhs).cloned()) BTreeSet::from_sorted_iter(
self.difference(rhs).cloned(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord + Clone> BitXor<&BTreeSet<T>> for &BTreeSet<T> { impl<T: Ord + Clone, A: Allocator + Clone> BitXor<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T>; type Output = BTreeSet<T, A>;
/// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`. /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
/// ///
@ -1288,14 +1407,17 @@ impl<T: Ord + Clone> BitXor<&BTreeSet<T>> for &BTreeSet<T> {
/// let result = &a ^ &b; /// let result = &a ^ &b;
/// assert_eq!(result, BTreeSet::from([1, 4])); /// assert_eq!(result, BTreeSet::from([1, 4]));
/// ``` /// ```
fn bitxor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> { fn bitxor(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(self.symmetric_difference(rhs).cloned()) BTreeSet::from_sorted_iter(
self.symmetric_difference(rhs).cloned(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord + Clone> BitAnd<&BTreeSet<T>> for &BTreeSet<T> { impl<T: Ord + Clone, A: Allocator + Clone> BitAnd<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T>; type Output = BTreeSet<T, A>;
/// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`. /// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
/// ///
@ -1310,14 +1432,17 @@ impl<T: Ord + Clone> BitAnd<&BTreeSet<T>> for &BTreeSet<T> {
/// let result = &a & &b; /// let result = &a & &b;
/// assert_eq!(result, BTreeSet::from([2, 3])); /// assert_eq!(result, BTreeSet::from([2, 3]));
/// ``` /// ```
fn bitand(self, rhs: &BTreeSet<T>) -> BTreeSet<T> { fn bitand(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(self.intersection(rhs).cloned()) BTreeSet::from_sorted_iter(
self.intersection(rhs).cloned(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Ord + Clone> BitOr<&BTreeSet<T>> for &BTreeSet<T> { impl<T: Ord + Clone, A: Allocator + Clone> BitOr<&BTreeSet<T, A>> for &BTreeSet<T, A> {
type Output = BTreeSet<T>; type Output = BTreeSet<T, A>;
/// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`. /// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
/// ///
@ -1332,13 +1457,16 @@ impl<T: Ord + Clone> BitOr<&BTreeSet<T>> for &BTreeSet<T> {
/// let result = &a | &b; /// let result = &a | &b;
/// assert_eq!(result, BTreeSet::from([1, 2, 3, 4, 5])); /// assert_eq!(result, BTreeSet::from([1, 2, 3, 4, 5]));
/// ``` /// ```
fn bitor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> { fn bitor(self, rhs: &BTreeSet<T, A>) -> BTreeSet<T, A> {
BTreeSet::from_sorted_iter(self.union(rhs).cloned()) BTreeSet::from_sorted_iter(
self.union(rhs).cloned(),
ManuallyDrop::into_inner(self.map.alloc.clone()),
)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T: Debug> Debug for BTreeSet<T> { impl<T: Debug, A: Allocator> Debug for BTreeSet<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish() f.debug_set().entries(self.iter()).finish()
} }
@ -1391,7 +1519,7 @@ impl<T> ExactSizeIterator for Iter<'_, T> {
impl<T> FusedIterator for Iter<'_, T> {} impl<T> FusedIterator for Iter<'_, T> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> Iterator for IntoIter<T> { impl<T, A: Allocator> Iterator for IntoIter<T, A> {
type Item = T; type Item = T;
fn next(&mut self) -> Option<T> { fn next(&mut self) -> Option<T> {
@ -1403,20 +1531,20 @@ impl<T> Iterator for IntoIter<T> {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> DoubleEndedIterator for IntoIter<T> { impl<T, A: Allocator> DoubleEndedIterator for IntoIter<T, A> {
fn next_back(&mut self) -> Option<T> { fn next_back(&mut self) -> Option<T> {
self.iter.next_back().map(|(k, _)| k) self.iter.next_back().map(|(k, _)| k)
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> ExactSizeIterator for IntoIter<T> { impl<T, A: Allocator> ExactSizeIterator for IntoIter<T, A> {
fn len(&self) -> usize { fn len(&self) -> usize {
self.iter.len() self.iter.len()
} }
} }
#[stable(feature = "fused", since = "1.26.0")] #[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for IntoIter<T> {} impl<T, A: Allocator> FusedIterator for IntoIter<T, A> {}
#[stable(feature = "btree_range", since = "1.17.0")] #[stable(feature = "btree_range", since = "1.17.0")]
impl<T> Clone for Range<'_, T> { impl<T> Clone for Range<'_, T> {
@ -1457,7 +1585,7 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> {
impl<T> FusedIterator for Range<'_, T> {} impl<T> FusedIterator for Range<'_, T> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Difference<'_, T> { impl<T, A: Allocator + Clone> Clone for Difference<'_, T, A> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Difference { Difference {
inner: match &self.inner { inner: match &self.inner {
@ -1474,7 +1602,7 @@ impl<T> Clone for Difference<'_, T> {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Ord> Iterator for Difference<'a, T> { impl<'a, T: Ord, A: Allocator> Iterator for Difference<'a, T, A> {
type Item = &'a T; type Item = &'a T;
fn next(&mut self) -> Option<&'a T> { fn next(&mut self) -> Option<&'a T> {
@ -1521,7 +1649,7 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
} }
#[stable(feature = "fused", since = "1.26.0")] #[stable(feature = "fused", since = "1.26.0")]
impl<T: Ord> FusedIterator for Difference<'_, T> {} impl<T: Ord, A: Allocator> FusedIterator for Difference<'_, T, A> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for SymmetricDifference<'_, T> { impl<T> Clone for SymmetricDifference<'_, T> {
@ -1559,7 +1687,7 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
impl<T: Ord> FusedIterator for SymmetricDifference<'_, T> {} impl<T: Ord> FusedIterator for SymmetricDifference<'_, T> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Intersection<'_, T> { impl<T, A: Allocator + Clone> Clone for Intersection<'_, T, A> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Intersection { Intersection {
inner: match &self.inner { inner: match &self.inner {
@ -1575,7 +1703,7 @@ impl<T> Clone for Intersection<'_, T> {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Ord> Iterator for Intersection<'a, T> { impl<'a, T: Ord, A: Allocator> Iterator for Intersection<'a, T, A> {
type Item = &'a T; type Item = &'a T;
fn next(&mut self) -> Option<&'a T> { fn next(&mut self) -> Option<&'a T> {
@ -1616,7 +1744,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
} }
#[stable(feature = "fused", since = "1.26.0")] #[stable(feature = "fused", since = "1.26.0")]
impl<T: Ord> FusedIterator for Intersection<'_, T> {} impl<T: Ord, A: Allocator> FusedIterator for Intersection<'_, T, A> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for Union<'_, T> { impl<T> Clone for Union<'_, T> {

View file

@ -1,5 +1,6 @@
use super::node::{ForceResult::*, Root}; use super::node::{ForceResult::*, Root};
use super::search::SearchResult::*; use super::search::SearchResult::*;
use core::alloc::Allocator;
use core::borrow::Borrow; use core::borrow::Borrow;
impl<K, V> Root<K, V> { impl<K, V> Root<K, V> {
@ -28,12 +29,12 @@ impl<K, V> Root<K, V> {
/// and if the ordering of `Q` corresponds to that of `K`. /// and if the ordering of `Q` corresponds to that of `K`.
/// If `self` respects all `BTreeMap` tree invariants, then both /// If `self` respects all `BTreeMap` tree invariants, then both
/// `self` and the returned tree will respect those invariants. /// `self` and the returned tree will respect those invariants.
pub fn split_off<Q: ?Sized + Ord>(&mut self, key: &Q) -> Self pub fn split_off<Q: ?Sized + Ord, A: Allocator>(&mut self, key: &Q, alloc: &A) -> Self
where where
K: Borrow<Q>, K: Borrow<Q>,
{ {
let left_root = self; let left_root = self;
let mut right_root = Root::new_pillar(left_root.height()); let mut right_root = Root::new_pillar(left_root.height(), alloc);
let mut left_node = left_root.borrow_mut(); let mut left_node = left_root.borrow_mut();
let mut right_node = right_root.borrow_mut(); let mut right_node = right_root.borrow_mut();
@ -56,16 +57,16 @@ impl<K, V> Root<K, V> {
} }
} }
left_root.fix_right_border(); left_root.fix_right_border(alloc);
right_root.fix_left_border(); right_root.fix_left_border(alloc);
right_root right_root
} }
/// Creates a tree consisting of empty nodes. /// Creates a tree consisting of empty nodes.
fn new_pillar(height: usize) -> Self { fn new_pillar<A: Allocator>(height: usize, alloc: &A) -> Self {
let mut root = Root::new(); let mut root = Root::new(alloc);
for _ in 0..height { for _ in 0..height {
root.push_internal_level(); root.push_internal_level(alloc);
} }
root root
} }