@@ -7,12 +7,17 @@ use core::iter::{FusedIterator, Peekable};
77use core:: mem:: ManuallyDrop ;
88use core:: ops:: { BitAnd , BitOr , BitXor , Bound , RangeBounds , Sub } ;
99
10- use super :: map:: { BTreeMap , Keys } ;
10+ use super :: map:: { self , BTreeMap , Keys } ;
1111use super :: merge_iter:: MergeIterInner ;
1212use super :: set_val:: SetValZST ;
1313use crate :: alloc:: { Allocator , Global } ;
1414use crate :: vec:: Vec ;
1515
16+ mod entry;
17+
18+ #[ unstable( feature = "btree_set_entry" , issue = "none" ) ]
19+ pub use self :: entry:: { Entry , OccupiedEntry , VacantEntry } ;
20+
1621/// An ordered set based on a B-Tree.
1722///
1823/// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance
@@ -928,6 +933,79 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
928933 self . map . replace ( value)
929934 }
930935
936+ /// Inserts the given `value` into the set if it is not present, then
937+ /// returns a reference to the value in the set.
938+ ///
939+ /// # Examples
940+ ///
941+ /// ```
942+ /// #![feature(btree_set_entry)]
943+ ///
944+ /// use std::collections::BTreeSet;
945+ ///
946+ /// let mut set = BTreeSet::from([1, 2, 3]);
947+ /// assert_eq!(set.len(), 3);
948+ /// assert_eq!(set.get_or_insert(2), &2);
949+ /// assert_eq!(set.get_or_insert(100), &100);
950+ /// assert_eq!(set.len(), 4); // 100 was inserted
951+ /// ```
952+ #[ inline]
953+ #[ unstable( feature = "btree_set_entry" , issue = "none" ) ]
954+ pub fn get_or_insert ( & mut self , value : T ) -> & T
955+ where
956+ T : Ord ,
957+ {
958+ self . map . entry ( value) . insert_entry ( SetValZST ) . into_key ( )
959+ }
960+
961+ /// Inserts a value computed from `f` into the set if the given `value` is
962+ /// not present, then returns a reference to the value in the set.
963+ ///
964+ /// # Examples
965+ ///
966+ /// ```
967+ /// #![feature(btree_set_entry)]
968+ ///
969+ /// use std::collections::BTreeSet;
970+ ///
971+ /// let mut set: BTreeSet<String> = ["cat", "dog", "horse"]
972+ /// .iter().map(|&pet| pet.to_owned()).collect();
973+ ///
974+ /// assert_eq!(set.len(), 3);
975+ /// for &pet in &["cat", "dog", "fish"] {
976+ /// let value = set.get_or_insert_with(pet, str::to_owned);
977+ /// assert_eq!(value, pet);
978+ /// }
979+ /// assert_eq!(set.len(), 4); // a new "fish" was inserted
980+ /// ```
981+ #[ inline]
982+ #[ unstable( feature = "btree_set_entry" , issue = "none" ) ]
983+ pub fn get_or_insert_with < Q : ?Sized , F > ( & mut self , value : & Q , f : F ) -> & T
984+ where
985+ T : Borrow < Q > + Ord ,
986+ Q : Ord ,
987+ F : FnOnce ( & Q ) -> T ,
988+ {
989+ self . map . get_or_insert_with ( value, f)
990+ }
991+
992+ /// Gets the given value's corresponding entry in the set for in-place manipulation.
993+ ///
994+ /// # Examples
995+ ///
996+ /// TODO
997+ #[ inline]
998+ #[ unstable( feature = "btree_set_entry" , issue = "none" ) ]
999+ pub fn entry ( & mut self , value : T ) -> Entry < ' _ , T , A >
1000+ where
1001+ T : Ord ,
1002+ {
1003+ match self . map . entry ( value) {
1004+ map:: Entry :: Occupied ( entry) => Entry :: Occupied ( OccupiedEntry { inner : entry } ) ,
1005+ map:: Entry :: Vacant ( entry) => Entry :: Vacant ( VacantEntry { inner : entry } ) ,
1006+ }
1007+ }
1008+
9311009 /// If the set contains an element equal to the value, removes it from the
9321010 /// set and drops it. Returns whether such an element was present.
9331011 ///
0 commit comments