Skip to content

Tracking Issue for BTreeSet entry APIs #133549

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
1 of 3 tasks
cuviper opened this issue Nov 27, 2024 · 1 comment
Open
1 of 3 tasks

Tracking Issue for BTreeSet entry APIs #133549

cuviper opened this issue Nov 27, 2024 · 1 comment
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@cuviper
Copy link
Member

cuviper commented Nov 27, 2024

Feature gate: #![feature(btree_set_entry)]

This is a tracking issue for Entry and entry-like methods on BTreeSet.

Public API

impl<T, A: Allocator + Clone> BTreeSet<T, A> {
    pub fn get_or_insert(&mut self, value: T) -> &T
    where
        T: Ord,
    {...}
    pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
    where
        T: Borrow<Q> + Ord,
        Q: Ord,
        F: FnOnce(&Q) -> T,
    {...}

    pub fn entry(&mut self, value: T) -> Entry<'_, T, A>
    where
        T: Ord,
    {...}
}

pub enum Entry<'a, T, A: Allocator + Clone = Global> {
    Occupied(OccupiedEntry<'a, T, A>),
    Vacant(VacantEntry<'a, T, A>),
}
pub struct OccupiedEntry<'a, T, A: Allocator + Clone = Global> {...}
pub struct VacantEntry<'a, T, A: Allocator + Clone = Global> {...}

impl<T: Debug + Ord, A: Allocator + Clone> Debug for Entry<'_, T, A> {...}
impl<T: Debug + Ord, A: Allocator + Clone> Debug for OccupiedEntry<'_, T, A> {...}
impl<T: Debug + Ord, A: Allocator + Clone> Debug for VacantEntry<'_, T, A> {...}

impl<'a, T: Ord, A: Allocator + Clone> Entry<'a, T, A> {
    pub fn insert(self) -> OccupiedEntry<'a, T, A> {...}
    pub fn or_insert(self) {...}
    pub fn get(&self) -> &T {...}
}

impl<'a, T: Ord, A: Allocator + Clone> OccupiedEntry<'a, T, A> {
    pub fn get(&self) -> &T {...}
    pub fn remove(self) -> T {...}
}

impl<'a, T: Ord, A: Allocator + Clone> VacantEntry<'a, T, A> {
    pub fn get(&self) -> &T {...}
    pub fn into_value(self) -> T {...}
    pub fn insert(self) {...}
}

Steps / History

Unresolved Questions

  • None yet.

See also #60896 for HashSet.

Footnotes

  1. https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html

@cuviper cuviper added C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Nov 27, 2024
jieyouxu added a commit to jieyouxu/rust that referenced this issue Nov 30, 2024
…-Simulacrum

Add `BTreeSet` entry APIs to match `HashSet`

The following methods are added, along with the corresponding `Entry` implementation.

```rust
impl<T, A: Allocator + Clone> BTreeSet<T, A> {
    pub fn get_or_insert(&mut self, value: T) -> &T
    where
        T: Ord,
    {...}
    pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
    where
        T: Borrow<Q> + Ord,
        Q: Ord,
        F: FnOnce(&Q) -> T,
    {...}

    pub fn entry(&mut self, value: T) -> Entry<'_, T, A>
    where
        T: Ord,
    {...}
}
```

Tracking issue rust-lang#133549
Closes rust-lang/rfcs#1490
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Nov 30, 2024
Rollup merge of rust-lang#133548 - cuviper:btreeset-entry-api, r=Mark-Simulacrum

Add `BTreeSet` entry APIs to match `HashSet`

The following methods are added, along with the corresponding `Entry` implementation.

```rust
impl<T, A: Allocator + Clone> BTreeSet<T, A> {
    pub fn get_or_insert(&mut self, value: T) -> &T
    where
        T: Ord,
    {...}
    pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
    where
        T: Borrow<Q> + Ord,
        Q: Ord,
        F: FnOnce(&Q) -> T,
    {...}

    pub fn entry(&mut self, value: T) -> Entry<'_, T, A>
    where
        T: Ord,
    {...}
}
```

Tracking issue rust-lang#133549
Closes rust-lang/rfcs#1490
github-actions bot pushed a commit to tautschnig/verify-rust-std that referenced this issue Mar 11, 2025
…-Simulacrum

Add `BTreeSet` entry APIs to match `HashSet`

The following methods are added, along with the corresponding `Entry` implementation.

```rust
impl<T, A: Allocator + Clone> BTreeSet<T, A> {
    pub fn get_or_insert(&mut self, value: T) -> &T
    where
        T: Ord,
    {...}
    pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
    where
        T: Borrow<Q> + Ord,
        Q: Ord,
        F: FnOnce(&Q) -> T,
    {...}

    pub fn entry(&mut self, value: T) -> Entry<'_, T, A>
    where
        T: Ord,
    {...}
}
```

Tracking issue rust-lang#133549
Closes rust-lang/rfcs#1490
@sunshowers
Copy link
Contributor

sunshowers commented May 24, 2025

I have a fun use case for this related to https://docs.rs/iddqd: as part of it I need a sorted set with a custom comparator which must be passed in (data required for comparisons cannot really be stored on the elements themselves).

I'm currently using a thread-local for this purpose, but I realized that Borrow provides just enough flexibility to make this possible without a thread-local.

For the three basic operations, find, insert, and remove:

  • find and remove work on stable Rust today.
  • insert does not work because it accepts a concrete T, not a borrowed form of it. However, as of rustc 1.89.0-nightly (4d051fb30 2025-05-18), get_or_insert_with works great for my purpose.

I've written up some notes at https://github.com/oxidecomputer/iddqd/blob/37da27bc6eb62f23e19f947b0487e01bd17bf209/crates/iddqd/src/support/btree_table.rs#L21-L66, and I have a PoC showing get_or_insert_with working with nightly Rust and removing a bunch of unsafe code: oxidecomputer/iddqd#16

I know this is pushing the limits of what's legal with BTreeSet, but it would be really cool to have get_or_insert_with available.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

2 participants