Skip to content

Commit 18fd12f

Browse files
committed
Add rules for overloaded map::erase
1 parent 31bf58f commit 18fd12f

7 files changed

Lines changed: 188 additions & 10 deletions

File tree

‎rules/map/shim.rs‎

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ impl<K: Ord, T> Map<K, T> {
177177
}
178178
}
179179

180+
fn unlink(node: &Value<MapNode<T>>) -> Value<MapNode<T>> {
181+
let prev = MapNode::prev(node);
182+
let next = MapNode::next(node);
183+
prev.borrow_mut().next = Rc::downgrade(&next);
184+
next.borrow_mut().prev = Rc::downgrade(&prev);
185+
next
186+
}
187+
180188
pub fn erase(&mut self, it: &BidirectionalIterator<T>) -> BidirectionalIterator<T>
181189
where
182190
T: MapEntry<K>,
@@ -189,13 +197,20 @@ impl<K: Ord, T> Map<K, T> {
189197
.expect("ub: erase of end iterator")
190198
.borrow()
191199
.key();
192-
let prev = MapNode::prev(node);
193-
let next = MapNode::next(node);
194-
prev.borrow_mut().next = Rc::downgrade(&next);
195-
next.borrow_mut().prev = Rc::downgrade(&prev);
200+
let next = Self::unlink(node);
196201
self.nodes.remove(&key);
197202
BidirectionalIterator::Map(next)
198203
}
204+
205+
pub fn erase_key(&mut self, key: &K) -> usize {
206+
match self.nodes.remove(key) {
207+
Some(node) => {
208+
Self::unlink(&node);
209+
1
210+
}
211+
None => 0,
212+
}
213+
}
199214
}
200215

201216
impl<K: 'static, T: 'static> Map<K, T> {
@@ -369,21 +384,36 @@ impl<K: Ord, T> UnsafeMap<K, T> {
369384
}
370385
}
371386

372-
pub fn erase(&mut self, it: &UnsafeBidirectionalIterator<T>) -> UnsafeBidirectionalIterator<T>
373-
where
374-
T: MapEntry<K>,
375-
{
376-
let UnsafeBidirectionalIterator::Map(node) = *it;
377-
let key = unsafe { (*UnsafeMapNode::value(node)).key() };
387+
fn unlink(node: *mut UnsafeMapNode<T>) -> *mut UnsafeMapNode<T> {
378388
let prev = UnsafeMapNode::prev(node);
379389
let next = UnsafeMapNode::next(node);
380390
unsafe {
381391
(*prev).next = next;
382392
(*next).prev = prev;
383393
}
394+
next
395+
}
396+
397+
pub fn erase(&mut self, it: &UnsafeBidirectionalIterator<T>) -> UnsafeBidirectionalIterator<T>
398+
where
399+
T: MapEntry<K>,
400+
{
401+
let UnsafeBidirectionalIterator::Map(node) = *it;
402+
let key = unsafe { (*UnsafeMapNode::value(node)).key() };
403+
let next = Self::unlink(node);
384404
self.nodes.remove(&key);
385405
UnsafeBidirectionalIterator::Map(next)
386406
}
407+
408+
pub fn erase_key(&mut self, key: &K) -> usize {
409+
match self.nodes.remove(key) {
410+
Some(mut node) => {
411+
Self::unlink(&mut *node);
412+
1
413+
}
414+
None => 0,
415+
}
416+
}
387417
}
388418

