@@ -17,69 +17,38 @@ use translate::*;
17
17
#[ macro_export]
18
18
macro_rules! glib_boxed_wrapper {
19
19
( [ $( $attr: meta) * ] $name: ident, $ffi_name: path, @copy $copy_arg: ident $copy_expr: expr,
20
- @free $free_arg: ident $free_expr: expr,
20
+ @free $free_arg: ident $free_expr: expr, @init $init_arg : ident $init_expr : expr , @clear $clear_arg : ident $clear_expr : expr ,
21
21
@get_type $get_type_expr: expr) => {
22
- glib_boxed_wrapper!( [ $( $attr) * ] $name, $ffi_name, @copy $copy_arg $copy_expr,
23
- @free $free_arg $free_expr) ;
24
-
25
- impl $crate:: types:: StaticType for $name {
26
- fn static_type( ) -> $crate:: types:: Type {
27
- #[ allow( unused_unsafe) ]
28
- unsafe { $crate:: translate:: from_glib( $get_type_expr) }
29
- }
30
- }
31
-
32
- #[ doc( hidden) ]
33
- impl <' a> $crate:: value:: FromValueOptional <' a> for $name {
34
- unsafe fn from_value_optional( value: & $crate:: Value ) -> Option <Self > {
35
- $crate:: translate:: from_glib_full( $crate:: gobject_sys:: g_value_dup_boxed( $crate:: translate:: ToGlibPtr :: to_glib_none( value) . 0 ) as * mut $ffi_name)
36
- }
37
- }
38
-
39
- #[ doc( hidden) ]
40
- impl $crate:: value:: SetValue for $name {
41
- unsafe fn set_value( value: & mut $crate:: Value , this: & Self ) {
42
- $crate:: gobject_sys:: g_value_set_boxed( $crate:: translate:: ToGlibPtrMut :: to_glib_none_mut( value) . 0 , $crate:: translate:: ToGlibPtr :: <* const $ffi_name>:: to_glib_none( this) . 0 as $crate:: glib_sys:: gpointer)
43
- }
44
- }
22
+ glib_boxed_wrapper!( @generic_impl [ $( $attr) * ] $name, $ffi_name) ;
23
+ glib_boxed_wrapper!( @memory_manager_impl $name, $ffi_name, @copy $copy_arg $copy_expr, @free $free_arg $free_expr,
24
+ @init $init_arg $init_expr, @clear $clear_arg $clear_expr) ;
25
+ glib_boxed_wrapper!( @value_impl $name, $ffi_name, @get_type $get_type_expr) ;
26
+ } ;
45
27
46
- #[ doc( hidden) ]
47
- impl $crate:: value:: SetValueOptional for $name {
48
- unsafe fn set_value_optional( value: & mut $crate:: Value , this: Option <& Self >) {
49
- $crate:: gobject_sys:: g_value_set_boxed( $crate:: translate:: ToGlibPtrMut :: to_glib_none_mut( value) . 0 , $crate:: translate:: ToGlibPtr :: <* const $ffi_name>:: to_glib_none( & this) . 0 as $crate:: glib_sys:: gpointer)
50
- }
51
- }
28
+ ( [ $( $attr: meta) * ] $name: ident, $ffi_name: path, @copy $copy_arg: ident $copy_expr: expr,
29
+ @free $free_arg: ident $free_expr: expr, @init $init_arg: ident $init_expr: expr, @clear $clear_arg: ident $clear_expr: expr) => {
30
+ glib_boxed_wrapper!( @generic_impl [ $( $attr) * ] $name, $ffi_name) ;
31
+ glib_boxed_wrapper!( @memory_manager_impl $name, $ffi_name, @copy $copy_arg $copy_expr, @free $free_arg $free_expr,
32
+ @init $init_arg $init_expr, @clear $clear_arg $clear_expr) ;
52
33
} ;
53
34
54
35
( [ $( $attr: meta) * ] $name: ident, $ffi_name: path, @copy $copy_arg: ident $copy_expr: expr,
55
36
@free $free_arg: ident $free_expr: expr) => {
37
+ glib_boxed_wrapper!( @generic_impl [ $( $attr) * ] $name, $ffi_name) ;
38
+ glib_boxed_wrapper!( @memory_manager_impl $name, $ffi_name, @copy $copy_arg $copy_expr, @free $free_arg $free_expr) ;
39
+ } ;
40
+
41
+ ( [ $( $attr: meta) * ] $name: ident, $ffi_name: path, @copy $copy_arg: ident $copy_expr: expr,
42
+ @free $free_arg: ident $free_expr: expr, @get_type $get_type_expr: expr) => {
43
+ glib_boxed_wrapper!( @generic_impl [ $( $attr) * ] $name, $ffi_name) ;
44
+ glib_boxed_wrapper!( @memory_manager_impl $name, $ffi_name, @copy $copy_arg $copy_expr, @free $free_arg $free_expr) ;
45
+ glib_boxed_wrapper!( @value_impl $name, $ffi_name, @get_type $get_type_expr) ;
46
+ } ;
47
+
48
+ ( @generic_impl [ $( $attr: meta) * ] $name: ident, $ffi_name: path) => {
56
49
$( #[ $attr] ) *
57
50
#[ derive( Clone ) ]
58
51
pub struct $name( $crate:: boxed:: Boxed <$ffi_name, MemoryManager >) ;
59
-
60
- #[ doc( hidden) ]
61
- pub struct MemoryManager ;
62
-
63
- impl $crate:: boxed:: BoxedMemoryManager <$ffi_name> for MemoryManager {
64
- #[ inline]
65
- unsafe fn copy( $copy_arg: * const $ffi_name) -> * mut $ffi_name {
66
- $copy_expr
67
- }
68
-
69
- #[ inline]
70
- unsafe fn free( $free_arg: * mut $ffi_name) {
71
- $free_expr
72
- }
73
- }
74
-
75
- #[ doc( hidden) ]
76
- impl $crate:: translate:: Uninitialized for $name {
77
- #[ inline]
78
- unsafe fn uninitialized( ) -> Self {
79
- $name( $crate:: boxed:: Boxed :: uninitialized( ) )
80
- }
81
- }
82
-
83
52
#[ doc( hidden) ]
84
53
impl $crate:: translate:: GlibPtrDefault for $name {
85
54
type GlibType = * mut $ffi_name;
@@ -261,7 +230,100 @@ macro_rules! glib_boxed_wrapper {
261
230
$crate:: translate:: FromGlibContainerAsVec :: from_glib_full_num_as_vec( ptr, $crate:: translate:: c_ptr_array_len( ptr) )
262
231
}
263
232
}
264
- }
233
+ } ;
234
+
235
+ ( @value_impl $name: ident, $ffi_name: path, @get_type $get_type_expr: expr) => {
236
+ impl $crate:: types:: StaticType for $name {
237
+ fn static_type( ) -> $crate:: types:: Type {
238
+ #[ allow( unused_unsafe) ]
239
+ unsafe { $crate:: translate:: from_glib( $get_type_expr) }
240
+ }
241
+ }
242
+
243
+ #[ doc( hidden) ]
244
+ impl <' a> $crate:: value:: FromValueOptional <' a> for $name {
245
+ unsafe fn from_value_optional( value: & $crate:: Value ) -> Option <Self > {
246
+ $crate:: translate:: from_glib_full( $crate:: gobject_sys:: g_value_dup_boxed( $crate:: translate:: ToGlibPtr :: to_glib_none( value) . 0 ) as * mut $ffi_name)
247
+ }
248
+ }
249
+
250
+ #[ doc( hidden) ]
251
+ impl $crate:: value:: SetValue for $name {
252
+ unsafe fn set_value( value: & mut $crate:: Value , this: & Self ) {
253
+ $crate:: gobject_sys:: g_value_set_boxed( $crate:: translate:: ToGlibPtrMut :: to_glib_none_mut( value) . 0 , $crate:: translate:: ToGlibPtr :: <* const $ffi_name>:: to_glib_none( this) . 0 as $crate:: glib_sys:: gpointer)
254
+ }
255
+ }
256
+
257
+ #[ doc( hidden) ]
258
+ impl $crate:: value:: SetValueOptional for $name {
259
+ unsafe fn set_value_optional( value: & mut $crate:: Value , this: Option <& Self >) {
260
+ $crate:: gobject_sys:: g_value_set_boxed( $crate:: translate:: ToGlibPtrMut :: to_glib_none_mut( value) . 0 , $crate:: translate:: ToGlibPtr :: <* const $ffi_name>:: to_glib_none( & this) . 0 as $crate:: glib_sys:: gpointer)
261
+ }
262
+ }
263
+ } ;
264
+
265
+ ( @memory_manager_impl $name: ident, $ffi_name: path, @copy $copy_arg: ident $copy_expr: expr, @free $free_arg: ident $free_expr: expr) => {
266
+ #[ doc( hidden) ]
267
+ pub struct MemoryManager ;
268
+
269
+ impl $crate:: boxed:: BoxedMemoryManager <$ffi_name> for MemoryManager {
270
+ #[ inline]
271
+ unsafe fn copy( $copy_arg: * const $ffi_name) -> * mut $ffi_name {
272
+ $copy_expr
273
+ }
274
+
275
+ #[ inline]
276
+ unsafe fn free( $free_arg: * mut $ffi_name) {
277
+ $free_expr
278
+ }
279
+
280
+ #[ inline]
281
+ unsafe fn init( _: * mut $ffi_name) {
282
+ unimplemented!( )
283
+ }
284
+
285
+ #[ inline]
286
+ unsafe fn clear( _: * mut $ffi_name) {
287
+ unimplemented!( )
288
+ }
289
+ }
290
+ } ;
291
+
292
+ ( @memory_manager_impl $name: ident, $ffi_name: path, @copy $copy_arg: ident $copy_expr: expr, @free $free_arg: ident $free_expr: expr,
293
+ @init $init_arg: ident $init_expr: expr, @clear $clear_arg: ident $clear_expr: expr) => {
294
+ #[ doc( hidden) ]
295
+ pub struct MemoryManager ;
296
+
297
+ impl $crate:: boxed:: BoxedMemoryManager <$ffi_name> for MemoryManager {
298
+ #[ inline]
299
+ unsafe fn copy( $copy_arg: * const $ffi_name) -> * mut $ffi_name {
300
+ $copy_expr
301
+ }
302
+
303
+ #[ inline]
304
+ unsafe fn free( $free_arg: * mut $ffi_name) {
305
+ $free_expr
306
+ }
307
+
308
+ #[ inline]
309
+ unsafe fn init( $init_arg: * mut $ffi_name) {
310
+ $init_expr
311
+ }
312
+
313
+ #[ inline]
314
+ unsafe fn clear( $clear_arg: * mut $ffi_name) {
315
+ $clear_expr
316
+ }
317
+ }
318
+
319
+ #[ doc( hidden) ]
320
+ impl $crate:: translate:: Uninitialized for $name {
321
+ #[ inline]
322
+ unsafe fn uninitialized( ) -> Self {
323
+ $name( $crate:: boxed:: Boxed :: uninitialized( ) )
324
+ }
325
+ }
326
+ } ;
265
327
}
266
328
267
329
enum AnyBox < T > {
@@ -287,6 +349,10 @@ pub trait BoxedMemoryManager<T>: 'static {
287
349
unsafe fn copy ( ptr : * const T ) -> * mut T ;
288
350
/// Frees the object.
289
351
unsafe fn free ( ptr : * mut T ) ;
352
+ /// Initializes an already allocated object.
353
+ unsafe fn init ( ptr : * mut T ) ;
354
+ /// Clears and frees all memory of the object, but not the object itself.
355
+ unsafe fn clear ( ptr : * mut T ) ;
290
356
}
291
357
292
358
/// Encapsulates memory management logic for boxed types.
@@ -295,21 +361,16 @@ pub struct Boxed<T: 'static, MM: BoxedMemoryManager<T>> {
295
361
_dummy : PhantomData < MM > ,
296
362
}
297
363
298
- impl < T : ' static , MM : BoxedMemoryManager < T > > Boxed < T , MM > {
299
- #[ inline]
300
- pub unsafe fn uninitialized ( ) -> Self {
301
- Boxed {
302
- inner : AnyBox :: Native ( Box :: new ( mem:: uninitialized ( ) ) ) ,
303
- _dummy : PhantomData ,
304
- }
305
- }
306
- }
307
-
308
364
impl < T : ' static , MM : BoxedMemoryManager < T > > Uninitialized for Boxed < T , MM > {
309
365
#[ inline]
310
366
unsafe fn uninitialized ( ) -> Self {
311
367
Boxed {
312
- inner : AnyBox :: Native ( Box :: new ( mem:: uninitialized ( ) ) ) ,
368
+ inner : {
369
+ let mut inner = Box :: < T > :: new ( mem:: zeroed ( ) ) ;
370
+ MM :: init ( & mut * inner) ;
371
+
372
+ AnyBox :: Native ( inner)
373
+ } ,
313
374
_dummy : PhantomData ,
314
375
}
315
376
}
@@ -397,8 +458,14 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> Drop for Boxed<T, MM> {
397
458
#[ inline]
398
459
fn drop ( & mut self ) {
399
460
unsafe {
400
- if let AnyBox :: ForeignOwned ( ptr) = self . inner {
401
- MM :: free ( ptr. as_ptr ( ) ) ;
461
+ match self . inner {
462
+ AnyBox :: ForeignOwned ( ptr) => {
463
+ MM :: free ( ptr. as_ptr ( ) ) ;
464
+ }
465
+ AnyBox :: Native ( ref mut box_) => {
466
+ MM :: clear ( & mut * * box_) ;
467
+ }
468
+ _ => ( ) ,
402
469
}
403
470
}
404
471
}
0 commit comments