Skip to content

Commit 21c5579

Browse files
authored
Merge pull request #875 from sdroege/collections
Improve `glib::collections` API and make it more versatile
2 parents ab7525f + 28913c8 commit 21c5579

19 files changed

+5793
-1692
lines changed

glib/src/boxed.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,19 @@ macro_rules! glib_boxed_wrapper {
4141
#[doc = "Return the inner pointer to the underlying C value."]
4242
#[inline]
4343
pub fn as_ptr(&self) -> *mut $ffi_name {
44-
$crate::translate::ToGlibPtr::to_glib_none(&self.inner).0 as *mut _
44+
unsafe { *(self as *const Self as *const *const $ffi_name) as *mut $ffi_name }
45+
}
46+
47+
#[doc = "Borrows the underlying C value."]
48+
#[inline]
49+
pub unsafe fn from_glib_ptr_borrow<'a>(ptr: *const *const $ffi_name) -> &'a Self {
50+
&*(ptr as *const Self)
51+
}
52+
53+
#[doc = "Borrows the underlying C value mutably."]
54+
#[inline]
55+
pub unsafe fn from_glib_ptr_borrow_mut<'a>(ptr: *mut *mut $ffi_name) -> &'a mut Self {
56+
&mut *(ptr as *mut Self)
4557
}
4658
}
4759

@@ -59,6 +71,9 @@ macro_rules! glib_boxed_wrapper {
5971
type GlibType = *mut $ffi_name;
6072
}
6173