389419
pub struct UnsafeMapRange<T> {

‎rules/map/src.cpp‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,15 @@ template <typename T1, typename T2>
8686
std::map<T1, T2> &f26(std::map<T1, T2> &dst, const std::map<T1, T2> &src) {
8787
return dst = src;
8888
}
89+
90+
template <typename T1, typename T2>
91+
typename std::map<T1, T2>::iterator
92+
f27(std::map<T1, T2> &o, typename std::map<T1, T2>::const_iterator it) {
93+
return o.erase(it);
94+
}
95+
96+
template <typename T1, typename T2>
97+
std::size_t f28(std::map<T1, T2> &o,
98+
const typename std::map<T1, T2>::key_type &key) {
99+
return o.erase(key);
100+
}

‎rules/map/tgt_refcount.rs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,14 @@ fn f26<T1: Ord + Clone + 'static, T2: Clone + 'static>(a0: Ptr<Map<T1, (Value<T1
124124
}
125125
a0.write(__m)
126126
}
127+
128+
fn f27<T1: Ord + Clone + 'static, T2: 'static>(
129+
a0: Ptr<Map<T1, (Value<T1>, Value<T2>)>>,
130+
a1: BidirectionalIterator<(Value<T1>, Value<T2>)>,
131+
) -> BidirectionalIterator<(Value<T1>, Value<T2>)> {
132+
a0.with_mut(|__m: &mut Map<T1, (Value<T1>, Value<T2>)>| __m.erase(&a1))
133+
}
134+
135+
fn f28<T1: Ord + 'static, T2: 'static>(a0: Ptr<Map<T1, (Value<T1>, Value<T2>)>>, a1: T1) -> usize {
136+
a0.with_mut(|__m: &mut Map<T1, (Value<T1>, Value<T2>)>| __m.erase_key(&a1))
137+
}

‎rules/map/tgt_unsafe.rs‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,14 @@ unsafe fn f25<T1, T2>(a0: &mut UnsafeMap<T1, (T1, T2)>, a1: &mut UnsafeMap<T1, (
7474
unsafe fn f26<T1: Ord + Clone, T2: Clone>(a0: &mut UnsafeMap<T1, (T1, T2)>, a1: UnsafeMap<T1, (T1, T2)>) {
7575
*a0 = a1.clone()
7676
}
77+
78+
unsafe fn f27<T1: Ord + Clone, T2>(
79+
a0: &mut UnsafeMap<T1, (T1, T2)>,
80+
a1: UnsafeBidirectionalIterator<(T1, T2)>,
81+
) -> UnsafeBidirectionalIterator<(T1, T2)> {
82+
a0.erase(&a1)
83+
}
84+
85+
unsafe fn f28<T1: Ord, T2>(a0: &mut UnsafeMap<T1, (T1, T2)>, a1: T1) -> usize {
86+
a0.erase_key(&a1)
87+
}

‎tests/unit/map.cpp‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ int main() {
5858
r.erase(it4);
5959
assert(r.size() == 3);
6060
assert(m.find(4) == m.end());
61+
m[7] = 7;
62+
m[8] = 8;
63+
m[9] = 9;
64+
assert(r.size() == 6);
65+
assert(m.erase(10) == 0);
66+
int key9 = 9;
67+
assert(m.erase(key9) == 1);
68+
assert(r.size() == 5);
69+
std::map<short, unsigned>::const_iterator cit = m.find(7);
70+
std::map<short, unsigned>::iterator next = m.erase(cit);
71+
assert(next == m.find(8));
72+
next = m.erase(next);
73+
assert(next == m.end());
74+
assert(r.size() == 3);
75+
assert(m.find(8) == m.end());
6176
std::map<std::pair<int, long>, double> other_map;
6277
assert(other_map.size() == 0);
6378
std::pair<int, long> key0(1, 1);

‎tests/unit/out/refcount/map.rs‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,89 @@ fn main_0() -> i32 {
433433
== (m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
434434
.with(|__m: &Map<i16, (Value<i16>, Value<u32>)>| __m.end())
435435
);
436+
(m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
437+
.with_mut(|__m: &mut Map<i16, (Value<i16>, Value<u32>)>| {
438+
__m.get_or_insert_with(7_i16.clone(), || {
439+
(
440+
Rc::new(RefCell::new(7_i16)),
441+
Rc::new(RefCell::new(<u32>::default())),
442+
)
443+
})
444+
.borrow()
445+
.1
446+
.as_pointer()
447+
})
448+
.write(7_u32);
449+
(m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
450+
.with_mut(|__m: &mut Map<i16, (Value<i16>, Value<u32>)>| {
451+
__m.get_or_insert_with(8_i16.clone(), || {
452+
(
453+
Rc::new(RefCell::new(8_i16)),
454+
Rc::new(RefCell::new(<u32>::default())),
455+
)
456+
})
457+
.borrow()
458+
.1
459+
.as_pointer()
460+
})
461+
.write(8_u32);
462+
(m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
463+
.with_mut(|__m: &mut Map<i16, (Value<i16>, Value<u32>)>| {
464+
__m.get_or_insert_with(9_i16.clone(), || {
465+
(
466+
Rc::new(RefCell::new(9_i16)),
467+
Rc::new(RefCell::new(<u32>::default())),
468+
)
469+
})
470+
.borrow()
471+
.1
472+
.as_pointer()
473+
})
474+
.write(9_u32);
475+
assert!(((*r.upgrade().deref()).len() == 6_usize));
476+
assert!(
477+
((m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
478+
.with_mut(|__m: &mut Map<i16, (Value<i16>, Value<u32>)>| __m.erase_key(&10_i16))
479+
== 0_usize)
480+
);
481+
let mut key9: i32 = 9;
482+
assert!(
483+
((m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
484+
.with_mut(|__m: &mut Map<i16, (Value<i16>, Value<u32>)>| __m.erase_key(&(key9 as i16)))
485+
== 1_usize)
486+
);
487+
assert!(((*r.upgrade().deref()).len() == 5_usize));
488+
let cit: Value<BidirectionalIterator<(Value<i16>, Value<u32>)>> = Rc::new(RefCell::new(
489+
<BidirectionalIterator<(Value<i16>, Value<u32>)>>::from(
490+
(m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
491+
.with(|__m: &Map<i16, (Value<i16>, Value<u32>)>| __m.find(&7_i16)),
492+
),
493+
));
494+
let next: Value<BidirectionalIterator<(Value<i16>, Value<u32>)>> = Rc::new(RefCell::new(
495+
(m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>).with_mut(
496+
|__m: &mut Map<i16, (Value<i16>, Value<u32>)>| __m.erase(&(*cit.borrow()).clone()),
497+
),
498+
));
499+
assert!(
500+
(*next.borrow())
501+
== (m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
502+
.with(|__m: &Map<i16, (Value<i16>, Value<u32>)>| __m.find(&8_i16))
503+
);
504+
(*next.borrow_mut()) = (m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>).with_mut(
505+
|__m: &mut Map<i16, (Value<i16>, Value<u32>)>| __m.erase(&(*next.borrow()).clone()),
506+
);
507+
assert!(
508+
(*next.borrow())
509+
== (m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
510+
.with(|__m: &Map<i16, (Value<i16>, Value<u32>)>| __m.end())
511+
);
512+
assert!(((*r.upgrade().deref()).len() == 3_usize));
513+
assert!(
514+
(m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
515+
.with(|__m: &Map<i16, (Value<i16>, Value<u32>)>| __m.find(&8_i16))
516+
== (m.as_pointer() as Ptr<Map<i16, (Value<i16>, Value<u32>)>>)
517+
.with(|__m: &Map<i16, (Value<i16>, Value<u32>)>| __m.end())
518+
);
436519
let other_map: Value<
437520
Map<(Value<i32>, Value<i64>), (Value<(Value<i32>, Value<i64>)>, Value<f64>)>,
438521
> = Rc::new(RefCell::new(Map::new()));

‎tests/unit/out/unsafe/map.rs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,22 @@ unsafe fn main_0() -> i32 {
120120
(*r).erase(&(it4).clone());
121121
assert!((((*r).len()) == (3_usize)));
122122
assert!(m.find(&4_i16) == m.end());
123+
(*&mut (*m.get_or_insert_with(7_i16.clone(), || (7_i16, <u32>::default()))).1) = 7_u32;
124+
(*&mut (*m.get_or_insert_with(8_i16.clone(), || (8_i16, <u32>::default()))).1) = 8_u32;
125+
(*&mut (*m.get_or_insert_with(9_i16.clone(), || (9_i16, <u32>::default()))).1) = 9_u32;
126+
assert!((((*r).len()) == (6_usize)));
127+
assert!(((m.erase_key(&10_i16)) == (0_usize)));
128+
let mut key9: i32 = 9;
129+
assert!(((m.erase_key(&(key9 as i16))) == (1_usize)));
130+
assert!((((*r).len()) == (5_usize)));
131+
let mut cit: UnsafeBidirectionalIterator<(i16, u32)> =
132+
<UnsafeBidirectionalIterator<(i16, u32)>>::from(m.find(&7_i16));
133+
let mut next: UnsafeBidirectionalIterator<(i16, u32)> = m.erase(&(cit).clone());
134+
assert!(next == m.find(&8_i16));
135+
next = m.erase(&(next).clone());
136+
assert!(next == m.end());
137+
assert!((((*r).len()) == (3_usize)));
138+
assert!(m.find(&8_i16) == m.end());
123139
let mut other_map: UnsafeMap<(i32, i64), ((i32, i64), f64)> = UnsafeMap::new();
124140
assert!(((other_map.len()) == (0_usize)));
125141
let mut key0: (i32, i64) = (1.into(), 1.into());

0 commit comments

Comments
 (0)