1
- use std:: cell:: Cell ;
2
1
use std:: char;
3
2
use std:: fmt;
4
3
use std:: mem:: size_of;
5
4
use std:: ops:: Range ;
6
5
use std:: str:: FromStr ;
7
6
use std:: string:: ToString ;
8
7
8
+ use crossbeam_utils:: atomic:: AtomicCell ;
9
9
use num_traits:: ToPrimitive ;
10
10
use unic:: ucd:: category:: GeneralCategory ;
11
11
use unic:: ucd:: ident:: { is_xid_continue, is_xid_start} ;
@@ -45,10 +45,10 @@ use crate::vm::VirtualMachine;
45
45
/// encoding defaults to sys.getdefaultencoding().
46
46
/// errors defaults to 'strict'."
47
47
#[ pyclass( name = "str" ) ]
48
- #[ derive( Clone , Debug ) ]
48
+ #[ derive( Debug ) ]
49
49
pub struct PyString {
50
50
value : String ,
51
- hash : Cell < Option < pyhash:: PyHash > > ,
51
+ hash : AtomicCell < Option < pyhash:: PyHash > > ,
52
52
}
53
53
54
54
impl PyString {
@@ -68,7 +68,7 @@ impl From<String> for PyString {
68
68
fn from ( s : String ) -> PyString {
69
69
PyString {
70
70
value : s,
71
- hash : Cell :: default ( ) ,
71
+ hash : AtomicCell :: default ( ) ,
72
72
}
73
73
}
74
74
}
@@ -97,7 +97,7 @@ impl TryIntoRef<PyString> for &str {
97
97
#[ derive( Debug ) ]
98
98
pub struct PyStringIterator {
99
99
pub string : PyStringRef ,
100
- byte_position : Cell < usize > ,
100
+ byte_position : AtomicCell < usize > ,
101
101
}
102
102
103
103
impl PyValue for PyStringIterator {
@@ -110,14 +110,13 @@ impl PyValue for PyStringIterator {
110
110
impl PyStringIterator {
111
111
#[ pymethod( name = "__next__" ) ]
112
112
fn next ( & self , vm : & VirtualMachine ) -> PyResult {
113
- let pos = self . byte_position . get ( ) ;
113
+ let pos = self . byte_position . load ( ) ;
114
114
115
115
if pos < self . string . value . len ( ) {
116
116
// We can be sure that chars() has a value, because of the pos check above.
117
117
let char_ = self . string . value [ pos..] . chars ( ) . next ( ) . unwrap ( ) ;
118
118
119
- self . byte_position
120
- . set ( self . byte_position . get ( ) + char_. len_utf8 ( ) ) ;
119
+ self . byte_position . store ( pos + char_. len_utf8 ( ) ) ;
121
120
122
121
char_. to_string ( ) . into_pyobject ( vm)
123
122
} else {
@@ -134,7 +133,7 @@ impl PyStringIterator {
134
133
#[ pyclass]
135
134
#[ derive( Debug ) ]
136
135
pub struct PyStringReverseIterator {
137
- pub position : Cell < usize > ,
136
+ pub position : AtomicCell < usize > ,
138
137
pub string : PyStringRef ,
139
138
}
140
139
@@ -148,13 +147,12 @@ impl PyValue for PyStringReverseIterator {
148
147
impl PyStringReverseIterator {
149
148
#[ pymethod( name = "__next__" ) ]
150
149
fn next ( & self , vm : & VirtualMachine ) -> PyResult {
151
- if self . position . get ( ) > 0 {
152
- let position: usize = self . position . get ( ) - 1 ;
150
+ let pos = self . position . load ( ) ;
153
151
154
- # [ allow ( clippy :: range_plus_one ) ]
155
- let value = self . string . value . do_slice ( position..position + 1 ) ;
152
+ if pos > 0 {
153
+ let value = self . string . value . do_slice ( pos - 1 ..pos ) ;
156
154
157
- self . position . set ( position ) ;
155
+ self . position . store ( pos - 1 ) ;
158
156
value. into_pyobject ( vm)
159
157
} else {
160
158
Err ( objiter:: new_stop_iteration ( vm) )
@@ -311,11 +309,11 @@ impl PyString {
311
309
312
310
#[ pymethod( name = "__hash__" ) ]
313
311
fn hash ( & self ) -> pyhash:: PyHash {
314
- match self . hash . get ( ) {
312
+ match self . hash . load ( ) {
315
313
Some ( hash) => hash,
316
314
None => {
317
315
let hash = pyhash:: hash_value ( & self . value ) ;
318
- self . hash . set ( Some ( hash) ) ;
316
+ self . hash . store ( Some ( hash) ) ;
319
317
hash
320
318
}
321
319
}
@@ -1287,20 +1285,20 @@ impl PyString {
1287
1285
encode_string ( zelf, encoding. into_option ( ) , errors. into_option ( ) , vm)
1288
1286
}
1289
1287
1290
- #[ pymethod( name = "__iter__" ) ]
1288
+ #[ pymethod( magic ) ]
1291
1289
fn iter ( zelf : PyRef < Self > ) -> PyStringIterator {
1292
1290
PyStringIterator {
1293
- byte_position : Cell :: new ( 0 ) ,
1291
+ byte_position : AtomicCell :: new ( 0 ) ,
1294
1292
string : zelf,
1295
1293
}
1296
1294
}
1297
1295
1298
- #[ pymethod( name = "__reversed__" ) ]
1296
+ #[ pymethod( magic ) ]
1299
1297
fn reversed ( zelf : PyRef < Self > ) -> PyStringReverseIterator {
1300
1298
let begin = zelf. value . chars ( ) . count ( ) ;
1301
1299
1302
1300
PyStringReverseIterator {
1303
- position : Cell :: new ( begin) ,
1301
+ position : AtomicCell :: new ( begin) ,
1304
1302
string : zelf,
1305
1303
}
1306
1304
}
0 commit comments