Skip to content
This repository was archived by the owner on Jun 8, 2021. It is now read-only.

Commit c5e2632

Browse files
authored
Merge pull request #496 from sdroege/clear-boxed
Add init/clear function for boxed types
2 parents b52d708 + 7c647aa commit c5e2632

File tree

3 files changed

+169
-68
lines changed

3 files changed

+169
-68
lines changed

src/boxed.rs

Lines changed: 135 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -17,69 +17,38 @@ use translate::*;
1717
#[macro_export]
1818
macro_rules! glib_boxed_wrapper {
1919
([$($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,
2121
@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+
};
4527

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);
5233
};
5334

5435
([$($attr:meta)*] $name:ident, $ffi_name:path, @copy $copy_arg:ident $copy_expr:expr,
5536
@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) => {
5649
$(#[$attr])*
5750
#[derive(Clone)]
5851
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-
8352
#[doc(hidden)]
8453
impl $crate::translate::GlibPtrDefault for $name {
8554
type GlibType = *mut $ffi_name;
@@ -261,7 +230,100 @@ macro_rules! glib_boxed_wrapper {
261230
$crate::translate::FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, $crate::translate::c_ptr_array_len(ptr))
262231
}
263232
}
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+
};
265327
}
266328

267329
enum AnyBox<T> {
@@ -287,6 +349,10 @@ pub trait BoxedMemoryManager<T>: 'static {
287349
unsafe fn copy(ptr: *const T) -> *mut T;
288350
/// Frees the object.
289351
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);
290356
}
291357

292358
/// Encapsulates memory management logic for boxed types.
@@ -295,21 +361,16 @@ pub struct Boxed<T: 'static, MM: BoxedMemoryManager<T>> {
295361
_dummy: PhantomData<MM>,
296362
}
297363

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-
308364
impl<T: 'static, MM: BoxedMemoryManager<T>> Uninitialized for Boxed<T, MM> {
309365
#[inline]
310366
unsafe fn uninitialized() -> Self {
311367
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+
},
313374
_dummy: PhantomData,
314375
}
315376
}
@@ -397,8 +458,14 @@ impl<T: 'static, MM: BoxedMemoryManager<T>> Drop for Boxed<T, MM> {
397458
#[inline]
398459
fn drop(&mut self) {
399460
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+
_ => (),
402469
}
403470
}
404471
}

src/date.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ glib_wrapper! {
2121
match fn {
2222
copy => |ptr| gobject_sys::g_boxed_copy(glib_sys::g_date_get_type(), ptr as *const _) as *mut _,
2323
free => |ptr| glib_sys::g_date_free(ptr),
24+
init => |_ptr| (),
25+
clear => |ptr| glib_sys::g_date_clear(ptr, 1),
2426
get_type => || glib_sys::g_date_get_type(),
2527
}
2628
}

src/wrapper.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,38 @@ macro_rules! glib_wrapper {
265265
@free $free_arg $free_expr, @get_type $get_type_expr);
266266
};
267267

268+
(
269+
$(#[$attr:meta])*
270+
pub struct $name:ident(Boxed<$ffi_name:path>);
271+
272+
match fn {
273+
copy => |$copy_arg:ident| $copy_expr:expr,
274+
free => |$free_arg:ident| $free_expr:expr,
275+
init => |$init_arg:ident| $init_expr:expr,
276+
clear => |$clear_arg:ident| $clear_expr:expr,
277+
}
278+
) => {
279+
glib_boxed_wrapper!([$($attr)*] $name, $ffi_name, @copy $copy_arg $copy_expr,
280+
@free $free_arg $free_expr, @init $init_arg $init_expr, @clear $clear_arg $clear_expr);
281+
};
282+
283+
(
284+
$(#[$attr:meta])*
285+
pub struct $name:ident(Boxed<$ffi_name:path>);
286+
287+
match fn {
288+
copy => |$copy_arg:ident| $copy_expr:expr,
289+
free => |$free_arg:ident| $free_expr:expr,
290+
init => |$init_arg:ident| $init_expr:expr,
291+
clear => |$clear_arg:ident| $clear_expr:expr,
292+
get_type => || $get_type_expr:expr,
293+
}
294+
) => {
295+
glib_boxed_wrapper!([$($attr)*] $name, $ffi_name, @copy $copy_arg $copy_expr,
296+
@free $free_arg $free_expr, @init $init_arg $init_expr, @clear $clear_arg $clear_expr,
297+
@get_type $get_type_expr);
298+
};
299+
268300
// Shared
269301

270302
(

0 commit comments

Comments
 (0)