@@ -6,10 +6,10 @@ use core::str;
6
6
use core:: fmt:: { self , Formatter , Debug , Display } ;
7
7
use core:: hash:: { Hash , Hasher } ;
8
8
9
- use crate :: { CollectorId , GcSafe , GcRebrand } ;
9
+ use crate :: { CollectorId , internals :: ConstCollectorId , GcSafe , GcRebrand } ;
10
10
use zerogc_derive:: { Trace , unsafe_gc_impl} ;
11
11
12
- use self :: repr:: GcArrayRepr ;
12
+ use self :: repr:: { GcArrayRepr } ;
13
13
14
14
pub mod repr;
15
15
@@ -48,12 +48,12 @@ impl<'gc, Id: CollectorId> GcString<'gc, Id> {
48
48
/// Undefined behavior if the bytes aren't valid
49
49
/// UTF8, just like with [core::str::from_utf8_unchecked]
50
50
#[ inline]
51
- pub unsafe fn from_utf8_unchecked ( bytes : GcArray < ' gc , u8 , Id > ) -> Self {
51
+ pub const unsafe fn from_utf8_unchecked ( bytes : GcArray < ' gc , u8 , Id > ) -> Self {
52
52
GcString { bytes }
53
53
}
54
54
/// Retrieve this string as a raw array of bytes
55
55
#[ inline]
56
- pub fn as_bytes ( & self ) -> GcArray < ' gc , u8 , Id > {
56
+ pub const fn as_bytes ( & self ) -> GcArray < ' gc , u8 , Id > {
57
57
self . bytes
58
58
}
59
59
/// Convert this string into a slice of bytes
@@ -62,6 +62,29 @@ impl<'gc, Id: CollectorId> GcString<'gc, Id> {
62
62
unsafe { str:: from_utf8_unchecked ( self . as_bytes ( ) . as_slice ( ) ) }
63
63
}
64
64
}
65
+ /// Const access to [GcString]
66
+ pub trait ConstStringAccess < ' gc > {
67
+ /// Get this string as a slice of bytes
68
+ fn as_bytes_const ( & self ) -> & ' gc [ u8 ] ;
69
+ /// Convert this string to a `str` slice
70
+ fn as_str_const ( & self ) -> & ' gc str ;
71
+ /// Get the length of this string (in bytes)
72
+ fn len_const ( & self ) -> usize ;
73
+ }
74
+ impl < ' gc , Id : ~const ConstCollectorId > const ConstStringAccess < ' gc > for GcString < ' gc , Id > {
75
+ #[ inline]
76
+ fn as_bytes_const ( & self ) -> & ' gc [ u8 ] {
77
+ self . bytes . as_slice_const ( )
78
+ }
79
+ #[ inline]
80
+ fn as_str_const ( & self ) -> & ' gc str {
81
+ unsafe { str:: from_utf8_unchecked ( self . as_bytes_const ( ) ) }
82
+ }
83
+ #[ inline]
84
+ fn len_const ( & self ) -> usize {
85
+ self . bytes . len_const ( )
86
+ }
87
+ }
65
88
impl < ' gc , Id : CollectorId > Deref for GcString < ' gc , Id > {
66
89
type Target = str ;
67
90
#[ inline]
@@ -92,28 +115,16 @@ impl<'gc, Id: CollectorId> Display for GcString<'gc, Id> {
92
115
pub struct GcArray < ' gc , T : ' gc , Id : CollectorId > {
93
116
repr : Id :: ArrayRepr < ' gc , T >
94
117
}
95
- impl < ' gc , T : GcSafe < ' gc , Id > , Id : CollectorId > GcArray < ' gc , T , Id > {
96
- /// Create an array from the specified raw pointer and length
97
- ///
98
- /// ## Safety
99
- /// Pointer and length must be valid, and point to a garbage collected
100
- /// value allocated from the corresponding [CollectorId]
101
- #[ inline]
102
- pub unsafe fn from_raw_ptr ( ptr : NonNull < T > , len : usize ) -> Self {
103
- GcArray { repr : Id :: ArrayRepr :: < ' gc , T > :: from_raw_parts ( ptr, len) }
104
- }
105
- }
106
- // Relax T: GcSafe bound
107
118
impl < ' gc , T , Id : CollectorId > GcArray < ' gc , T , Id > {
108
- /// The value of the array as a slice
119
+ /// Convert this array into a slice
109
120
#[ inline]
110
- pub fn as_slice ( self ) -> & ' gc [ T ] {
121
+ pub fn as_slice ( & self ) -> & ' gc [ T ] {
111
122
self . repr . as_slice ( )
112
123
}
113
124
/// Load a raw pointer to the array's value
114
125
#[ inline]
115
- pub fn as_raw_ptr ( self ) -> * mut T {
116
- self . repr . as_raw_ptr ( )
126
+ pub fn as_raw_ptr ( & self ) -> * mut T {
127
+ self . as_slice ( ) . as_ptr ( ) as * mut T
117
128
}
118
129
/// Load the length of the array
119
130
#[ inline]
@@ -123,7 +134,7 @@ impl<'gc, T, Id: CollectorId> GcArray<'gc, T, Id> {
123
134
/// Check if the array is empty
124
135
#[ inline]
125
136
pub fn is_empty ( & self ) -> bool {
126
- self . repr . is_empty ( )
137
+ self . len ( ) == 0
127
138
}
128
139
/// Resolve the [CollectorId]
129
140
#[ inline]
@@ -135,6 +146,68 @@ impl<'gc, T, Id: CollectorId> GcArray<'gc, T, Id> {
135
146
pub fn as_raw_repr ( & self ) -> & Id :: ArrayRepr < ' gc , T > {
136
147
& self . repr
137
148
}
149
+ /// Create an array from the specified raw pointer and length
150
+ ///
151
+ /// ## Safety
152
+ /// Pointer and length must be valid, and point to a garbage collected
153
+ /// value allocated from the corresponding [CollectorId]
154
+ #[ inline]
155
+ pub unsafe fn from_raw_ptr ( ptr : NonNull < T > , len : usize ) -> Self {
156
+ GcArray { repr : Id :: ArrayRepr :: < ' gc , T > :: from_raw_parts ( ptr, len) }
157
+ }
158
+ }
159
+ /// Const access to [GcString]
160
+ pub trait ConstArrayAccess < ' gc , T > {
161
+ /// The value of the array as a slice
162
+ fn as_slice_const ( & self ) -> & ' gc [ T ] ;
163
+ /// Load a raw pointer to the array's value
164
+ fn as_raw_ptr_const ( & self ) -> * mut T ;
165
+ /// The length of this array
166
+ fn len_const ( & self ) -> usize ;
167
+ }
168
+ // Relax T: GcSafe bound
169
+ impl < ' gc , T , Id : ~const ConstCollectorId > const ConstArrayAccess < ' gc , T > for GcArray < ' gc , T , Id > {
170
+ #[ inline]
171
+ fn as_slice_const ( & self ) -> & ' gc [ T ] {
172
+ /*
173
+ * TODO: This is horrible, but currently nessicarry
174
+ * to do this in a const-fn context.
175
+ */
176
+ match Id :: ArrayRepr :: < ' gc , T > :: UNCHECKED_KIND {
177
+ repr:: ArrayReprKind :: Fat => {
178
+ unsafe {
179
+ core:: mem:: transmute_copy :: <
180
+ Id :: ArrayRepr < ' gc , T > ,
181
+ & ' gc [ T ]
182
+ > ( & self . repr )
183
+ }
184
+ } ,
185
+ repr:: ArrayReprKind :: Thin => {
186
+ unsafe {
187
+ let ptr = core:: mem:: transmute_copy :: <
188
+ Id :: ArrayRepr < ' gc , T > ,
189
+ NonNull < T >
190
+ > ( & self . repr ) ;
191
+ & * core:: ptr:: slice_from_raw_parts (
192
+ ptr. as_ptr ( ) ,
193
+ Id :: resolve_array_len_const (
194
+ & self . repr
195
+ )
196
+ )
197
+ }
198
+ } ,
199
+ }
200
+ }
201
+ /// Load a raw pointer to the array's value
202
+ #[ inline]
203
+ fn as_raw_ptr_const ( & self ) -> * mut T {
204
+ self . as_slice_const ( ) . as_ptr ( ) as * mut T
205
+ }
206
+ /// Load the length of the array
207
+ #[ inline]
208
+ fn len_const ( & self ) -> usize {
209
+ self . as_slice_const ( ) . len ( )
210
+ }
138
211
}
139
212
impl < ' gc , T , Id : CollectorId > Deref for GcArray < ' gc , T , Id > {
140
213
type Target = [ T ] ;
@@ -192,7 +265,7 @@ impl<'gc, T: Hash, Id: CollectorId> Hash for GcArray<'gc, T, Id> {
192
265
fn hash < H : Hasher > ( & self , hasher : & mut H ) {
193
266
T :: hash_slice ( self . as_slice ( ) , hasher)
194
267
}
195
- }
268
+ }
196
269
// Need to implement by hand, because [T] is not GcRebrand
197
270
unsafe_gc_impl ! (
198
271
target => GcArray <' gc, T , Id >,
0 commit comments