Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9d9b55c
make invalid_type_param_default lint show up in cargo future-compat r…
RalfJung Jul 15, 2024
bda31d1
built-in derive: remove BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE hack …
RalfJung Jul 18, 2024
9b165a1
Implement cursors for `BTreeSet`
kmicklas Jul 28, 2024
bbeff8c
set `force_recompile: true` if library is modified
onur-ozkan Jul 30, 2024
6fcc630
update download-rustc documentation
onur-ozkan Jul 30, 2024
0204762
Share `UnorderedKeyError` with `BTReeMap` for set API
kmicklas Aug 1, 2024
4560770
Fix some uses of "map" instead of "set" in `BTreeSet` cursor API docs
kmicklas Aug 1, 2024
cbdc377
Introduce `Cursor`/`CursorMut`/`CursorMutKey` thrichotomy for `BTreeS…
kmicklas Aug 1, 2024
0bc501e
Fix mutability in doc tests for `BTreeSet` cursors
kmicklas Aug 1, 2024
8497800
Add test for updating enum discriminant through pointer
clubby789 Aug 1, 2024
9e5c9c1
tests: add regression test for incorrect "builtin attribute is checke…
jieyouxu Aug 4, 2024
9d0eaa2
check_attr: cover multi-segment attributes on specific check arms
jieyouxu Aug 4, 2024
249afea
docs(resolve): more explain about `target`
bvanjoi Aug 4, 2024
249d686
rustdoc: Rename `SelfTy` to `ReceiverTy`
camelid Jul 31, 2024
664b3ff
rustdoc: Create `SelfTy` to replace `Generic(kw::SelfUpper)`
camelid Jul 31, 2024
4e348fa
rustdoc: Stop treating `Self` as a generic in search index
camelid Aug 1, 2024
e452e3d
Use `match` instead of sequence of `if let`s
camelid Aug 1, 2024
b4f77df
rustdoc: Delete `ReceiverTy` (formerly known as `SelfTy`)
camelid Aug 1, 2024
dac7f20
Add test for `Self` not being a generic in search index
camelid Aug 1, 2024
831580a
Rollup merge of #127655 - RalfJung:invalid_type_param_default, r=comp…
matthiaskrgr Aug 5, 2024
12c363a
Rollup merge of #127907 - RalfJung:byte_slice_in_packed_struct_with_d…
matthiaskrgr Aug 5, 2024
e698469
Rollup merge of #127974 - onur-ozkan:force-std-builds, r=Mark-Simulacrum
matthiaskrgr Aug 5, 2024
47d0e6e
Rollup merge of #128309 - kmicklas:btreeset-cursor, r=Amanieu
matthiaskrgr Aug 5, 2024
b45a3b2
Rollup merge of #128471 - camelid:rustdoc-self, r=notriddle
matthiaskrgr Aug 5, 2024
06743da
Rollup merge of #128500 - clubby789:122600-test, r=Mark-Simulacrum
matthiaskrgr Aug 5, 2024
30cc5fb
Rollup merge of #128623 - jieyouxu:check-attr-ice, r=nnethercote
matthiaskrgr Aug 5, 2024
f247711
Rollup merge of #128630 - bvanjoi:resolve-comment, r=petrochenkov
matthiaskrgr Aug 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Introduce Cursor/CursorMut/CursorMutKey thrichotomy for `BTreeS…
…et` like map API
  • Loading branch information
kmicklas committed Aug 1, 2024
commit cbdc3778667c5bad3f9eee4124000a0ca96e4590
210 changes: 194 additions & 16 deletions library/alloc/src/collections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1249,25 +1249,25 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
///
/// let mut set = BTreeSet::from([1, 2, 3, 4]);
///
/// let mut cursor = unsafe { set.lower_bound_mut(Bound::Included(&2)) };
/// let mut cursor = set.lower_bound_mut(Bound::Included(&2));
/// assert_eq!(cursor.peek_prev(), Some(&mut 1));
/// assert_eq!(cursor.peek_next(), Some(&mut 2));
///
/// let mut cursor = unsafe { set.lower_bound_mut(Bound::Excluded(&2)) };
/// let mut cursor = set.lower_bound_mut(Bound::Excluded(&2));
/// assert_eq!(cursor.peek_prev(), Some(&mut 2));
/// assert_eq!(cursor.peek_next(), Some(&mut 3));
///
/// let mut cursor = unsafe { set.lower_bound_mut(Bound::Unbounded) };
/// let mut cursor = set.lower_bound_mut(Bound::Unbounded);
/// assert_eq!(cursor.peek_prev(), None);
/// assert_eq!(cursor.peek_next(), Some(&mut 1));
/// ```
#[unstable(feature = "btree_cursors", issue = "107540")]
pub unsafe fn lower_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
pub fn lower_bound_mut<Q: ?Sized>(&mut self, bound: Bound<&Q>) -> CursorMut<'_, T, A>
where
T: Borrow<Q> + Ord,
Q: Ord,
{
CursorMut { inner: unsafe { self.map.lower_bound_mut(bound).with_mutable_key() } }
CursorMut { inner: self.map.lower_bound_mut(bound) }
}

