@@ -5,17 +5,18 @@ use crate::{
5
5
use optional:: Optioned ;
6
6
use std:: ops:: Range ;
7
7
8
- pub trait MutObjectSequenceOp < ' a > {
9
- type Guard ;
8
+ pub trait MutObjectSequenceOp < ' a > : Sized {
9
+ type Guard : Sized ;
10
10
11
11
fn do_get ( index : usize , guard : & Self :: Guard ) -> Option < & PyObjectRef > ;
12
12
fn do_lock ( & ' a self ) -> Self :: Guard ;
13
13
14
14
fn mut_count ( & ' a self , vm : & VirtualMachine , needle : & PyObject ) -> PyResult < usize > {
15
+ let mut find_iter = self . _mut_find ( vm, needle, 0 ..isize:: MAX as usize ) ;
15
16
let mut count = 0 ;
16
- self . _mut_iter_equal_skeleton :: < _ , false > ( vm , needle , 0 ..isize :: MAX as usize , || {
17
- count += 1
18
- } ) ? ;
17
+ while ( find_iter . next ( ) . transpose ( ) ? ) . is_some ( ) {
18
+ count += 1 ;
19
+ }
19
20
Ok ( count)
20
21
}
21
22
@@ -24,68 +25,90 @@ pub trait MutObjectSequenceOp<'a> {
24
25
vm : & VirtualMachine ,
25
26
needle : & PyObject ,
26
27
range : Range < usize > ,
27
- ) -> PyResult < Optioned < usize > > {
28
- self . _mut_iter_equal_skeleton :: < _ , true > ( vm, needle, range, || { } )
28
+ ) -> PyResult < Option < usize > > {
29
+ self . _mut_find ( vm, needle, range) . next ( ) . transpose ( )
29
30
}
30
31
31
- fn mut_index ( & ' a self , vm : & VirtualMachine , needle : & PyObject ) -> PyResult < Optioned < usize > > {
32
+ fn mut_index ( & ' a self , vm : & VirtualMachine , needle : & PyObject ) -> PyResult < Option < usize > > {
32
33
self . mut_index_range ( vm, needle, 0 ..isize:: MAX as usize )
33
34
}
34
35
35
36
fn mut_contains ( & ' a self , vm : & VirtualMachine , needle : & PyObject ) -> PyResult < bool > {
36
37
self . mut_index ( vm, needle) . map ( |x| x. is_some ( ) )
37
38
}
38
39
39
- fn _mut_iter_equal_skeleton < F , const SHORT : bool > (
40
+ fn _mut_find < ' b , ' vm > (
40
41
& ' a self ,
41
- vm : & VirtualMachine ,
42
- needle : & PyObject ,
42
+ vm : & ' vm VirtualMachine ,
43
+ needle : & ' b PyObject ,
43
44
range : Range < usize > ,
44
- mut f : F ,
45
- ) -> PyResult < Optioned < usize > >
46
- where
47
- F : FnMut ( ) ,
48
- {
49
- let mut borrower = None ;
50
- let mut i = range. start ;
51
-
52
- let index = loop {
53
- if i >= range. end {
54
- break Optioned :: < usize > :: none ( ) ;
55
- }
56
- let guard = if let Some ( x) = borrower. take ( ) {
57
- x
58
- } else {
59
- self . do_lock ( )
60
- } ;
45
+ ) -> MutObjectSequenceFindIter < ' a , ' b , ' vm , Self > {
46
+ MutObjectSequenceFindIter {
47
+ seq : self ,
48
+ needle,
49
+ pos : range. start ,
50
+ end : range. end ,
51
+ guard : None ,
52
+ vm,
53
+ }
54
+ }
55
+ }
56
+
57
+ pub struct MutObjectSequenceFindIter < ' a , ' b , ' vm , S : MutObjectSequenceOp < ' a > > {
58
+ // mutable fields
59
+ pos : usize ,
60
+ guard : Option < S :: Guard > ,
61
+ // immutable fields
62
+ seq : & ' a S ,
63
+ needle : & ' b PyObject ,
64
+ end : usize ,
65
+ vm : & ' vm VirtualMachine ,
66
+ }
61
67
62
- let elem = if let Some ( x) = Self :: do_get ( i, & guard) {
68
+ impl < ' a , ' b , ' vm , S : MutObjectSequenceOp < ' a > > MutObjectSequenceFindIter < ' a , ' b , ' vm , S > {
69
+ #[ inline]
70
+ fn next_impl ( & mut self ) -> PyResult < Optioned < usize > > {
71
+ loop {
72
+ if self . pos >= self . end {
73
+ return Ok ( Optioned :: none ( ) ) ;
74
+ }
75
+ let guard = self . guard . take ( ) . unwrap_or_else ( || self . seq . do_lock ( ) ) ;
76
+ let elem = if let Some ( x) = S :: do_get ( self . pos , & guard) {
63
77
x
64
78
} else {
65
- break Optioned :: < usize > :: none ( ) ;
79
+ return Ok ( Optioned :: none ( ) ) ;
66
80
} ;
67
81
68
- if elem. is ( needle) {
69
- f ( ) ;
70
- if SHORT {
71
- break Optioned :: < usize > :: some ( i) ;
72
- }
73
- borrower = Some ( guard) ;
82
+ let is_equal = if elem. is ( self . needle ) {
83
+ self . guard = Some ( guard) ;
84
+ true
74
85
} else {
75
86
let elem = elem. clone ( ) ;
76
87
drop ( guard) ;
88
+ elem. rich_compare_bool ( self . needle , PyComparisonOp :: Eq , self . vm ) ?
89
+ } ;
77
90
78
- if elem. rich_compare_bool ( needle, PyComparisonOp :: Eq , vm) ? {
79
- f ( ) ;
80
- if SHORT {
81
- break Optioned :: < usize > :: some ( i) ;
82
- }
83
- }
91
+ if is_equal {
92
+ break ;
84
93
}
85
- i += 1 ;
86
- } ;
87
94
88
- Ok ( index)
95
+ self . pos += 1 ;
96
+ }
97
+
98
+ let i = self . pos ;
99
+ self . pos += 1 ;
100
+ Ok ( Optioned :: some ( i) )
101
+ }
102
+ }
103
+
104
+ impl < ' a , ' b , ' vm , S : MutObjectSequenceOp < ' a > > Iterator
105
+ for MutObjectSequenceFindIter < ' a , ' b , ' vm , S >
106
+ {
107
+ type Item = PyResult < usize > ;
108
+
109
+ #[ inline]
110
+ fn next ( & mut self ) -> Option < Self :: Item > {
111
+ self . next_impl ( ) . map ( Into :: into) . transpose ( )
89
112
}
90
113
}
91
114
0 commit comments