1mod combined_getters;
2
3#[doc(hidden)]
4pub mod __private {
5 pub use pastey::paste;
6}
7
8#[derive(thiserror::Error, Debug)]
9#[error("Unique contraint violation on {field} for value {value:?}")]
10pub struct UniqueContraintViolation<T> {
11 pub field: &'static str,
12 pub value: T,
13}
14
15#[macro_export]
17macro_rules! multi_index_container {
18 (
19 $(#[$meta:meta])*
20 $vis:vis $map_name:ident<$value_type:ty> {
21 $(unique $unique_name:ident: $unique_key_type:ty => |$unique_param:ident| $unique_expr:expr,)*
22 $(non_unique $non_unique_name:ident: $non_unique_key_type:ty => |$non_unique_param:ident| $non_unique_expr:expr,)*
23 $(unique_ordered $unique_ordered_name:ident: $unique_ordered_key_type:ty => |$unique_ordered_param:ident| $unique_ordered_expr:expr,)*
24 $(non_unique_ordered $non_unique_ordered_name:ident: $non_unique_ordered_key_type:ty => |$non_unique_ordered_param:ident| $non_unique_ordered_expr:expr,)*
25 }
26 ) => {
27 use multi_index_container::__private::paste;
28
29 paste! {
30 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
40 $vis struct [<$map_name StorageIndex>] (usize);
41
42 impl [<$map_name StorageIndex>] {
43 pub fn next(&self) -> Self {
52 Self ( self.0 + 1 )
53 }
54 }
55 }
56
57 $(#[$meta])*
58 #[doc = concat!("A map for storing `", stringify!($value_type), "` indexed by `", stringify!($storage_key_type), "`.")]
59 $(
60 #[doc = concat!("- Unique index `", stringify!($unique_name), "`: `", stringify!($unique_key_type), "`")]
61 )*
62 $(
63 #[doc = concat!("- Non-unique index `", stringify!($non_unique_name), "`: `", stringify!($non_unique_key_type), "`")]
64 )*
65 $(
66 #[doc = concat!("- Unique ordered index `", stringify!($unique_ordered_name), "`: `", stringify!($unique_ordered_key_type), "`")]
67 )*
68 $(
69 #[doc = concat!("- Non-unique ordered index `", stringify!($non_unique_ordered_name), "`: `", stringify!($non_unique_ordered_key_type), "`")]
70 )*
71 $vis struct $map_name {
72
73
74 #[doc = "Storage keys that have been freed and can be reused."]
75 freed_storage_keys: Vec< paste! { [<$map_name StorageIndex>] }>,
76
77 #[doc = "The next storage key to be assigned when no freed keys are available."]
78 next_storage_key: paste! { [<$map_name StorageIndex>] },
79
80 #[doc = concat!("Primary storage mapping each index to its `", stringify!($value_type), "`.")]
81 storage: std::collections::HashMap<paste! { [<$map_name StorageIndex>] }, $value_type>,
82
83 $(
84 #[doc = concat!("Unique index `", stringify!($unique_name), "` mapping `", stringify!($unique_key_type), "` to a single storage index.")]
85 $unique_name: std::collections::HashMap<$unique_key_type, paste! { [<$map_name StorageIndex>] }>,
86 )*
87 $(
88 #[doc = concat!("Non-unique index `", stringify!($non_unique_name), "` mapping `", stringify!($non_unique_key_type), "` to a set of storage indices.")]
89 $non_unique_name: std::collections::HashMap<$non_unique_key_type, std::collections::HashSet< paste! { [<$map_name StorageIndex>] } >>,
90 )*
91 $(
92 #[doc = concat!("Unique ordered index `", stringify!($unique_ordered_name), "` mapping `", stringify!($unique_ordered_key_type), "` to a single storage index.")]
93 $unique_ordered_name: std::collections::BTreeMap<$unique_ordered_key_type, paste! { [<$map_name StorageIndex>] } >,
94 )*
95 $(
96 #[doc = concat!("Non-unique ordered index `", stringify!($non_unique_ordered_name), "` mapping `", stringify!($non_unique_ordered_key_type), "` to a set of storage indices.")]
97 $non_unique_ordered_name: std::collections::BTreeMap<$non_unique_ordered_key_type, std::collections::HashSet< paste! { [<$map_name StorageIndex>] } >>,
98 )*
99 }
100
101 impl $map_name {
102
103 #[doc = concat!("Initialise an empty ", stringify!($value_type))]
104 pub fn new() -> Self {
105 Self {
106 freed_storage_keys: Vec::new(),
107 next_storage_key: Default::default(),
108 storage: std::collections::HashMap::new(),
109 $(
110 $unique_name: std::collections::HashMap::new(),
111 )*
112 $(
113 $non_unique_name: std::collections::HashMap::new(),
114 )*
115 $(
116 $unique_ordered_name: std::collections::BTreeMap::new(),
117 )*
118 $(
119 $non_unique_ordered_name: std::collections::BTreeMap::new(),
120 )*
121 }
122 }
123
124 #[doc = "Get a reference to a value in the store based on the storage index."]
125 pub fn get(&self, storage_key: &paste! { [<$map_name StorageIndex>] }) -> Option<&$value_type> {
126 self.storage.get(storage_key)
127 }
128
129 #[doc = concat!("Inserts a `", stringify!($value_type), "` and update all indexes with the new type.")]
130 pub fn insert(&mut self, value: $value_type) -> Result<(), multi_index_container::UniqueContraintViolation<$value_type>> {
131 $(
133 let $unique_param = &value;
134 let unique_key = $unique_expr;
135 if self.$unique_name.contains_key(&unique_key) {
136 return Err(multi_index_container::UniqueContraintViolation { field: stringify!($unique_name), value } );
137 }
138 )*
139 $(
140 let $unique_ordered_param = &value;
141 let unique_key = $unique_ordered_expr;
142 if self.$unique_ordered_name.contains_key(&unique_key) {
143 return Err(multi_index_container::UniqueContraintViolation { field: stringify!($unique_ordered_name), value } );
144 }
145 )*
146
147 let storage_key = self.freed_storage_keys.pop().unwrap_or_else(
148 || {
149 let key = self.next_storage_key;
150 self.next_storage_key = self.next_storage_key.next();
151 key
152 }
153 );
154
155 let storage_key_clone = storage_key;
157 self.storage.insert(storage_key, value);
158
159 let stored_value = self.storage.get(&storage_key_clone).unwrap();
161
162 $(
163 let $unique_param = stored_value;
164 let unique_key = $unique_expr;
165 self.$unique_name.insert(unique_key, storage_key_clone);
166 )*
167
168 $(
169 let $non_unique_param = stored_value;
170 let non_unique_key = $non_unique_expr;
171 self.$non_unique_name
172 .entry(non_unique_key)
173 .or_default()
174 .insert(storage_key_clone);
175 )*
176 $(
177 let $unique_ordered_param = stored_value;
178 let unique_ordered_key = $unique_ordered_expr;
179 self.$unique_ordered_name.insert(unique_ordered_key, storage_key_clone);
180 )*
181 $(
182 let $non_unique_ordered_param = stored_value;
183 let non_unique_ordered_key = $non_unique_ordered_expr;
184 self.$non_unique_ordered_name
185 .entry(non_unique_ordered_key)
186 .or_default()
187 .insert(storage_key_clone);
188 )*
189
190 Ok(())
191 }
192
193 #[doc = concat!("Inserts a `", stringify!($value_type), "` overwriting any existing entries that conflict on unique indexes.")]
194 pub fn insert_or_overwrite(&mut self, value: $value_type) {
195 $(
196 let $unique_param = &value;
197 let unique_key = $unique_expr;
198 if let Some(&conflicting_storage_key) = self.$unique_name.get(&unique_key) {
199 self.remove(&conflicting_storage_key);
200 }
201 )*
202 $(
203 let $unique_ordered_param = &value;
204 let unique_ordered_key = $unique_ordered_expr;
205 if let Some(&conflicting_storage_key) = self.$unique_ordered_name.get(&unique_ordered_key) {
206 self.remove(&conflicting_storage_key);
207 }
208 )*
209
210 let storage_key = self.freed_storage_keys.pop().unwrap_or_else(
211 || {
212 let key = self.next_storage_key;
213 self.next_storage_key = self.next_storage_key.next();
214 key
215 }
216 );
217
218 let storage_key_clone = storage_key;
219 self.storage.insert(storage_key, value);
220
221 let stored_value = self.storage.get(&storage_key_clone).unwrap();
222
223 $(
224 let $unique_param = stored_value;
225 let unique_key = $unique_expr;
226 self.$unique_name.insert(unique_key, storage_key_clone);
227 )*
228
229 $(
230 let $non_unique_param = stored_value;
231 let non_unique_key = $non_unique_expr;
232 self.$non_unique_name
233 .entry(non_unique_key)
234 .or_default()
235 .insert(storage_key_clone);
236 )*
237 $(
238 let $unique_ordered_param = stored_value;
239 let unique_ordered_key = $unique_ordered_expr;
240 self.$unique_ordered_name.insert(unique_ordered_key, storage_key_clone);
241 )*
242 $(
243 let $non_unique_ordered_param = stored_value;
244 let non_unique_ordered_key = $non_unique_ordered_expr;
245 self.$non_unique_ordered_name
246 .entry(non_unique_ordered_key)
247 .or_default()
248 .insert(storage_key_clone);
249 )*
250 }
251
252 $(
253 paste! {
254 #[doc = concat!("Get a single value, if it exist, by indexing by the unique key `", stringify!($unique_name), "` .")]
255 pub fn [<get_by_ $unique_name>](&self, $unique_name: &$unique_key_type) -> Option<&$value_type> {
256 self.$unique_name
257 .get($unique_name)
258 .and_then(|storage_key| self.storage.get(storage_key))
259 }
260
261 #[doc = concat!("Get a mutable modifier for a value, if it exist, by indexing by the unique key `", stringify!($unique_name), "` .")]
262 pub fn [<get_mut_by_ $unique_name>](&mut self, $unique_name: &$unique_key_type) -> Option<[<$map_name MutEntry>]> {
263 let storage_key = self.$unique_name.get($unique_name)?;
264
265 Some([<$map_name MutEntry>] {
266 entry: *storage_key,
267 hashmap: self
268 })
269 }
270 }
271 )*
272
273 $(
274 paste! {
275 #[doc = concat!("Get a single value, if it exist, by indexing by the unique ordered key `", stringify!($unique_ordered_name), "` .")]
276 pub fn [<get_by_ $unique_ordered_name>](&self, $unique_ordered_name: &$unique_ordered_key_type) -> Option<&$value_type> {
277 self.$unique_ordered_name
278 .get($unique_ordered_name)
279 .and_then(|storage_key| self.storage.get(storage_key))
280 }
281
282 #[doc = concat!("Get a mutable modifier for a value, if it exist, by indexing by the unique ordered key `", stringify!($unique_name), "` .")]
283 pub fn [<get_mut_by_ $unique_ordered_name>](&mut self, $unique_ordered_name: &$unique_ordered_key_type) -> Option<[<$map_name MutEntry>]> {
284 let storage_key = self.$unique_ordered_name.get($unique_ordered_name)?;
285 Some([<$map_name MutEntry>] {
286 entry: *storage_key,
287 hashmap: self
288 })
289 }
290
291 $vis fn [<first_by_ $unique_ordered_name>](&self) -> Option<&$value_type> {
292 self.$unique_ordered_name
293 .first_key_value()
294 .and_then(|(_, sk)| self.storage.get(sk))
295 }
296
297 $vis fn [<last_by_ $unique_ordered_name>](&self) -> Option<&$value_type> {
298 self.$unique_ordered_name
299 .last_key_value()
300 .and_then(|(_, sk)| self.storage.get(sk))
301 }
302
303 $vis fn [<get_by_ $unique_ordered_name _range>]<R>(&self, range: R) -> impl Iterator<Item = &$value_type>
304 where
305 R: std::ops::RangeBounds<$unique_ordered_key_type>,
306 {
307 self.$unique_ordered_name
308 .range(range)
309 .filter_map(|(_, sk)| self.storage.get(sk))
310 }
311 }
312 )*
313
314 $(
315 paste! {
316 #[doc = concat!("Get the values by indexing by the non unique key `", stringify!($non_unique_name), "` .")]
317 pub fn [<get_by_ $non_unique_name>]<'a>(&'a self, $non_unique_name: &$non_unique_key_type) -> impl Iterator<Item = &'a $value_type> {
318 self.$non_unique_name
319 .get($non_unique_name)
320 .into_iter()
321 .flat_map(|storage_keys| {
322 storage_keys
323 .iter()
324 .filter_map(|sk| self.storage.get(sk))
325 })
326 }
327
328 #[doc = concat!("Get a mutable modifier for a value, if it exist, by indexing by the non unique key `", stringify!($non_unique_name), "` .")]
329 pub fn [<get_mut_by_ $non_unique_name>](&mut self, $non_unique_name: &$non_unique_key_type) -> [<$map_name MutEntries>] {
330 let storage_keys = match self.$non_unique_name.get($non_unique_name) {
331 Some(s) => s,
332 None => return [<$map_name MutEntries>] {
333 entries: vec![].into_iter(),
334 hashmap: self,
335 },
336 };
337
338 [<$map_name MutEntries>] {
339 entries: storage_keys.clone().into_iter().collect::<Vec<_>>().into_iter(),
340 hashmap: self,
341 }
342 }
343 }
344 )*
345
346 $(
347 paste! {
348 #[doc = concat!("Get the values by indexing by the non unique ordered key `", stringify!($non_unique_ordered_name), "` .")]
349 pub fn [<get_by_ $non_unique_ordered_name>]<'a>(&'a self, $non_unique_ordered_name: &$non_unique_ordered_key_type) -> impl Iterator<Item = &'a $value_type> {
350 self.$non_unique_ordered_name
351 .get($non_unique_ordered_name)
352 .into_iter()
353 .flat_map(|storage_keys| {
354 storage_keys
355 .iter()
356 .filter_map(|sk| self.storage.get(sk))
357 })
358 }
359
360 #[doc = concat!("Get a mutable modifier for a value, if it exist, by indexing by the non unique ordered key `", stringify!($non_unique_ordered_name), "` .")]
361 pub fn [<get_mut_by_ $non_unique_ordered_name>](&mut self, $non_unique_ordered_name: &$non_unique_ordered_key_type) -> [<$map_name MutEntries>] {
362 let storage_keys = match self.$non_unique_ordered_name.get($non_unique_ordered_name) {
363 Some(s) => s,
364 None => return [<$map_name MutEntries>] {
365 entries: vec![].into_iter(),
366 hashmap: self,
367 },
368 };
369
370 [<$map_name MutEntries>] {
371 entries: storage_keys.clone().into_iter().collect::<Vec<_>>().into_iter(),
372 hashmap: self,
373 }
374 }
375
376 $vis fn [<first_by_ $non_unique_ordered_name>](&self) -> impl Iterator<Item = &$value_type> {
377 self.$non_unique_ordered_name
378 .first_key_value()
379 .into_iter()
380 .flat_map(|(_, storage_keys)| {
381 storage_keys
382 .iter()
383 .filter_map(|sk| self.storage.get(sk))
384 })
385 }
386
387 $vis fn [<last_by_ $non_unique_ordered_name>](&self) -> impl Iterator<Item = &$value_type> {
388 self.$non_unique_ordered_name
389 .last_key_value()
390 .into_iter()
391 .flat_map(|(_, storage_keys)| {
392 storage_keys
393 .iter()
394 .filter_map(|sk| self.storage.get(sk))
395 })
396 }
397
398 $vis fn [<get_by_ $non_unique_ordered_name _range>]<R>(&self, range: R) -> impl Iterator<Item = &$value_type>
399 where
400 R: std::ops::RangeBounds<$non_unique_ordered_key_type>,
401 {
402 self.$non_unique_ordered_name
403 .range(range)
404 .flat_map(|(_, storage_keys)| {
405 storage_keys
406 .iter()
407 .filter_map(|sk| self.storage.get(sk))
408 })
409 }
410 }
411 )*
412
413 $crate::__multimap_combined_getters!(@generate_combos
414 $vis $map_name<$value_type>,
415 all_fields: [
416 $(($non_unique_name: $non_unique_key_type))*
417 $(($non_unique_ordered_name: $non_unique_ordered_key_type))*
418 ],
419 selected: [],
420 remaining: [
421 $($non_unique_name: $non_unique_key_type,)*
422 $($non_unique_ordered_name: $non_unique_ordered_key_type,)*
423 ]
424 );
425
426 $crate::__multimap_combined_ordered_getters!(@generate_combos
427 $vis $map_name<$value_type>,
428 eq_fields: [
429 $($non_unique_name: $non_unique_key_type,)*
430 $($non_unique_ordered_name: $non_unique_ordered_key_type,)*
431 ],
432 ordered_fields: [
433 $($non_unique_ordered_name: $non_unique_ordered_key_type,)*
434 ]
435 );
436
437 #[doc = concat!("Remove entry from store by unique key.")]
438 pub fn remove(&mut self, storage_key: &paste! { [<$map_name StorageIndex>] }) -> Option<$value_type> {
439 let value = self.storage.remove(storage_key)?;
440
441 $(
443 let $unique_param = &value;
444 let unique_key = $unique_expr;
445 self.$unique_name.remove(&unique_key);
446 )*
447
448 $(
450 let $non_unique_param = &value;
451 let non_unique_key = $non_unique_expr;
452 if let Some(keys) = self.$non_unique_name.get_mut(&non_unique_key) {
453 keys.retain(|k| k != storage_key);
454 if keys.is_empty() {
455 self.$non_unique_name.remove(&non_unique_key);
456 }
457 }
458 )*
459
460 $(
462 let $unique_ordered_param = &value;
463 let unique_ordered_key = $unique_ordered_expr;
464 self.$unique_ordered_name.remove(&unique_ordered_key);
465 )*
466 $(
468 let $non_unique_ordered_param = &value;
469 let non_unique_ordered_key = $non_unique_ordered_expr;
470 if let Some(keys) = self.$non_unique_ordered_name.get_mut(&non_unique_ordered_key) {
471 keys.remove(storage_key);
472 if keys.is_empty() {
473 self.$non_unique_ordered_name.remove(&non_unique_ordered_key);
474 }
475 }
476 )*
477
478 self.freed_storage_keys.push(*storage_key);
479
480 Some(value)
481 }
482
483 #[doc = "Get the number of values in the store"]
484 #[inline]
485 pub fn len(&self) -> usize {
486 self.storage.len()
487 }
488
489 #[doc = "Check if the map is empty"]
490 #[inline]
491 pub fn is_empty(&self) -> bool {
492 self.storage.is_empty()
493 }
494
495 #[doc = "Extend the map with multiple values, returning a vector of all the unique contraint errors."]
496 pub fn extend<I>(&mut self, iter: I) -> Vec<multi_index_container::UniqueContraintViolation<$value_type>>
497 where
498 I: IntoIterator<Item = $value_type>,
499 {
500 let mut errors = Vec::new();
501 for value in iter {
502 if let Err(e) = self.insert(value) {
503 errors.push(e);
504 }
505 }
506 errors
507 }
508
509 #[doc = "Iterate over all the values in the map."]
510 pub fn values(&self) -> std::collections::hash_map::Values<'_, paste! { [<$map_name StorageIndex>] }, $value_type> {
511 self.storage.values()
512 }
513 }
514
515 impl Default for $map_name {
516
517 #[inline]
518 fn default() -> Self {
519 Self::new()
520 }
521 }
522
523 paste! {
524 #[doc = concat!("An iterator likey type of mutable entry handles into [`", stringify!($map_name), "`], produced by a multi-key lookup.")]
525 #[doc = ""]
526 #[doc = "Holds exclusive mutable access to the map for its lifetime `'map`, ensuring"]
527 #[doc = "no other mutable borrows can exist while entries are being traversed or modified."]
528 #[doc = ""]
529 #[doc = "Obtained from methods that look up multiple keys at once (e.g. `get_many_mut`)."]
530 #[doc = concat!("Each item yielded is a [`", stringify!($map_name), "MutEntry`], which allows in-place mutation or removal of that individual entry.")]
531 #[doc = ""]
532 #[doc = "# Notes"]
533 #[doc = "- Entries are yielded in the same order as the keys passed to the originating lookup."]
534 #[doc = "- Indices that no longer exist in the map at iteration time are silently skipped"]
535 #[doc = " by consuming methods such as `remove_all` and `collect_values`."]
536 #[doc = ""]
537 #[doc = "# Lifetimes"]
538 #[doc = concat!("- `'map` — ties this iterator to the mutable borrow of the underlying [`", stringify!($map_name), "`], preventing any other access to the map until the iterator is dropped.")]
539 $vis struct [<$map_name MutEntries>]<'map> {
540 entries: std::vec::IntoIter<[<$map_name StorageIndex>]>,
541 hashmap: &'map mut $map_name,
542 }
543
544 impl<'map> [<$map_name MutEntries>]<'map> {
545 pub fn filter<F>(self, mut predicate: F) -> Self
549 where
550 F: FnMut(&$value_type) -> bool,
551 {
552 let filtered: Vec<_> = self
553 .entries
554 .filter(|index| {
555 self.hashmap
556 .storage
557 .get(index)
558 .map(|v| predicate(v))
559 .unwrap_or(false)
560 })
561 .collect();
562
563 Self {
564 entries: filtered.into_iter(),
565 hashmap: self.hashmap,
566 }
567 }
568
569 pub fn first(self) -> Option<[<$map_name MutEntry>]<'map>> {
571 let hashmap = self.hashmap;
572 self.entries
573 .into_iter()
574 .next()
575 .map(|entry| [<$map_name MutEntry>] { entry, hashmap })
576 }
577
578 pub fn for_each<F>(self, mut f: F)
580 where
581 F: for<'entry> FnMut([<$map_name MutEntry>]<'entry>),
582 {
583 let hashmap = self.hashmap;
584 for entry in self.entries {
585 f([<$map_name MutEntry>] { entry, hashmap });
586 }
587 }
588
589 pub fn find<F>(self, mut predicate: F) -> Option<[<$map_name MutEntry>]<'map>>
591 where
592 F: FnMut(&$value_type) -> bool,
593 {
594 let hashmap = self.hashmap;
595 let found = self.entries
596 .into_iter()
597 .find(|index| {
598 hashmap
599 .storage
600 .get(index)
601 .map(|v| predicate(v))
602 .unwrap_or(false)
603 });
604
605 found.map(|entry| [<$map_name MutEntry>] { entry, hashmap })
606 }
607
608 pub fn remove_all(self) -> Vec<$value_type> {
613 let hashmap = self.hashmap;
614 self.entries
615 .into_iter()
616 .filter_map(|entry| {
617 hashmap
618 .storage
619 .get(&entry)
620 .is_some()
621 .then(|| [<$map_name MutEntry>] { entry, hashmap }.remove())
622 })
623 .collect()
624 }
625
626 pub fn last(self) -> Option<[<$map_name MutEntry>]<'map>> {
631 let hashmap = self.hashmap;
632 self.entries
633 .into_iter()
634 .last()
635 .map(|entry| [<$map_name MutEntry>] { entry, hashmap })
636 }
637
638 pub fn nth(self, n: usize) -> Option<[<$map_name MutEntry>]<'map>> {
646 let hashmap = self.hashmap;
647 self.entries
648 .into_iter()
649 .nth(n)
650 .map(|entry| [<$map_name MutEntry>] { entry, hashmap })
651 }
652
653 #[inline]
655 pub fn count(self) -> usize {
656 self.entries.len()
657 }
658
659 #[inline]
661 pub fn is_empty(self) -> bool {
662 self.entries.len() == 0
663 }
664
665 #[inline]
667 pub fn is_not_empty(self) -> bool {
668 self.entries.len() != 0
669 }
670 pub fn collect_values(self) -> Vec<&'map $value_type> {
677 let hashmap = self.hashmap;
678 self.entries
679 .into_iter()
680 .filter_map(|index| hashmap.storage.get(&index))
681 .collect()
682 }
683 }
684 }
685
686 paste! {
687 $vis struct [<$map_name MutEntry>] <'map> {
688 entry: [<$map_name StorageIndex>],
689 hashmap: &'map mut $map_name,
690 }
691
692 impl<'map> [<$map_name MutEntry>]<'map> {
693
694 pub fn remove(&mut self) -> $value_type {
696 self.hashmap.remove(&self.entry).expect("Expected the value to exist given it is guaranteed by the mutable pointer to the hashmap while this reference is initialised.")
697 }
698
699 pub fn get(&self) -> &$value_type {
700 self.hashmap.get(&self.entry).expect("Expected the value to exist given it is guaranteed by the mutable pointer to the hashmap while this reference is initialised.")
701 }
702
703 #[doc = concat!("Modify a `", stringify!($value_type), "` such that indexes are kept up to date.")]
704 #[doc = "If a modified value would fail to be inserted, the original value remains in place while the new value gets returned as part of the error. This means it is cloned as part of this function. To avoid this clone you can use the modify_or_remove function"]
705 pub fn modify<F>(&mut self, f: F) -> Result<(), multi_index_container::UniqueContraintViolation<$value_type>>
706 where
707 F: for<'entry> FnOnce(&'entry mut $value_type),
708 {
709 let value = self.remove();
710 let mut modifiable_value = value.clone();
711 f(&mut modifiable_value);
712
713 if let Err(error) = self.hashmap.insert(modifiable_value) {
714 self.hashmap.insert(value).expect("Expected to be able to insert the value we just removed.");
715
716 return Err(error)
717 }
718
719 Ok(())
720 }
721
722 #[doc = concat!("Modify a `", stringify!($value_type), "` such that indexes are kept up to date.")]
723 #[doc = "If a modified value would fail to be inserted, the original value is lost."]
724 pub fn modify_or_remove<F>(&mut self, f: F) -> Result<(), multi_index_container::UniqueContraintViolation<$value_type>>
725 where
726 F: for<'entry> FnOnce(&'entry mut $value_type),
727 {
728 let mut modifiable_value = self.remove();
729 f(&mut modifiable_value);
730
731 self.hashmap.insert(modifiable_value)
732 }
733 }
734 }
735 };
736}