/// Returns a [`Cursor`] pointing at the gap after the greatest element
Expand Down Expand Up @@ -1353,7 +1353,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
T: Borrow<Q> + Ord,
Q: Ord,
{
CursorMut { inner: unsafe { self.map.upper_bound_mut(bound).with_mutable_key() } }
CursorMut { inner: self.map.upper_bound_mut(bound) }
}
}

Expand Down Expand Up @@ -2010,6 +2010,31 @@ impl<K: Debug> Debug for Cursor<'_, K> {
}
}

/// A cursor over a `BTreeSet` with editing operations.
///
/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can
/// safely mutate the set during iteration. This is because the lifetime of its yielded
/// references is tied to its own lifetime, instead of just the underlying map. This means
/// cursors cannot yield multiple elements at once.
///
/// Cursors always point to a gap between two elements in the set, and can
/// operate on the two immediately adjacent elements.
///
/// A `CursorMut` is created with the [`BTreeSet::lower_bound_mut`] and [`BTreeSet::upper_bound_mut`]
/// methods.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub struct CursorMut<'a, K: 'a, #[unstable(feature = "allocator_api", issue = "32838")] A = Global>
{
inner: super::map::CursorMut<'a, K, SetValZST, A>,
}

#[unstable(feature = "btree_cursors", issue = "107540")]
impl<K: Debug, A> Debug for CursorMut<'_, K, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("CursorMut")
}
}

/// A cursor over a `BTreeSet` with editing operations, and which allows
/// mutating elements.
///
Expand All @@ -2021,8 +2046,8 @@ impl<K: Debug> Debug for Cursor<'_, K> {
/// Cursors always point to a gap between two elements in the set, and can
/// operate on the two immediately adjacent elements.
///
/// A `CursorMut` is created with the [`BTreeSet::lower_bound_mut`] and
/// [`BTreeSet::upper_bound_mut`] methods.
/// A `CursorMutKey` is created from a [`CursorMut`] with the
/// [`CursorMut::with_mutable_key`] method.
///
/// # Safety
///
Expand All @@ -2032,15 +2057,18 @@ impl<K: Debug> Debug for Cursor<'_, K> {
/// * The newly inserted element must be unique in the tree.
/// * All elements in the tree must remain in sorted order.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub struct CursorMut<'a, K: 'a, #[unstable(feature = "allocator_api", issue = "32838")] A = Global>
{
pub struct CursorMutKey<
'a,
K: 'a,
#[unstable(feature = "allocator_api", issue = "32838")] A = Global,
> {
inner: super::map::CursorMutKey<'a, K, SetValZST, A>,
}

#[unstable(feature = "btree_cursors", issue = "107540")]
impl<K: Debug, A> Debug for CursorMut<'_, K, A> {
impl<K: Debug, A> Debug for CursorMutKey<'_, K, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("CursorMut")
f.write_str("CursorMutKey")
}
}

Expand Down Expand Up @@ -2089,7 +2117,7 @@ impl<'a, T, A> CursorMut<'a, T, A> {
/// If the cursor is already at the end of the set then `None` is returned
/// and the cursor is not moved.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn next(&mut self) -> Option<&mut T> {
pub fn next(&mut self) -> Option<&T> {
self.inner.next().map(|(k, _)| k)
}

Expand All @@ -2099,23 +2127,23 @@ impl<'a, T, A> CursorMut<'a, T, A> {
/// If the cursor is already at the start of the set then `None` is returned
/// and the cursor is not moved.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn prev(&mut self) -> Option<&mut T> {
pub fn prev(&mut self) -> Option<&T> {
self.inner.prev().map(|(k, _)| k)
}

/// Returns a reference to the next element without moving the cursor.
///
/// If the cursor is at the end of the set then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&mut self) -> Option<&mut T> {
pub fn peek_next(&mut self) -> Option<&T> {
self.inner.peek_next().map(|(k, _)| k)
}

/// Returns a reference to the previous element without moving the cursor.
///
/// If the cursor is at the start of the set then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_prev(&mut self) -> Option<&mut T> {
pub fn peek_prev(&mut self) -> Option<&T> {
self.inner.peek_prev().map(|(k, _)| k)
}

Expand All @@ -2129,6 +2157,70 @@ impl<'a, T, A> CursorMut<'a, T, A> {
pub fn as_cursor(&self) -> Cursor<'_, T> {
Cursor { inner: self.inner.as_cursor() }
}

/// Converts the cursor into a [`CursorMutKey`], which allows mutating
/// elements in the tree.
///
/// # Safety
///
/// Since this cursor allows mutating elements, you must ensure that the
/// `BTreeSet` invariants are maintained. Specifically:
///
/// * The newly inserted element must be unique in the tree.
/// * All elements in the tree must remain in sorted order.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub unsafe fn with_mutable_key(self) -> CursorMutKey<'a, T, A> {
CursorMutKey { inner: unsafe { self.inner.with_mutable_key() } }
}
}

