1
1
use std:: cell:: Cell ;
2
- use std:: ops:: Mul ;
3
2
4
3
use num_bigint:: { BigInt , Sign } ;
5
4
use num_integer:: Integer ;
@@ -14,7 +13,7 @@ use crate::vm::VirtualMachine;
14
13
use super :: objint:: { PyInt , PyIntRef } ;
15
14
use super :: objiter;
16
15
use super :: objslice:: { PySlice , PySliceRef } ;
17
- use super :: objtype:: PyClassRef ;
16
+ use super :: objtype:: { self , PyClassRef } ;
18
17
19
18
#[ derive( Debug , Clone ) ]
20
19
pub struct PyRange {
@@ -65,15 +64,22 @@ impl PyRange {
65
64
}
66
65
67
66
#[ inline]
68
- pub fn get < ' a , T > ( & ' a self , index : T ) -> Option < BigInt >
69
- where
70
- & ' a BigInt : Mul < T , Output = BigInt > ,
71
- {
67
+ pub fn get ( & self , index : & BigInt ) -> Option < BigInt > {
72
68
let start = self . start . as_bigint ( ) ;
73
69
let stop = self . stop . as_bigint ( ) ;
74
70
let step = self . step . as_bigint ( ) ;
75
71
76
- let result = start + step * index;
72
+ let index = if index < & BigInt :: zero ( ) {
73
+ let index = stop + index;
74
+ if index < BigInt :: zero ( ) {
75
+ return None ;
76
+ }
77
+ index
78
+ } else {
79
+ index. clone ( )
80
+ } ;
81
+
82
+ let result = start + step * & index;
77
83
78
84
if ( self . forward ( ) && !self . is_empty ( ) && & result < stop)
79
85
|| ( !self . forward ( ) && !self . is_empty ( ) && & result > stop)
@@ -104,6 +110,7 @@ pub fn init(context: &PyContext) {
104
110
"__bool__" => context. new_rustfunc( PyRange :: bool ) ,
105
111
"__contains__" => context. new_rustfunc( PyRange :: contains) ,
106
112
"__doc__" => context. new_str( range_doc. to_string( ) ) ,
113
+ "__eq__" => context. new_rustfunc( PyRange :: eq) ,
107
114
"__getitem__" => context. new_rustfunc( PyRange :: getitem) ,
108
115
"__iter__" => context. new_rustfunc( PyRange :: iter) ,
109
116
"__len__" => context. new_rustfunc( PyRange :: len) ,
@@ -240,6 +247,17 @@ impl PyRange {
240
247
}
241
248
}
242
249
250
+ fn eq ( & self , rhs : PyObjectRef , vm : & VirtualMachine ) -> bool {
251
+ if objtype:: isinstance ( & rhs, & vm. ctx . range_type ( ) ) {
252
+ let rhs = get_value ( & rhs) ;
253
+ self . start . as_bigint ( ) == rhs. start . as_bigint ( )
254
+ && self . stop . as_bigint ( ) == rhs. stop . as_bigint ( )
255
+ && self . step . as_bigint ( ) == rhs. step . as_bigint ( )
256
+ } else {
257
+ false
258
+ }
259
+ }
260
+
243
261
fn index ( & self , needle : PyObjectRef , vm : & VirtualMachine ) -> PyResult < PyInt > {
244
262
if let Ok ( int) = needle. downcast :: < PyInt > ( ) {
245
263
match self . index_of ( int. as_bigint ( ) ) {
@@ -274,7 +292,7 @@ impl PyRange {
274
292
}
275
293
RangeIndex :: Slice ( slice) => {
276
294
let new_start = if let Some ( int) = slice. start_index ( vm) ? {
277
- if let Some ( i) = self . get ( int) {
295
+ if let Some ( i) = self . get ( & int) {
278
296
PyInt :: new ( i) . into_ref ( vm)
279
297
} else {
280
298
self . start . clone ( )
@@ -284,7 +302,7 @@ impl PyRange {
284
302
} ;
285
303
286
304
let new_end = if let Some ( int) = slice. stop_index ( vm) ? {
287
- if let Some ( i) = self . get ( int) {
305
+ if let Some ( i) = self . get ( & int) {
288
306
PyInt :: new ( i) . into_ref ( vm)
289
307
} else {
290
308
self . stop . clone ( )
@@ -339,7 +357,8 @@ type PyRangeIteratorRef = PyRef<PyRangeIterator>;
339
357
340
358
impl PyRangeIteratorRef {
341
359
fn next ( self , vm : & VirtualMachine ) -> PyResult < BigInt > {
342
- if let Some ( int) = self . range . get ( self . position . get ( ) ) {
360
+ let position = BigInt :: from ( self . position . get ( ) ) ;
361
+ if let Some ( int) = self . range . get ( & position) {
343
362
self . position . set ( self . position . get ( ) + 1 ) ;
344
363
Ok ( int)
345
364
} else {
0 commit comments