74+
#[doc(hidden)]
75+
unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::TransparentPtrType for $name $(<$($generic),+>)? {}
76+
6277
#[doc(hidden)]
6378
impl<'a $(, $($generic $(: $bound $(+ $bound2)*)?),+)?> $crate::translate::ToGlibPtr<'a, *const $ffi_name> for $name $(<$($generic),+>)? {
6479
type Storage = std::marker::PhantomData<&'a $crate::boxed::Boxed<$ffi_name, Self>>;
@@ -92,19 +107,22 @@ macro_rules! glib_boxed_wrapper {
92107

93108
fn to_glib_none_from_slice(t: &'a [Self]) -> (*mut *const $ffi_name, Self::Storage) {
94109
let mut v_ptr = Vec::with_capacity(t.len() + 1);
95-
v_ptr.extend(t.iter().map(|t| t.as_ptr() as *const $ffi_name));
96-
v_ptr.push(std::ptr::null());
110+
unsafe {
111+
let ptr = v_ptr.as_mut_ptr();
112+
std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *const $ffi_name, ptr, t.len());
113+
std::ptr::write(ptr.add(t.len()), std::ptr::null_mut());
114+
v_ptr.set_len(t.len() + 1);
115+
}
97116

98117
(v_ptr.as_ptr() as *mut *const $ffi_name, (std::marker::PhantomData, Some(v_ptr)))
99118
}
100119

101120
fn to_glib_container_from_slice(t: &'a [Self]) -> (*mut *const $ffi_name, Self::Storage) {
102121
let v_ptr = unsafe {
103-
let v_ptr = $crate::ffi::g_malloc0(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
122+
let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
104123

105-
for (i, t) in t.iter().enumerate() {
106-
std::ptr::write(v_ptr.add(i), t.as_ptr());
107-
}
124+
std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *const $ffi_name, v_ptr, t.len());
125+
std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
108126

109127
v_ptr
110128
};
@@ -114,11 +132,12 @@ macro_rules! glib_boxed_wrapper {
114132

115133
fn to_glib_full_from_slice(t: &[Self]) -> *mut *const $ffi_name {
116134
unsafe {
117-
let v_ptr = $crate::ffi::g_malloc0(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
135+
let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
118136

119137
for (i, s) in t.iter().enumerate() {
120138
std::ptr::write(v_ptr.add(i), $crate::translate::ToGlibPtr::to_glib_full(s));
121139
}
140+
std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
122141

123142
v_ptr
124143
}
@@ -313,9 +332,8 @@ macro_rules! glib_boxed_wrapper {
313332
unsafe fn from_value(value: &'a $crate::Value) -> Self {
314333
debug_assert_eq!(std::mem::size_of::<Self>(), std::mem::size_of::<$crate::ffi::gpointer>());
315334
let value = &*(value as *const $crate::Value as *const $crate::gobject_ffi::GValue);
316-
let ptr = &value.data[0].v_pointer as *const $crate::ffi::gpointer as *const *const $ffi_name;
317-
debug_assert!(!(*ptr).is_null());
318-
&*(ptr as *const $name $(<$($generic),+>)?)
335+
debug_assert!(!value.data[0].v_pointer.is_null());
336+
<$name $(<$($generic),+>)?>::from_glib_ptr_borrow(&value.data[0].v_pointer as *const $crate::ffi::gpointer as *const *const $ffi_name)
319337
}
320338
}
321339

glib/src/boxed_inline.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ macro_rules! glib_boxed_inline_wrapper {
3030

3131
$crate::glib_boxed_inline_wrapper!(
3232
@generic_impl [$($attr)*] $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $ffi_name,
33-
@copy ptr unsafe { let copy = $crate::ffi::g_malloc0(std::mem::size_of::<$ffi_name>()) as *mut $ffi_name; std::ptr::copy_nonoverlapping(ptr, copy, 1); copy },
33+
@copy ptr unsafe { let copy = $crate::ffi::g_malloc(std::mem::size_of::<$ffi_name>()) as *mut $ffi_name; std::ptr::copy_nonoverlapping(ptr, copy, 1); copy },
3434
@free ptr unsafe { $crate::ffi::g_free(ptr as *mut _); },
3535
@init _ptr (), @copy_into dest src std::ptr::copy_nonoverlapping(src, dest, 1), @clear _ptr ()
3636
);
@@ -100,7 +100,7 @@ macro_rules! glib_boxed_inline_wrapper {
100100

101101
$crate::glib_boxed_inline_wrapper!(
102102
@generic_impl [$($attr)*] $name $(<$($generic $(: $bound $(+ $bound2)*)?),+>)?, $ffi_name,
103-
@copy ptr unsafe { let copy = $crate::ffi::g_malloc0(std::mem::size_of::<$ffi_name>()) as *mut $ffi_name; let c = |$copy_into_arg_dest, $copy_into_arg_src| $copy_into_expr; c(copy, ptr); copy },
103+
@copy ptr unsafe { let copy = $crate::ffi::g_malloc(std::mem::size_of::<$ffi_name>()) as *mut $ffi_name; let c = |$copy_into_arg_dest, $copy_into_arg_src| $copy_into_expr; c(copy, ptr); copy },
104104
@free ptr unsafe { let c = |$clear_arg| $clear_expr; c(ptr); $crate::ffi::g_free(ptr as *mut _); },
105105
@init $init_arg $init_expr, @copy_into $copy_into_arg_dest $copy_into_arg_src $copy_into_expr, @clear $clear_arg $clear_expr
106106
);
@@ -157,13 +157,30 @@ macro_rules! glib_boxed_inline_wrapper {
157157
pub fn as_ptr(&self) -> *mut $ffi_name {
158158
&self.inner as *const $ffi_name as *mut _
159159
}
160+
161+
#[doc = "Borrows the underlying C value."]
162+
#[inline]
163+
pub unsafe fn from_glib_ptr_borrow<'a>(ptr: *const $ffi_name) -> &'a Self {
164+
&*(ptr as *const Self)
165+
}
166+
167+
#[doc = "Borrows the underlying C value mutably."]
168+
#[inline]
169+
pub unsafe fn from_glib_ptr_borrow_mut<'a>(ptr: *mut $ffi_name) -> &'a mut Self {
170+
&mut *(ptr as *mut Self)
171+
}
160172
}
161173

162174
#[doc(hidden)]
163175
impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::GlibPtrDefault for $name $(<$($generic),+>)? {
164176
type GlibType = *mut $ffi_name;
165177
}
166178

179+
#[doc(hidden)]
180+
unsafe impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::TransparentType for $name $(<$($generic),+>)? {
181+
type GlibType = $ffi_name;
182+
}
183+
167184
#[doc(hidden)]
168185
impl $(<$($generic $(: $bound $(+ $bound2)*)?),+>)? $crate::translate::Uninitialized for $name $(<$($generic),+>)? {
169186
#[inline]
@@ -231,11 +248,12 @@ macro_rules! glib_boxed_inline_wrapper {
231248

232249
fn to_glib_container_from_slice(t: &'a [Self]) -> (*mut *const $ffi_name, Self::Storage) {
233250
let v_ptr = unsafe {
234-
let v_ptr = $crate::ffi::g_malloc0(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
251+
let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
235252

236253
for (i, s) in t.iter().enumerate() {
237254
std::ptr::write(v_ptr.add(i), &s.inner as *const $ffi_name);
238255
}
256+
std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
239257

240258
v_ptr
241259
};
@@ -245,11 +263,12 @@ macro_rules! glib_boxed_inline_wrapper {
245263

246264
fn to_glib_full_from_slice(t: &[Self]) -> *mut *const $ffi_name {
247265
unsafe {
248-
let v_ptr = $crate::ffi::g_malloc0(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
266+
let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<*const $ffi_name>() * (t.len() + 1)) as *mut *const $ffi_name;
249267

250268
for (i, s) in t.iter().enumerate() {
251269
std::ptr::write(v_ptr.add(i), $crate::translate::ToGlibPtr::to_glib_full(s));
252270
}
271+
std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut());
253272

254273
v_ptr
255274
}
@@ -295,7 +314,7 @@ macro_rules! glib_boxed_inline_wrapper {
295314

296315
fn to_glib_full_from_slice(t: &[Self]) -> *mut $ffi_name {
297316
let v_ptr = unsafe {
298-
let v_ptr = $crate::ffi::g_malloc0(std::mem::size_of::<$ffi_name>()) as *mut $ffi_name;
317+
let v_ptr = $crate::ffi::g_malloc(std::mem::size_of::<$ffi_name>()) as *mut $ffi_name;
299318

300319
for (i, s) in t.iter().enumerate() {
301320
let copy_into = |$copy_into_arg_dest: *mut $ffi_name, $copy_into_arg_src: *const $ffi_name| $copy_into_expr;

0 commit comments

Comments
 (0)