impl<'a, T, A> CursorMutKey<'a, T, A> {
/// Advances the cursor to the next gap, returning the element that it
/// moved over.
///
/// If the cursor is already at the end of the set then `None` is returned
/// and the cursor is not moved.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn next(&mut self) -> Option<&mut T> {
self.inner.next().map(|(k, _)| k)
}

/// Advances the cursor to the previous gap, returning the element that it
/// moved over.
///
/// If the cursor is already at the start of the set then `None` is returned
/// and the cursor is not moved.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn prev(&mut self) -> Option<&mut T> {
self.inner.prev().map(|(k, _)| k)
}

/// Returns a reference to the next element without moving the cursor.
///
/// If the cursor is at the end of the set then `None` is returned
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&mut self) -> Option<&mut T> {
self.inner.peek_next().map(|(k, _)| k)
}

/// Returns a reference to the previous element without moving the cursor.
///
/// If the cursor is at the start of the set then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_prev(&mut self) -> Option<&mut T> {
self.inner.peek_prev().map(|(k, _)| k)
}

/// Returns a read-only cursor pointing to the same location as the
/// `CursorMutKey`.
///
/// The lifetime of the returned `Cursor` is bound to that of the
/// `CursorMutKey`, which means it cannot outlive the `CursorMutKey` and that the
/// `CursorMutKey` is frozen for the lifetime of the `Cursor`.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn as_cursor(&self) -> Cursor<'_, T> {
Cursor { inner: self.inner.as_cursor() }
}
}

impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> {
Expand Down Expand Up @@ -2217,6 +2309,92 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> {
}
}

impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
/// Inserts a new element into the set in the gap that the
/// cursor is currently pointing to.
///
/// After the insertion the cursor will be pointing at the gap before the
/// newly inserted element.
///
/// # Safety
///
/// You must ensure that the `BTreeSet` invariants are maintained.
/// Specifically:
///
/// * The key of the newly inserted element must be unique in the tree.
/// * All elements in the tree must remain in sorted order.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub unsafe fn insert_after_unchecked(&mut self, value: T) {
unsafe { self.inner.insert_after_unchecked(value, SetValZST) }
}

/// Inserts a new element into the set in the gap that the
/// cursor is currently pointing to.
///
/// After the insertion the cursor will be pointing at the gap after the
/// newly inserted element.
///
/// # Safety
///
/// You must ensure that the `BTreeSet` invariants are maintained.
/// Specifically:
///
/// * The newly inserted element must be unique in the tree.
/// * All elements in the tree must remain in sorted order.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub unsafe fn insert_before_unchecked(&mut self, value: T) {
unsafe { self.inner.insert_before_unchecked(value, SetValZST) }
}

/// Inserts a new element into the set in the gap that the
/// cursor is currently pointing to.
///
/// After the insertion the cursor will be pointing at the gap before the
/// newly inserted element.
///
/// If the inserted element is not greater than the element before the
/// cursor (if any), or if it not less than the element after the cursor (if
/// any), then an [`UnorderedKeyError`] is returned since this would
/// invalidate the [`Ord`] invariant between the elements of the set.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn insert_after(&mut self, value: T) -> Result<(), UnorderedKeyError> {
self.inner.insert_after(value, SetValZST)
}

/// Inserts a new element into the set in the gap that the
/// cursor is currently pointing to.
///
/// After the insertion the cursor will be pointing at the gap after the
/// newly inserted element.
///
/// If the inserted element is not greater than the element before the
/// cursor (if any), or if it not less than the element after the cursor (if
/// any), then an [`UnorderedKeyError`] is returned since this would
/// invalidate the [`Ord`] invariant between the elements of the set.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn insert_before(&mut self, value: T) -> Result<(), UnorderedKeyError> {
self.inner.insert_before(value, SetValZST)
}

/// Removes the next element from the `BTreeSet`.
///
/// The element that was removed is returned. The cursor position is
/// unchanged (before the removed element).
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn remove_next(&mut self) -> Option<T> {
self.inner.remove_next().map(|(k, _)| k)
}

/// Removes the precending element from the `BTreeSet`.
///
/// The element that was removed is returned. The cursor position is
/// unchanged (after the removed element).
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn remove_prev(&mut self) -> Option<T> {
self.inner.remove_prev().map(|(k, _)| k)
}
}

#[unstable(feature = "btree_cursors", issue = "107540")]
pub use super::map::UnorderedKeyError;

Expand Down