Skip to content

Commit 14b4563

Browse files
authored
Merge pull request #977 from sdroege/more-intostrv-impls
glib: Add various `IntoStrV` impls
2 parents f0685a7 + a2a9eb0 commit 14b4563

File tree

1 file changed

+147
-12
lines changed

1 file changed

+147
-12
lines changed

glib/src/collections/strv.rs

Lines changed: 147 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,31 +1054,121 @@ const MAX_STACK_ALLOCATION: usize = 16;
10541054
impl IntoStrV for Vec<GString> {
10551055
#[inline]
10561056
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1057-
let required_len = (self.len() + 1) * mem::size_of::<*mut c_char>()
1058-
+ self.iter().map(|s| s.len() + 1).sum::<usize>();
1057+
self.as_slice().run_with_strv(f)
1058+
}
1059+
}
1060+
1061+
impl<'a> IntoStrV for Vec<&'a GString> {
1062+
#[inline]
1063+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1064+
self.as_slice().run_with_strv(f)
1065+
}
1066+
}
1067+
1068+
impl<'a> IntoStrV for Vec<&'a GStr> {
1069+
#[inline]
1070+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1071+
self.as_slice().run_with_strv(f)
1072+
}
1073+
}
1074+
1075+
impl<'a> IntoStrV for Vec<&'a str> {
1076+
#[inline]
1077+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1078+
self.as_slice().run_with_strv(f)
1079+
}
1080+
}
1081+
1082+
impl IntoStrV for Vec<String> {
1083+
#[inline]
1084+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1085+
self.as_slice().run_with_strv(f)
1086+
}
1087+
}
1088+
1089+
impl<'a> IntoStrV for Vec<&'a String> {
1090+
#[inline]
1091+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1092+
self.as_slice().run_with_strv(f)
1093+
}
1094+
}
1095+
1096+
impl IntoStrV for &[GString] {
1097+
#[inline]
1098+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1099+
let required_len = (self.len() + 1) * mem::size_of::<*mut c_char>();
10591100

10601101
if required_len < MAX_STACK_ALLOCATION * mem::size_of::<*mut c_char>() {
10611102
unsafe {
10621103
let mut s = mem::MaybeUninit::<[*mut c_char; MAX_STACK_ALLOCATION]>::uninit();
10631104
let ptrs = s.as_mut_ptr() as *mut *mut c_char;
1064-
let mut strs = ptrs.add(self.len() + 1) as *mut c_char;
10651105

10661106
for (i, item) in self.iter().enumerate() {
1067-
ptr::copy_nonoverlapping(item.as_ptr(), strs, item.len() + 1);
1068-
*ptrs.add(i) = strs;
1069-
strs = strs.add(item.len() + 1);
1107+
*ptrs.add(i) = item.as_ptr() as *mut _;
1108+
}
1109+
*ptrs.add(self.len()) = ptr::null_mut();
1110+
1111+
f(std::slice::from_raw_parts(ptrs, self.len() + 1))
1112+
}
1113+
} else {
1114+
let mut s = StrV::with_capacity(self.len());
1115+
s.extend_from_slice(self);
1116+
s.run_with_strv(f)
1117+
}
1118+
}
1119+
}
1120+
1121+
impl<'a> IntoStrV for &[&'a GString] {
1122+
#[inline]
1123+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1124+
let required_len = (self.len() + 1) * mem::size_of::<*mut c_char>();
1125+
1126+
if required_len < MAX_STACK_ALLOCATION * mem::size_of::<*mut c_char>() {
1127+
unsafe {
1128+
let mut s = mem::MaybeUninit::<[*mut c_char; MAX_STACK_ALLOCATION]>::uninit();
1129+
let ptrs = s.as_mut_ptr() as *mut *mut c_char;
1130+
1131+
for (i, item) in self.iter().enumerate() {
1132+
*ptrs.add(i) = item.as_ptr() as *mut _;
10701133
}
10711134
*ptrs.add(self.len()) = ptr::null_mut();
10721135

10731136
f(std::slice::from_raw_parts(ptrs, self.len() + 1))
10741137
}
10751138
} else {
1076-
StrV::from(self).run_with_strv(f)
1139+
let mut s = StrV::with_capacity(self.len());
1140+
s.extend_from_slice(self);
1141+
s.run_with_strv(f)
10771142
}
10781143
}
10791144
}
10801145

