From 35c7943fd2d2a65b63712d95d62c8837633218b4 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Tue, 5 Sep 2017 12:34:05 -0400 Subject: [PATCH 1/3] Add or_default to Entry APIs --- .../src/library-features/entry_or_default.md | 13 +++++++++ src/liballoc/btree/map.rs | 29 +++++++++++++++++++ src/libstd/collections/hash/map.rs | 29 +++++++++++++++++++ 3 files changed, 71 insertions(+) create mode 100644 src/doc/unstable-book/src/library-features/entry_or_default.md diff --git a/src/doc/unstable-book/src/library-features/entry_or_default.md b/src/doc/unstable-book/src/library-features/entry_or_default.md new file mode 100644 index 0000000000000..f8c8a2a7a718b --- /dev/null +++ b/src/doc/unstable-book/src/library-features/entry_or_default.md @@ -0,0 +1,13 @@ +# `entry_or_default` + +The tracking issue for this feature is: [#44324] + +[#44324]: https://github.com/rust-lang/rust/issues/44324 + +------------------------ + +The `entry_or_default` feature adds a new method to `hash_map::Entry` +and `btree_map::Entry`, `or_default`, when `V: Default`. This method is +semantically identical to `or_insert_with(Default::default)`, and will +insert the default value for the type if no entry exists for the current +key. diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index f733c3332e282..0adfaf3be8f29 100644 --- a/src/liballoc/btree/map.rs +++ b/src/liballoc/btree/map.rs @@ -2104,6 +2104,35 @@ impl<'a, K: Ord, V> Entry<'a, K, V> { } } +impl<'a, K: Ord, V: Default> Entry<'a, K, V> { + #[unstable(feature = "entry_or_default", issue = "44324")] + /// 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. + /// + /// # Examples + /// + /// ``` + /// #![feature(entry_or_default)] + /// # fn main() { + /// use std::collections::BTreeMap; + /// + /// let mut map: BTreeMap<&str, String> = BTreeMap::new(); + /// let s = "hoho".to_string(); + /// + /// map.entry("poneyland").or_default(); + /// + /// assert_eq!(map["poneyland"], None); + /// # } + /// ``` + pub fn or_default(self) -> &'a mut V { + match self { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.insert(Default::default()), + } + } + +} + impl<'a, K: Ord, V> VacantEntry<'a, K, V> { /// Gets a reference to the key that would be used when inserting a value /// through the VacantEntry. diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 16b0c70998616..36399067a12cd 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2001,6 +2001,35 @@ impl<'a, K, V> Entry<'a, K, V> { } } +impl<'a, K, V: Default> Entry<'a, K, V> { + #[unstable(feature = "entry_or_default", issue = "44324")] + /// 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. + /// + /// # Examples + /// + /// ``` + /// #![feature(entry_or_default)] + /// # fn main() { + /// use std::collections::HashMap; + /// + /// let mut map: HashMap<&str, Option> = HashMap::new(); + /// let s = "hoho".to_string(); + /// + /// map.entry("poneyland").or_default(); + /// + /// assert_eq!(map["poneyland"], None); + /// # } + /// ``` + pub fn or_default(self) -> &'a mut V { + match self { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.insert(Default::default()), + } + } + +} + impl<'a, K, V> OccupiedEntry<'a, K, V> { /// Gets a reference to the key in the entry. /// From 00bdae02fdbb2e27e4d27a54683537faa33b3f17 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Tue, 5 Sep 2017 13:37:36 -0400 Subject: [PATCH 2/3] Avoid weird or_insert_with example --- src/liballoc/btree/map.rs | 4 +--- src/libstd/collections/hash/map.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs index 0adfaf3be8f29..4c93fead17237 100644 --- a/src/liballoc/btree/map.rs +++ b/src/liballoc/btree/map.rs @@ -2116,9 +2116,7 @@ impl<'a, K: Ord, V: Default> Entry<'a, K, V> { /// # fn main() { /// use std::collections::BTreeMap; /// - /// let mut map: BTreeMap<&str, String> = BTreeMap::new(); - /// let s = "hoho".to_string(); - /// + /// let mut map: BTreeMap<&str, Option> = BTreeMap::new(); /// map.entry("poneyland").or_default(); /// /// assert_eq!(map["poneyland"], None); diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 36399067a12cd..fbb69ca974930 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -2013,9 +2013,7 @@ impl<'a, K, V: Default> Entry<'a, K, V> { /// # fn main() { /// use std::collections::HashMap; /// - /// let mut map: HashMap<&str, Option> = HashMap::new(); - /// let s = "hoho".to_string(); - /// + /// let mut map: HashMap<&str, Option> = HashMap::new(); /// map.entry("poneyland").or_default(); /// /// assert_eq!(map["poneyland"], None); From 9389d26ba261119bec1dc5336d17ce23c34785b7 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Tue, 5 Sep 2017 14:21:44 -0400 Subject: [PATCH 3/3] use - for unstable book filenames --- .../library-features/{entry_or_default.md => entry-or-default.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/doc/unstable-book/src/library-features/{entry_or_default.md => entry-or-default.md} (100%) diff --git a/src/doc/unstable-book/src/library-features/entry_or_default.md b/src/doc/unstable-book/src/library-features/entry-or-default.md similarity index 100% rename from src/doc/unstable-book/src/library-features/entry_or_default.md rename to src/doc/unstable-book/src/library-features/entry-or-default.md