1081-
impl<'a> IntoStrV for &'a [String] {
1146+
impl<'a> IntoStrV for &[&'a GStr] {
1147+
#[inline]
1148+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1149+
let required_len = (self.len() + 1) * mem::size_of::<*mut c_char>();
1150+
1151+
if required_len < MAX_STACK_ALLOCATION * mem::size_of::<*mut c_char>() {
1152+
unsafe {
1153+
let mut s = mem::MaybeUninit::<[*mut c_char; MAX_STACK_ALLOCATION]>::uninit();
1154+
let ptrs = s.as_mut_ptr() as *mut *mut c_char;
1155+
1156+
for (i, item) in self.iter().enumerate() {
1157+
*ptrs.add(i) = item.as_ptr() as *mut _;
1158+
}
1159+
*ptrs.add(self.len()) = ptr::null_mut();
1160+
1161+
f(std::slice::from_raw_parts(ptrs, self.len() + 1))
1162+
}
1163+
} else {
1164+
let mut s = StrV::with_capacity(self.len());
1165+
s.extend_from_slice(self);
1166+
s.run_with_strv(f)
1167+
}
1168+
}
1169+
}
1170+
1171+
impl<'a> IntoStrV for &[&'a str] {
10821172
#[inline]
10831173
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
10841174
let required_len = (self.len() + 1) * mem::size_of::<*mut c_char>()
@@ -1108,7 +1198,7 @@ impl<'a> IntoStrV for &'a [String] {
11081198
}
11091199
}
11101200

1111-
impl<'a> IntoStrV for &'a [&'a str] {
1201+
impl IntoStrV for &[String] {
11121202
#[inline]
11131203
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
11141204
let required_len = (self.len() + 1) * mem::size_of::<*mut c_char>()
@@ -1138,7 +1228,7 @@ impl<'a> IntoStrV for &'a [&'a str] {
11381228
}
11391229
}
11401230

1141-
impl<const N: usize> IntoStrV for [GString; N] {
1231+
impl<'a> IntoStrV for &[&'a String] {
11421232
#[inline]
11431233
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
11441234
let required_len = (self.len() + 1) * mem::size_of::<*mut c_char>()
@@ -1151,7 +1241,8 @@ impl<const N: usize> IntoStrV for [GString; N] {
11511241
let mut strs = ptrs.add(self.len() + 1) as *mut c_char;
11521242

11531243
for (i, item) in self.iter().enumerate() {
1154-
ptr::copy_nonoverlapping(item.as_ptr(), strs, item.len() + 1);
1244+
ptr::copy_nonoverlapping(item.as_ptr() as *const _, strs, item.len());
1245+
*strs.add(item.len()) = 0;
11551246
*ptrs.add(i) = strs;
11561247
strs = strs.add(item.len() + 1);
11571248
}
@@ -1160,11 +1251,55 @@ impl<const N: usize> IntoStrV for [GString; N] {
11601251
f(std::slice::from_raw_parts(ptrs, self.len() + 1))
11611252
}
11621253
} else {
1163-
StrV::from(self).run_with_strv(f)
1254+
let mut s = StrV::with_capacity(self.len());
1255+
s.extend_from_slice(self);
1256+
s.run_with_strv(f)
11641257
}
11651258
}
11661259
}
11671260

1261+
impl<const N: usize> IntoStrV for [GString; N] {
1262+
#[inline]
1263+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1264+
self.as_slice().run_with_strv(f)
1265+
}
1266+
}
1267+
1268+
impl<'a, const N: usize> IntoStrV for [&'a GString; N] {
1269+
#[inline]
1270+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1271+
self.as_slice().run_with_strv(f)
1272+
}
1273+
}
1274+
1275+
impl<'a, const N: usize> IntoStrV for [&'a GStr; N] {
1276+
#[inline]
1277+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1278+
self.as_slice().run_with_strv(f)
1279+
}
1280+
}
1281+
1282+
impl<'a, const N: usize> IntoStrV for [&'a str; N] {
1283+
#[inline]
1284+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1285+
self.as_slice().run_with_strv(f)
1286+
}
1287+
}
1288+
1289+
impl<const N: usize> IntoStrV for [String; N] {
1290+
#[inline]
1291+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1292+
self.as_slice().run_with_strv(f)
1293+
}
1294+
}
1295+
1296+
impl<'a, const N: usize> IntoStrV for [&'a String; N] {
1297+
#[inline]
1298+
fn run_with_strv<R, F: FnOnce(&[*mut c_char]) -> R>(self, f: F) -> R {
1299+
self.as_slice().run_with_strv(f)
1300+
}
1301+
}
1302+
11681303
#[cfg(test)]
11691304
mod test {
11701305
use super::*;

0 commit comments

Comments
 (0)