Skip to main content

miniextendr_api/
into_r.rs

1#![allow(rustdoc::private_intra_doc_links)]
2//! Conversions from Rust types to R SEXP.
3//!
4//! This module provides the [`IntoR`] trait for converting Rust values to R SEXPs.
5//!
6//! # Submodules
7//!
8//! | Module | Contents |
9//! |--------|----------|
10//! | [`large_integers`] | `i64`, `u64`, `isize`, `usize` → REALSXP, plus string/bool/Option scalars |
11//! | [`collections`] | `HashMap`, `BTreeMap`, `HashSet`, `BTreeSet` → named/unnamed lists |
12//! | [`result`] | `Result<T, E>` → list with `ok`/`err` fields |
13//! | [`altrep`] | `Altrep<T>` marker type, `Lazy<T>` alias, `IntoRAltrep` trait |
14//!
15//! # Choosing the right outbound conversion
16//!
17//! [`IntoR`] is the **lax** outbound path — it silently widens 64-bit integers
18//! to R's `REALSXP` when the value doesn't fit `INTSXP`. The strict alternative
19//! lives in [`crate::strict`] and is opted into via `#[miniextendr(strict)]`,
20//! which routes through [`crate::strict::checked_into_sexp_i64`] and friends.
21//! Failure mode of staying on the default lax path when you care about exact
22//! representation: an `i64` value just above `i32::MAX` lands in R as an
23//! inexact `f64` (and IDs/counters larger than `2^53` start colliding).
24//!
25//! For storage-directed conversions (e.g. force `Vec<i64>` into `INTSXP`
26//! when values fit), reach for [`crate::into_r_as::IntoRAs`] instead.
27//!
28//! The inbound counterpart is [`crate::from_r::TryFromSexp`] (strict by
29//! construction — returns `Result`); the inbound looser path is
30//! [`crate::coerce::Coerce`] / [`crate::coerce::TryCoerce`]. There is
31//! intentionally no `TryFromSexpStrict` trait.
32//!
33//! # Thread Safety
34//!
35//! The trait provides two methods:
36//! - [`IntoR::into_sexp`] - checked version with debug thread assertions
37//! - [`IntoR::into_sexp_unchecked`] - unchecked version for performance-critical paths
38//!
39//! Use `into_sexp_unchecked` when you're certain you're on the main thread:
40//! - Inside ALTREP callbacks
41//! - Inside standalone `#[miniextendr]` functions (they run on the main thread)
42//! - Inside `extern "C-unwind"` functions called directly by R
43//!
44//! # The absence contract: what `None` becomes in R
45//!
46//! `None` does **not** map to one universal R value — it depends on the
47//! shape of `T` in `Option<T>`:
48//!
49//! - Owned scalars (`Option<i32>`, `Option<f64>`, `Option<bool>`,
50//!   `Option<String>`, and friends in [`large_integers`]) → the matching
51//!   `NA_<type>_`. R has a native NA sentinel for each of these.
52//! - `Option<&T>` where `T: Copy` (e.g. `Option<&i32>`) → `NULL`. A
53//!   reference has nothing to copy on `None`, so there is no NA to
54//!   produce. See the impl doc on `Option<&T>` in [`large_integers`].
55//! - `Option<&str>` is the one exception to the previous rule: it returns
56//!   `NA_character_`, matching `Option<String>`, because `str` is unsized
57//!   and can't use the generic `Copy`-bounded blanket impl — it has its
58//!   own hand-written impl instead.
59//! - Containers (`Option<Vec<T>>`, `Option<HashMap<..>>`, `Option<HashSet<..>>`,
60//!   `Option<BTreeMap<..>>`, `Option<BTreeSet<..>>`) → `NULL`. No container
61//!   type has a native R NA sentinel either.
62//! - The reading markers' `Option` (`Option<AsNumeric>`,
63//!   `Option<AsNumericVec>`, `Option<AsCharacter>`, `Option<AsCharacterVec>`;
64//!   see [`AsNumeric`](crate::convert::AsNumeric) and
65//!   [`AsCharacter`](crate::convert::AsCharacter)) → `NULL`. `NA` already
66//!   means `Some(marker(None))`, so `NULL` is what the marker's `Option`
67//!   reads back as `None`.
68//!
69//! Changing a return type from `Option<i32>` to `Option<&i32>` or
70//! `Option<Vec<i32>>` therefore silently flips the R-visible absence value
71//! from `NA_integer_` to `NULL`, and switching a return from `Option<f64>`
72//! to `Option<AsNumeric>` changes `NA` to `NULL`, with no compiler warning. See
73//! [`result`] for the analogous (and differently-shaped) contract on
74//! `Result::Err`.
75
76use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
77use std::hash::Hash;
78
79use crate::SexpExt;
80use crate::altrep_traits::{NA_INTEGER, NA_LOGICAL, NA_REAL};
81use crate::gc_protect::ProtectScope;
82use crate::list::ListBuilder;
83use crate::strvec::StrVecBuilder;
84
85/// Trait for converting Rust types to R SEXP values.
86///
87/// Outbound counterpart of [`crate::from_r::TryFromSexp`]. This is the **lax**
88/// path for 64-bit integer types — values that overflow `i32` silently land
89/// as `REALSXP`. For the strict alternative, see [`crate::strict`] and the
90/// `#[miniextendr(strict)]` attribute.
91///
92/// # Required Method
93///
94/// Implementors must provide [`try_into_sexp`](IntoR::try_into_sexp) and
95/// specify [`Error`](IntoR::Error). The other three methods have sensible
96/// defaults.
97///
98/// # Examples
99///
100/// ```no_run
101/// use miniextendr_api::into_r::IntoR;
102///
103/// let sexp = 42i32.into_sexp();
104/// let sexp = "hello".to_string().into_sexp();
105///
106/// // Fallible path:
107/// let result = "hello".try_into_sexp();
108/// assert!(result.is_ok());
109/// ```
110#[diagnostic::on_unimplemented(
111    note = "an `Option<Class>` return converts when spelled `Option<ExternalPtr<Class>>`, or with an explicit class wrap: `Option<WrapAsR6<Class>>` or `#[miniextendr(wrap = \"r6\")]` (any class system)"
112)]
113pub trait IntoR {
114    /// The error type for fallible conversions.
115    ///
116    /// Use [`std::convert::Infallible`] for types that can never fail.
117    /// Use [`IntoRError`](crate::into_r_error::IntoRError) for types
118    /// that may fail (e.g. strings exceeding R's i32 length limit).
119    type Error: std::fmt::Display;
120
121    /// Try to convert this value to an R SEXP.
122    ///
123    /// This is the **required** method. All other methods delegate to it.
124    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error>;
125
126    /// Try to convert to SEXP without thread safety checks.
127    ///
128    /// # Safety
129    ///
130    /// Must be called from R's main thread.
131    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error>
132    where
133        Self: Sized,
134    {
135        self.try_into_sexp()
136    }
137
138    /// Convert this value to an R SEXP, panicking on error.
139    ///
140    /// In debug builds, asserts that we're on R's main thread.
141    fn into_sexp(self) -> crate::SEXP
142    where
143        Self: Sized,
144    {
145        match self.try_into_sexp() {
146            Ok(sexp) => sexp,
147            Err(e) => {
    ::core::panicking::panic_fmt(format_args!("IntoR conversion failed: {0}",
            e));
}panic!("IntoR conversion failed: {e}"),
148        }
149    }
150
151    /// Convert to SEXP without thread safety checks, panicking on error.
152    ///
153    /// # Safety
154    ///
155    /// Must be called from R's main thread. In debug builds, this still
156    /// calls the checked version by default, but implementations may
157    /// skip thread assertions for performance.
158    unsafe fn into_sexp_unchecked(self) -> crate::SEXP
159    where
160        Self: Sized,
161    {
162        // Default: just call the checked version
163        self.into_sexp()
164    }
165}
166
167impl IntoR for crate::SEXP {
168    type Error = std::convert::Infallible;
169    #[inline]
170    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
171        Ok(self)
172    }
173    #[inline]
174    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
175        Ok(self)
176    }
177    #[inline]
178    fn into_sexp(self) -> crate::SEXP {
179        self
180    }
181}
182
183impl IntoR for crate::worker::Sendable<crate::SEXP> {
184    type Error = std::convert::Infallible;
185    #[inline]
186    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
187        Ok(self.0)
188    }
189    #[inline]
190    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
191        Ok(self.0)
192    }
193    #[inline]
194    fn into_sexp(self) -> crate::SEXP {
195        self.0
196    }
197}
198
199impl From<crate::worker::Sendable<crate::SEXP>> for crate::SEXP {
200    #[inline]
201    fn from(s: crate::worker::Sendable<crate::SEXP>) -> Self {
202        s.0
203    }
204}
205
206impl IntoR for () {
207    type Error = std::convert::Infallible;
208    #[inline]
209    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
210        Ok(crate::SEXP::nil())
211    }
212    #[inline]
213    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
214        self.try_into_sexp()
215    }
216    #[inline]
217    fn into_sexp(self) -> crate::SEXP {
218        crate::SEXP::nil()
219    }
220}
221
222impl IntoR for std::convert::Infallible {
223    type Error = std::convert::Infallible;
224    #[inline]
225    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
226        match self {}
227    }
228    #[inline]
229    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
230        match self {}
231    }
232    #[inline]
233    fn into_sexp(self) -> crate::SEXP {
234        match self {}
235    }
236}
237
238/// Macro for scalar IntoR via SEXP::scalar_* methods.
239macro_rules! impl_scalar_into_r {
240    ($ty:ty, $checked:ident, $unchecked:ident) => {
241        impl IntoR for $ty {
242            type Error = std::convert::Infallible;
243            #[inline]
244            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
245                Ok(crate::SEXP::$checked(self))
246            }
247            #[inline]
248            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
249                Ok(unsafe { self.into_sexp_unchecked() })
250            }
251            #[inline]
252            fn into_sexp(self) -> crate::SEXP {
253                crate::SEXP::$checked(self)
254            }
255            #[inline]
256            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
257                unsafe { crate::SEXP::$unchecked(self) }
258            }
259        }
260    };
261}
262
263impl IntoR for i32 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::SEXP::scalar_integer(self))
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { crate::SEXP::scalar_integer(self) }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { crate::SEXP::scalar_integer_unchecked(self) }
    }
}impl_scalar_into_r!(i32, scalar_integer, scalar_integer_unchecked);
264impl IntoR for f64 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::SEXP::scalar_real(self))
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { crate::SEXP::scalar_real(self) }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { crate::SEXP::scalar_real_unchecked(self) }
    }
}impl_scalar_into_r!(f64, scalar_real, scalar_real_unchecked);
265impl IntoR for u8 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::SEXP::scalar_raw(self))
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { crate::SEXP::scalar_raw(self) }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { crate::SEXP::scalar_raw_unchecked(self) }
    }
}impl_scalar_into_r!(u8, scalar_raw, scalar_raw_unchecked);
266impl IntoR for crate::Rcomplex {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::SEXP::scalar_complex(self))
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { crate::SEXP::scalar_complex(self) }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { crate::SEXP::scalar_complex_unchecked(self) }
    }
}impl_scalar_into_r!(crate::Rcomplex, scalar_complex, scalar_complex_unchecked);
267
268/// Generate an infallible [`IntoR`] impl whose only real method is `into_sexp`.
269///
270/// Collapses the four-line boilerplate shell shared by every `Infallible`
271/// `IntoR` impl in the optional-type modules: `try_into_sexp` delegates to
272/// `into_sexp`, `try_into_sexp_unchecked` delegates to `try_into_sexp`, and
273/// `into_sexp_unchecked` is left as the trait default. Only the `into_sexp`
274/// body is supplied, as a closure-style `|recv| expr` binding the receiver
275/// (a macro cannot reuse a `self` that arrives through a fragment, so the
276/// caller names it). The generated methods are byte-identical to the
277/// hand-written shell, so this is purely a dedup.
278///
279/// ```ignore
280/// into_r_infallible!(Uuid, |this| this.to_string().into_sexp());
281/// into_r_infallible!(Vec<Uuid>,
282///     |this| this.into_iter().map(|u| u.to_string()).collect::<Vec<_>>().into_sexp());
283/// ```
284macro_rules! into_r_infallible {
285    ($ty:ty, |$recv:ident| $body:expr) => {
286        impl $crate::into_r::IntoR for $ty {
287            type Error = ::std::convert::Infallible;
288            #[inline]
289            fn try_into_sexp(self) -> ::core::result::Result<$crate::SEXP, Self::Error> {
290                ::core::result::Result::Ok(self.into_sexp())
291            }
292            #[inline]
293            unsafe fn try_into_sexp_unchecked(
294                self,
295            ) -> ::core::result::Result<$crate::SEXP, Self::Error> {
296                self.try_into_sexp()
297            }
298            #[inline]
299            fn into_sexp(self) -> $crate::SEXP {
300                let $recv = self;
301                $body
302            }
303        }
304    };
305}
306#[allow(unused_imports)]
307pub(crate) use into_r_infallible;
308
309impl IntoR for Option<crate::Rcomplex> {
310    type Error = std::convert::Infallible;
311    #[inline]
312    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
313        Ok(self.into_sexp())
314    }
315    #[inline]
316    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
317        Ok(unsafe { self.into_sexp_unchecked() })
318    }
319    #[inline]
320    fn into_sexp(self) -> crate::SEXP {
321        match self {
322            Some(v) => v.into_sexp(),
323            None => crate::SEXP::scalar_complex(crate::Rcomplex {
324                r: NA_REAL,
325                i: NA_REAL,
326            }),
327        }
328    }
329    #[inline]
330    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
331        match self {
332            Some(v) => unsafe { v.into_sexp_unchecked() },
333            None => unsafe {
334                crate::SEXP::scalar_complex_unchecked(crate::Rcomplex {
335                    r: NA_REAL,
336                    i: NA_REAL,
337                })
338            },
339        }
340    }
341}
342
343/// Macro for infallible widening IntoR via Coerce.
344macro_rules! impl_into_r_via_coerce {
345    ($from:ty => $to:ty) => {
346        impl IntoR for $from {
347            type Error = std::convert::Infallible;
348            #[inline]
349            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
350                Ok(crate::coerce::Coerce::<$to>::coerce(self).into_sexp())
351            }
352            #[inline]
353            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
354                Ok(unsafe { self.into_sexp_unchecked() })
355            }
356            #[inline]
357            fn into_sexp(self) -> crate::SEXP {
358                crate::coerce::Coerce::<$to>::coerce(self).into_sexp()
359            }
360            #[inline]
361            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
362                unsafe { crate::coerce::Coerce::<$to>::coerce(self).into_sexp_unchecked() }
363            }
364        }
365    };
366}
367
368// Infallible widening to i32 (R's INTSXP)
369impl IntoR for i8 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::coerce::Coerce::<i32>::coerce(self).into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        crate::coerce::Coerce::<i32>::coerce(self).into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            crate::coerce::Coerce::<i32>::coerce(self).into_sexp_unchecked()
        }
    }
}impl_into_r_via_coerce!(i8 => i32);
370impl IntoR for i16 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::coerce::Coerce::<i32>::coerce(self).into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        crate::coerce::Coerce::<i32>::coerce(self).into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            crate::coerce::Coerce::<i32>::coerce(self).into_sexp_unchecked()
        }
    }
}impl_into_r_via_coerce!(i16 => i32);
371impl IntoR for u16 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::coerce::Coerce::<i32>::coerce(self).into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        crate::coerce::Coerce::<i32>::coerce(self).into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            crate::coerce::Coerce::<i32>::coerce(self).into_sexp_unchecked()
        }
    }
}impl_into_r_via_coerce!(u16 => i32);
372
373// Infallible widening to f64 (R's REALSXP)
374impl IntoR for f32 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::coerce::Coerce::<f64>::coerce(self).into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        crate::coerce::Coerce::<f64>::coerce(self).into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            crate::coerce::Coerce::<f64>::coerce(self).into_sexp_unchecked()
        }
    }
}impl_into_r_via_coerce!(f32 => f64);
375impl IntoR for u32 {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(crate::coerce::Coerce::<f64>::coerce(self).into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        crate::coerce::Coerce::<f64>::coerce(self).into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            crate::coerce::Coerce::<f64>::coerce(self).into_sexp_unchecked()
        }
    }
}impl_into_r_via_coerce!(u32 => f64); // all u32 exactly representable in f64
376
377mod large_integers;
378pub(crate) use large_integers::{str_to_charsxp, str_to_charsxp_unchecked};
379
380// region: Vector conversions
381
382// Concrete IntoR impls for Vec<T> where T: RNativeType.
383//
384// These are written as concrete impls rather than a blanket
385// `impl<T: RNativeType> IntoR for Vec<T>` to avoid a coherence conflict with the
386// one `impl<T: IntoRVecElement> IntoR for Vec<T>` blanket (see `crate::newtype`):
387// `Vec<T>` admits exactly one open-bound `IntoR` blanket slot, and that slot is
388// the shared element-marker route used by `MatchArg` enums and `#[derive(IntoR)]`
389// newtypes. A second `RNativeType`-bounded blanket would be E0119 — negative
390// trait bounds are not stable, so coherence cannot prove the bounds disjoint.
391// Concrete per-type impls sidestep the slot entirely (concrete-vs-blanket is
392// allowed: the foreign R-native types provably do not implement the marker).
393macro_rules! impl_into_r_vec_native {
394    ($t:ty) => {
395        impl IntoR for Vec<$t> {
396            type Error = std::convert::Infallible;
397            #[inline]
398            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
399                Ok(unsafe { vec_to_sexp(&self) })
400            }
401            #[inline]
402            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
403                Ok(unsafe { self.into_sexp_unchecked() })
404            }
405            #[inline]
406            fn into_sexp(self) -> crate::SEXP {
407                unsafe { vec_to_sexp(&self) }
408            }
409            #[inline]
410            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
411                unsafe { vec_to_sexp_unchecked(&self) }
412            }
413        }
414    };
415}
416
417impl IntoR for Vec<i32> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { vec_to_sexp(&self) })
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { unsafe { vec_to_sexp(&self) } }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { vec_to_sexp_unchecked(&self) }
    }
}impl_into_r_vec_native!(i32);
418impl IntoR for Vec<f64> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { vec_to_sexp(&self) })
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { unsafe { vec_to_sexp(&self) } }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { vec_to_sexp_unchecked(&self) }
    }
}impl_into_r_vec_native!(f64);
419impl IntoR for Vec<u8> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { vec_to_sexp(&self) })
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { unsafe { vec_to_sexp(&self) } }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { vec_to_sexp_unchecked(&self) }
    }
}impl_into_r_vec_native!(u8);
420impl IntoR for Vec<crate::RLogical> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { vec_to_sexp(&self) })
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { unsafe { vec_to_sexp(&self) } }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { vec_to_sexp_unchecked(&self) }
    }
}impl_into_r_vec_native!(crate::RLogical);
421impl IntoR for Vec<crate::Rcomplex> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { vec_to_sexp(&self) })
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP { unsafe { vec_to_sexp(&self) } }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { vec_to_sexp_unchecked(&self) }
    }
}impl_into_r_vec_native!(crate::Rcomplex);
422
423impl<T> IntoR for &[T]
424where
425    T: crate::RNativeType,
426{
427    type Error = std::convert::Infallible;
428    #[inline]
429    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
430        Ok(unsafe { vec_to_sexp(self) })
431    }
432    #[inline]
433    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
434        Ok(unsafe { self.into_sexp_unchecked() })
435    }
436    #[inline]
437    fn into_sexp(self) -> crate::SEXP {
438        unsafe { vec_to_sexp(self) }
439    }
440    #[inline]
441    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
442        unsafe { vec_to_sexp_unchecked(self) }
443    }
444}
445
446// A boxed slice converts exactly like the owned vector. `into_vec()` is an
447// O(1), allocation-free widen, so this one blanket subsumes every per-element
448// `Box<[X]>` impl (native, String, Cow, bool, …): any `Vec<X>: IntoR` element
449// gets `Box<[X]>` for free, inheriting the vector impl's error type and path.
450// Coherence-equivalent to the prior `impl<T: RNativeType> IntoR for Box<[T]>`:
451// both occupy the whole `Box<[T]>` slot (where-clauses don't narrow overlap),
452// so concrete downstream `impl IntoR for Box<[Local]>` stays just as available.
453impl<T> IntoR for Box<[T]>
454where
455    Vec<T>: IntoR,
456{
457    type Error = <Vec<T> as IntoR>::Error;
458    #[inline]
459    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
460        self.into_vec().try_into_sexp()
461    }
462    #[inline]
463    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
464        unsafe { self.into_vec().try_into_sexp_unchecked() }
465    }
466    #[inline]
467    fn into_sexp(self) -> crate::SEXP {
468        self.into_vec().into_sexp()
469    }
470    #[inline]
471    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
472        unsafe { self.into_vec().into_sexp_unchecked() }
473    }
474}
475
476// region: R vector allocation helpers
477//
478// These are the ONLY place in the codebase that should call Rf_allocVector
479// for typed vectors and obtain a mutable data slice. All conversion code
480// uses these helpers instead of raw FFI pointer arithmetic.
481
482/// Allocate an R vector of type `T` with `n` elements and return `(SEXP, &mut [T])`.
483///
484/// The returned SEXP is **unprotected** — caller must protect via `Rf_protect`,
485/// `OwnedProtect`, or `ProtectScope` before any further R allocation.
486///
487/// # Safety
488///
489/// Must be called from R's main thread.
490#[inline]
491pub(crate) unsafe fn alloc_r_vector<T: crate::RNativeType>(
492    n: usize,
493) -> (crate::SEXP, &'static mut [T]) {
494    unsafe {
495        let sexp = crate::sys::Rf_allocVector(T::SEXP_TYPE, n as crate::R_xlen_t);
496        let slice = crate::from_r::r_slice_mut(T::dataptr_mut(sexp), n);
497        (sexp, slice)
498    }
499}
500
501/// Allocate an R vector (unchecked FFI variant).
502///
503/// # Safety
504///
505/// Must be called from R's main thread.
506#[inline]
507pub(crate) unsafe fn alloc_r_vector_unchecked<T: crate::RNativeType>(
508    n: usize,
509) -> (crate::SEXP, &'static mut [T]) {
510    unsafe {
511        let sexp = crate::sys::Rf_allocVector_unchecked(T::SEXP_TYPE, n as crate::R_xlen_t);
512        let slice = crate::from_r::r_slice_mut(T::dataptr_mut(sexp), n);
513        (sexp, slice)
514    }
515}
516
517// endregion
518
519/// Convert a slice to an R vector (checked) using `copy_from_slice`.
520#[inline]
521unsafe fn vec_to_sexp<T: crate::RNativeType>(slice: &[T]) -> crate::SEXP {
522    unsafe {
523        let (sexp, dst) = alloc_r_vector::<T>(slice.len());
524        dst.copy_from_slice(slice);
525        sexp
526    }
527}
528
529/// Convert a slice to an R vector (unchecked) using `copy_from_slice`.
530#[inline]
531unsafe fn vec_to_sexp_unchecked<T: crate::RNativeType>(slice: &[T]) -> crate::SEXP {
532    unsafe {
533        let (sexp, dst) = alloc_r_vector_unchecked::<T>(slice.len());
534        dst.copy_from_slice(slice);
535        sexp
536    }
537}
538// endregion
539
540// region: Vec coercion for non-native types (i8, i16, u16 → i32; f32 → f64)
541
542/// Macro for `Vec<T>` where `T` coerces to a native R type.
543///
544/// Allocates the R vector directly and coerces in-place — no intermediate Vec.
545macro_rules! impl_vec_coerce_into_r {
546    ($from:ty => $to:ty) => {
547        impl IntoR for Vec<$from> {
548            type Error = std::convert::Infallible;
549            #[inline]
550            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
551                Ok(self.into_sexp())
552            }
553            #[inline]
554            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
555                Ok(unsafe { self.into_sexp_unchecked() })
556            }
557            #[inline]
558            fn into_sexp(self) -> crate::SEXP {
559                unsafe {
560                    let (sexp, dst) = alloc_r_vector::<$to>(self.len());
561                    for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
562                        *slot = <$to>::from(val);
563                    }
564                    sexp
565                }
566            }
567            #[inline]
568            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
569                unsafe {
570                    let (sexp, dst) = alloc_r_vector_unchecked::<$to>(self.len());
571                    for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
572                        *slot = <$to>::from(val);
573                    }
574                    sexp
575                }
576            }
577        }
578
579        impl IntoR for &[$from] {
580            type Error = std::convert::Infallible;
581            #[inline]
582            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
583                Ok(self.into_sexp())
584            }
585            #[inline]
586            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
587                Ok(unsafe { self.into_sexp_unchecked() })
588            }
589            #[inline]
590            fn into_sexp(self) -> crate::SEXP {
591                unsafe {
592                    let (sexp, dst) = alloc_r_vector::<$to>(self.len());
593                    for (slot, &val) in dst.iter_mut().zip(self.iter()) {
594                        *slot = <$to>::from(val);
595                    }
596                    sexp
597                }
598            }
599            #[inline]
600            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
601                unsafe {
602                    let (sexp, dst) = alloc_r_vector_unchecked::<$to>(self.len());
603                    for (slot, &val) in dst.iter_mut().zip(self.iter()) {
604                        *slot = <$to>::from(val);
605                    }
606                    sexp
607                }
608            }
609        }
610    };
611}
612
613// Sub-i32 integer types coerce to i32 (R's INTSXP)
614impl IntoR for Vec<i8> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
}
impl IntoR for &[i8] {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<i32>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
}impl_vec_coerce_into_r!(i8 => i32);
615impl IntoR for Vec<i16> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
}
impl IntoR for &[i16] {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<i32>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
}impl_vec_coerce_into_r!(i16 => i32);
616impl IntoR for Vec<u16> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
}
impl IntoR for &[u16] {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<i32>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <i32>::from(val);
            }
            sexp
        }
    }
}impl_vec_coerce_into_r!(u16 => i32);
617
618// f32 coerces to f64 (R's REALSXP)
619impl IntoR for Vec<f32> {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<f64>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <f64>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = <f64>::from(val);
            }
            sexp
        }
    }
}
impl IntoR for &[f32] {
    type Error = std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<f64>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <f64>::from(val);
            }
            sexp
        }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
            for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                *slot = <f64>::from(val);
            }
            sexp
        }
    }
}impl_vec_coerce_into_r!(f32 => f64);
620
621// i64/u64/isize/usize/u32: smart conversion (INTSXP when all fit, else REALSXP)
622//
623// Allocates the R vector directly and coerces in-place — no intermediate Vec.
624// The slice impl carries the conversion; the `Vec` impl borrows into it (the
625// elements are `Copy`), so `Vec<T>` and `&[T]` always agree.
626macro_rules! impl_vec_smart_i64_into_r {
627    ($t:ty, $fits_i32:expr) => {
628        impl IntoR for &[$t] {
629            type Error = std::convert::Infallible;
630            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
631                Ok(self.into_sexp())
632            }
633            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
634                Ok(unsafe { self.into_sexp_unchecked() })
635            }
636            fn into_sexp(self) -> crate::SEXP {
637                unsafe {
638                    if self.iter().all(|&x| $fits_i32(x)) {
639                        let (sexp, dst) = alloc_r_vector::<i32>(self.len());
640                        for (slot, &val) in dst.iter_mut().zip(self.iter()) {
641                            // fits_i32 guard verified range
642                            *slot = val as i32;
643                        }
644                        sexp
645                    } else {
646                        let (sexp, dst) = alloc_r_vector::<f64>(self.len());
647                        for (slot, &val) in dst.iter_mut().zip(self.iter()) {
648                            // R has no 64-bit integer; f64 loses precision > 2^53
649                            *slot = val as f64;
650                        }
651                        sexp
652                    }
653                }
654            }
655            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
656                unsafe {
657                    if self.iter().all(|&x| $fits_i32(x)) {
658                        let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
659                        for (slot, &val) in dst.iter_mut().zip(self.iter()) {
660                            // fits_i32 guard verified range
661                            *slot = val as i32;
662                        }
663                        sexp
664                    } else {
665                        let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
666                        for (slot, &val) in dst.iter_mut().zip(self.iter()) {
667                            // R has no 64-bit integer; f64 loses precision > 2^53
668                            *slot = val as f64;
669                        }
670                        sexp
671                    }
672                }
673            }
674        }
675
676        impl IntoR for Vec<$t> {
677            type Error = std::convert::Infallible;
678            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
679                Ok(self.into_sexp())
680            }
681            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
682                Ok(unsafe { self.into_sexp_unchecked() })
683            }
684            fn into_sexp(self) -> crate::SEXP {
685                self.as_slice().into_sexp()
686            }
687            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
688                unsafe { self.as_slice().into_sexp_unchecked() }
689            }
690        }
691    };
692}
693
694// i32::MIN is NA_integer_ in R, so exclude it
695impl IntoR for &[i64] {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x|
                        (|x: i64| x > i32::MIN as i64 && x <= i32::MAX as i64)(x)) {
                let (sexp, dst) = alloc_r_vector::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x|
                        (|x: i64| x > i32::MIN as i64 && x <= i32::MAX as i64)(x)) {
                let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
}
impl IntoR for Vec<i64> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP { self.as_slice().into_sexp() }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.as_slice().into_sexp_unchecked() }
    }
}impl_vec_smart_i64_into_r!(i64, |x: i64| x > i32::MIN as i64 && x <= i32::MAX as i64);
696impl IntoR for &[u64] {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x| (|x: u64| x <= i32::MAX as u64)(x)) {
                let (sexp, dst) = alloc_r_vector::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x| (|x: u64| x <= i32::MAX as u64)(x)) {
                let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
}
impl IntoR for Vec<u64> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP { self.as_slice().into_sexp() }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.as_slice().into_sexp_unchecked() }
    }
}impl_vec_smart_i64_into_r!(u64, |x: u64| x <= i32::MAX as u64);
697impl IntoR for &[isize] {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x|
                        (|x: isize|
                                x > i32::MIN as isize && x <= i32::MAX as isize)(x)) {
                let (sexp, dst) = alloc_r_vector::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x|
                        (|x: isize|
                                x > i32::MIN as isize && x <= i32::MAX as isize)(x)) {
                let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
}
impl IntoR for Vec<isize> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP { self.as_slice().into_sexp() }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.as_slice().into_sexp_unchecked() }
    }
}impl_vec_smart_i64_into_r!(isize, |x: isize| x > i32::MIN as isize
698    && x <= i32::MAX as isize);
699impl IntoR for &[usize] {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x| (|x: usize| x <= i32::MAX as usize)(x)) {
                let (sexp, dst) = alloc_r_vector::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x| (|x: usize| x <= i32::MAX as usize)(x)) {
                let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
}
impl IntoR for Vec<usize> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP { self.as_slice().into_sexp() }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.as_slice().into_sexp_unchecked() }
    }
}impl_vec_smart_i64_into_r!(usize, |x: usize| x <= i32::MAX as usize);
700// Matches Vec<Option<u32>> (impl_vec_option_coerce_into_r!(u32 => i64)):
701// INTSXP while everything fits, REALSXP otherwise.
702impl IntoR for &[u32] {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x| (|x: u32| x <= i32::MAX as u32)(x)) {
                let (sexp, dst) = alloc_r_vector::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            if self.iter().all(|&x| (|x: u32| x <= i32::MAX as u32)(x)) {
                let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as i32;
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
                for (slot, &val) in dst.iter_mut().zip(self.iter()) {
                    *slot = val as f64;
                }
                sexp
            }
        }
    }
}
impl IntoR for Vec<u32> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP { self.as_slice().into_sexp() }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.as_slice().into_sexp_unchecked() }
    }
}impl_vec_smart_i64_into_r!(u32, |x: u32| x <= i32::MAX as u32);
703// endregion
704
705mod altrep;
706mod collections;
707mod owned_str;
708mod result;
709
710pub use altrep::*;
711pub use result::*;
712
713// region: Fixed-size array conversions
714
715/// Convert a fixed-size array through its borrowed slice conversion.
716///
717/// Native values, smart integers, strings and logicals keep the slice's R
718/// representation and error type, without allocating an intermediate `Vec`.
719impl<T, E, const N: usize> IntoR for [T; N]
720where
721    for<'a> &'a [T]: IntoR<Error = E>,
722    E: std::fmt::Display,
723{
724    type Error = E;
725    #[inline]
726    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
727        self.as_slice().try_into_sexp()
728    }
729    #[inline]
730    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
731        unsafe { self.as_slice().try_into_sexp_unchecked() }
732    }
733    #[inline]
734    fn into_sexp(self) -> crate::SEXP {
735        self.as_slice().into_sexp()
736    }
737    #[inline]
738    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
739        unsafe { self.as_slice().into_sexp_unchecked() }
740    }
741}
742
743/// Convert an optional array: `Some` uses the array conversion, `None` is NULL.
744impl<T, const N: usize> IntoR for Option<[T; N]>
745where
746    [T; N]: IntoR,
747{
748    type Error = <[T; N] as IntoR>::Error;
749    #[inline]
750    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
751        match self {
752            Some(array) => array.try_into_sexp(),
753            None => Ok(crate::SEXP::nil()),
754        }
755    }
756    #[inline]
757    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
758        match self {
759            Some(array) => unsafe { array.try_into_sexp_unchecked() },
760            None => Ok(crate::SEXP::nil()),
761        }
762    }
763    #[inline]
764    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
765        match self {
766            Some(array) => unsafe { array.into_sexp_unchecked() },
767            None => crate::SEXP::nil(),
768        }
769    }
770}
771
772#[cfg(test)]
773mod array_error_tests {
774    use super::IntoR;
775
776    struct Fallible;
777
778    impl IntoR for &[Fallible] {
779        type Error = &'static str;
780
781        fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
782            Err("checked slice error")
783        }
784
785        unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
786            Err("unchecked slice error")
787        }
788    }
789
790    #[test]
791    fn array_forwards_slice_errors_without_panicking() {
792        assert_eq!(
793            [Fallible].try_into_sexp().unwrap_err(),
794            "checked slice error"
795        );
796        // The test slice conversion performs no R calls.
797        assert_eq!(
798            unsafe { [Fallible].try_into_sexp_unchecked() }.unwrap_err(),
799            "unchecked slice error"
800        );
801        assert_eq!(
802            Some([Fallible]).try_into_sexp().unwrap_err(),
803            "checked slice error"
804        );
805        assert_eq!(
806            unsafe { Some([Fallible]).try_into_sexp_unchecked() }.unwrap_err(),
807            "unchecked slice error"
808        );
809    }
810}
811// endregion
812
813// region: VecDeque conversions
814
815use std::collections::VecDeque;
816
817/// Convert `VecDeque<T>` to R vector where T: RNativeType.
818impl<T> IntoR for VecDeque<T>
819where
820    T: crate::RNativeType,
821{
822    type Error = std::convert::Infallible;
823    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
824        Ok(self.into_sexp())
825    }
826    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
827        Ok(unsafe { self.into_sexp_unchecked() })
828    }
829    fn into_sexp(self) -> crate::SEXP {
830        let vec: Vec<T> = self.into_iter().collect();
831        vec.into_sexp()
832    }
833    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
834        let vec: Vec<T> = self.into_iter().collect();
835        unsafe { vec.into_sexp_unchecked() }
836    }
837}
838// endregion
839
840// region: BinaryHeap conversions
841
842use std::collections::BinaryHeap;
843
844/// Convert `BinaryHeap<T>` to R vector where T: RNativeType + Ord.
845///
846/// The heap is drained into a vector (destroying the heap property).
847/// Elements are returned in arbitrary order, not sorted.
848impl<T> IntoR for BinaryHeap<T>
849where
850    T: crate::RNativeType + Ord,
851{
852    type Error = std::convert::Infallible;
853    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
854        Ok(self.into_vec().into_sexp())
855    }
856    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
857        Ok(unsafe { self.into_sexp_unchecked() })
858    }
859    fn into_sexp(self) -> crate::SEXP {
860        self.into_vec().into_sexp()
861    }
862    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
863        unsafe { self.into_vec().into_sexp_unchecked() }
864    }
865}
866// endregion
867
868// region: Cow conversions
869
870use std::borrow::Cow;
871
872/// Convert `Cow<'_, [T]>` to R vector where T: RNativeType.
873///
874/// Always copies into a fresh R vector via the `&[T]` path. We deliberately do
875/// *not* attempt speculative SEXP pointer recovery on the `Cow::Borrowed` arm:
876/// a bare `&[T]` carries no provenance metadata, so a borrowed *sub-slice* of
877/// an R vector (e.g. `&cow[2..5]`) is indistinguishable from a full borrow by
878/// pointer + length alone. Probing `data_ptr − header` for such a sub-slice
879/// reads provenance-free memory off the start of the R vector — the same hazard
880/// removed from the Arrow path in #867 (see #880). The Arrow `Buffer` can prove
881/// it is R-backed (`ptr_offset`/`capacity`); a `&[T]` cannot, so the only sound
882/// choice is the always-correct copy. `Cow` remains zero-copy on the *input*
883/// side through `TryFromRoot` and generated wrappers; raw `TryFromSexp`
884/// returns owned data. `IntoR` always copies.
885impl<T> IntoR for Cow<'_, [T]>
886where
887    T: crate::RNativeType + Clone,
888{
889    type Error = std::convert::Infallible;
890    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
891        Ok(self.into_sexp())
892    }
893    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
894        Ok(unsafe { self.into_sexp_unchecked() })
895    }
896    fn into_sexp(self) -> crate::SEXP {
897        self.as_ref().into_sexp()
898    }
899    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
900        unsafe { self.as_ref().into_sexp_unchecked() }
901    }
902}
903
904/// Convert `Cow<'_, str>` to R character scalar.
905impl IntoR for Cow<'_, str> {
906    type Error = crate::into_r_error::IntoRError;
907    #[inline]
908    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
909        self.as_ref().try_into_sexp()
910    }
911    #[inline]
912    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
913        Ok(unsafe { self.into_sexp_unchecked() })
914    }
915    #[inline]
916    fn into_sexp(self) -> crate::SEXP {
917        self.as_ref().into_sexp()
918    }
919    #[inline]
920    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
921        unsafe { self.as_ref().into_sexp_unchecked() }
922    }
923}
924// endregion
925
926// region: Box conversions (skipped - conflicts with IntoExternalPtr blanket impl)
927//
928// We can't add `impl<T: IntoR> IntoR for Box<T>` because it conflicts with
929// the blanket impl `impl<T: IntoExternalPtr> IntoR for T`. If downstream
930// crates implement `IntoExternalPtr for Box<SomeType>`, we'd have overlapping
931// impls. Users can manually unbox with `*boxed_value` before conversion.
932// endregion
933
934// region: PathBuf / OsString conversions
935
936use std::ffi::OsString;
937use std::path::PathBuf;
938
939/// Generate IntoR impls for types with `to_string_lossy()` (owned scalar, ref scalar,
940/// Option, Vec, `Vec<Option>`). Used for PathBuf/&Path and OsString/&OsStr.
941macro_rules! impl_lossy_string_into_r {
942    (
943        $(#[$owned_meta:meta])*
944        owned: $owned_ty:ty;
945        $(#[$ref_meta:meta])*
946        ref: $ref_ty:ty;
947        $(#[$option_meta:meta])*
948        option: $opt_ty:ty;
949        $(#[$vec_meta:meta])*
950        vec: $vec_ty:ty;
951        $(#[$vec_option_meta:meta])*
952        vec_option: $vec_opt_ty:ty;
953    ) => {
954        $(#[$owned_meta])*
955        impl IntoR for $owned_ty {
956            type Error = crate::into_r_error::IntoRError;
957            #[inline]
958            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
959                self.to_string_lossy().into_owned().try_into_sexp()
960            }
961            #[inline]
962            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
963                Ok(unsafe { self.into_sexp_unchecked() })
964            }
965            #[inline]
966            fn into_sexp(self) -> crate::SEXP {
967                self.to_string_lossy().into_owned().into_sexp()
968            }
969            #[inline]
970            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
971                unsafe { self.to_string_lossy().into_owned().into_sexp_unchecked() }
972            }
973        }
974
975        $(#[$ref_meta])*
976        impl IntoR for $ref_ty {
977            type Error = crate::into_r_error::IntoRError;
978            #[inline]
979            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
980                self.to_string_lossy().into_owned().try_into_sexp()
981            }
982            #[inline]
983            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
984                Ok(unsafe { self.into_sexp_unchecked() })
985            }
986            #[inline]
987            fn into_sexp(self) -> crate::SEXP {
988                self.to_string_lossy().into_owned().into_sexp()
989            }
990            #[inline]
991            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
992                unsafe { self.to_string_lossy().into_owned().into_sexp_unchecked() }
993            }
994        }
995
996        $(#[$option_meta])*
997        impl IntoR for Option<$owned_ty> {
998            type Error = crate::into_r_error::IntoRError;
999            #[inline]
1000            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1001                self.map(|v| v.to_string_lossy().into_owned()).try_into_sexp()
1002            }
1003            #[inline]
1004            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1005                Ok(unsafe { self.into_sexp_unchecked() })
1006            }
1007            #[inline]
1008            fn into_sexp(self) -> crate::SEXP {
1009                self.map(|v| v.to_string_lossy().into_owned()).into_sexp()
1010            }
1011            #[inline]
1012            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1013                unsafe {
1014                    self.map(|v| v.to_string_lossy().into_owned())
1015                        .into_sexp_unchecked()
1016                }
1017            }
1018        }
1019
1020        $(#[$vec_meta])*
1021        impl IntoR for Vec<$owned_ty> {
1022            type Error = crate::into_r_error::IntoRError;
1023            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1024                Ok(self.into_sexp())
1025            }
1026            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1027                Ok(unsafe { self.into_sexp_unchecked() })
1028            }
1029            fn into_sexp(self) -> crate::SEXP {
1030                let strings: Vec<String> = self
1031                    .into_iter()
1032                    .map(|v| v.to_string_lossy().into_owned())
1033                    .collect();
1034                strings.into_sexp()
1035            }
1036            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1037                let strings: Vec<String> = self
1038                    .into_iter()
1039                    .map(|v| v.to_string_lossy().into_owned())
1040                    .collect();
1041                unsafe { strings.into_sexp_unchecked() }
1042            }
1043        }
1044
1045        $(#[$vec_option_meta])*
1046        impl IntoR for Vec<Option<$owned_ty>> {
1047            type Error = crate::into_r_error::IntoRError;
1048            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1049                Ok(self.into_sexp())
1050            }
1051            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1052                Ok(unsafe { self.into_sexp_unchecked() })
1053            }
1054            fn into_sexp(self) -> crate::SEXP {
1055                let strings: Vec<Option<String>> = self
1056                    .into_iter()
1057                    .map(|opt| opt.map(|v| v.to_string_lossy().into_owned()))
1058                    .collect();
1059                strings.into_sexp()
1060            }
1061            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1062                let strings: Vec<Option<String>> = self
1063                    .into_iter()
1064                    .map(|opt| opt.map(|v| v.to_string_lossy().into_owned()))
1065                    .collect();
1066                unsafe { strings.into_sexp_unchecked() }
1067            }
1068        }
1069    };
1070}
1071
1072#[doc = r" Convert `PathBuf` to R character scalar."]
#[doc = r""]
#[doc = r" On Unix, paths that are not valid UTF-8 will produce lossy output"]
#[doc = r" (invalid sequences replaced with U+FFFD)."]
impl IntoR for PathBuf {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.to_string_lossy().into_owned().try_into_sexp()
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        self.to_string_lossy().into_owned().into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.to_string_lossy().into_owned().into_sexp_unchecked() }
    }
}
#[doc = r" Convert `&Path` to R character scalar."]
impl IntoR for &std::path::Path {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.to_string_lossy().into_owned().try_into_sexp()
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        self.to_string_lossy().into_owned().into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.to_string_lossy().into_owned().into_sexp_unchecked() }
    }
}
#[doc =
r" Convert `Option<PathBuf>` to R: Some(path) -> character, None -> NA_character_."]
impl IntoR for Option<PathBuf> {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map(|v| v.to_string_lossy().into_owned()).try_into_sexp()
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        self.map(|v| v.to_string_lossy().into_owned()).into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            self.map(|v|
                        v.to_string_lossy().into_owned()).into_sexp_unchecked()
        }
    }
}
#[doc = r" Convert `Vec<PathBuf>` to R character vector."]
impl IntoR for Vec<PathBuf> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        let strings: Vec<String> =
            self.into_iter().map(|v|
                        v.to_string_lossy().into_owned()).collect();
        strings.into_sexp()
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        let strings: Vec<String> =
            self.into_iter().map(|v|
                        v.to_string_lossy().into_owned()).collect();
        unsafe { strings.into_sexp_unchecked() }
    }
}
#[doc =
r" Convert `Vec<Option<PathBuf>>` to R character vector with NA support."]
impl IntoR for Vec<Option<PathBuf>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        let strings: Vec<Option<String>> =
            self.into_iter().map(|opt|
                        opt.map(|v| v.to_string_lossy().into_owned())).collect();
        strings.into_sexp()
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        let strings: Vec<Option<String>> =
            self.into_iter().map(|opt|
                        opt.map(|v| v.to_string_lossy().into_owned())).collect();
        unsafe { strings.into_sexp_unchecked() }
    }
}impl_lossy_string_into_r!(
1073    /// Convert `PathBuf` to R character scalar.
1074    ///
1075    /// On Unix, paths that are not valid UTF-8 will produce lossy output
1076    /// (invalid sequences replaced with U+FFFD).
1077    owned: PathBuf;
1078    /// Convert `&Path` to R character scalar.
1079    ref: &std::path::Path;
1080    /// Convert `Option<PathBuf>` to R: Some(path) -> character, None -> NA_character_.
1081    option: PathBuf;
1082    /// Convert `Vec<PathBuf>` to R character vector.
1083    vec: PathBuf;
1084    /// Convert `Vec<Option<PathBuf>>` to R character vector with NA support.
1085    vec_option: PathBuf;
1086);
1087
1088#[doc = r" Convert `OsString` to R character scalar."]
#[doc = r""]
#[doc =
r" On Unix, strings that are not valid UTF-8 will produce lossy output"]
#[doc = r" (invalid sequences replaced with U+FFFD)."]
impl IntoR for OsString {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.to_string_lossy().into_owned().try_into_sexp()
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        self.to_string_lossy().into_owned().into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.to_string_lossy().into_owned().into_sexp_unchecked() }
    }
}
#[doc = r" Convert `&OsStr` to R character scalar."]
impl IntoR for &std::ffi::OsStr {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.to_string_lossy().into_owned().try_into_sexp()
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        self.to_string_lossy().into_owned().into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe { self.to_string_lossy().into_owned().into_sexp_unchecked() }
    }
}
#[doc =
r" Convert `Option<OsString>` to R: Some(s) -> character, None -> NA_character_."]
impl IntoR for Option<OsString> {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map(|v| v.to_string_lossy().into_owned()).try_into_sexp()
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        self.map(|v| v.to_string_lossy().into_owned()).into_sexp()
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            self.map(|v|
                        v.to_string_lossy().into_owned()).into_sexp_unchecked()
        }
    }
}
#[doc = r" Convert `Vec<OsString>` to R character vector."]
impl IntoR for Vec<OsString> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        let strings: Vec<String> =
            self.into_iter().map(|v|
                        v.to_string_lossy().into_owned()).collect();
        strings.into_sexp()
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        let strings: Vec<String> =
            self.into_iter().map(|v|
                        v.to_string_lossy().into_owned()).collect();
        unsafe { strings.into_sexp_unchecked() }
    }
}
#[doc =
r" Convert `Vec<Option<OsString>>` to R character vector with NA support."]
impl IntoR for Vec<Option<OsString>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        let strings: Vec<Option<String>> =
            self.into_iter().map(|opt|
                        opt.map(|v| v.to_string_lossy().into_owned())).collect();
        strings.into_sexp()
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        let strings: Vec<Option<String>> =
            self.into_iter().map(|opt|
                        opt.map(|v| v.to_string_lossy().into_owned())).collect();
        unsafe { strings.into_sexp_unchecked() }
    }
}impl_lossy_string_into_r!(
1089    /// Convert `OsString` to R character scalar.
1090    ///
1091    /// On Unix, strings that are not valid UTF-8 will produce lossy output
1092    /// (invalid sequences replaced with U+FFFD).
1093    owned: OsString;
1094    /// Convert `&OsStr` to R character scalar.
1095    ref: &std::ffi::OsStr;
1096    /// Convert `Option<OsString>` to R: Some(s) -> character, None -> NA_character_.
1097    option: OsString;
1098    /// Convert `Vec<OsString>` to R character vector.
1099    vec: OsString;
1100    /// Convert `Vec<Option<OsString>>` to R character vector with NA support.
1101    vec_option: OsString;
1102);
1103// endregion
1104
1105// region: Set coercion for non-native types (i8, i16, u16 → i32)
1106
1107/// Macro for `HashSet<T>`/`BTreeSet<T>` where `T` coerces to i32 (R's native integer type).
1108macro_rules! impl_set_coerce_into_r {
1109    ($from:ty) => {
1110        impl IntoR for HashSet<$from> {
1111            type Error = std::convert::Infallible;
1112            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1113                Ok(self.into_sexp())
1114            }
1115            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1116                self.try_into_sexp()
1117            }
1118            fn into_sexp(self) -> crate::SEXP {
1119                let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
1120                vec.into_sexp()
1121            }
1122        }
1123
1124        impl IntoR for BTreeSet<$from> {
1125            type Error = std::convert::Infallible;
1126            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1127                Ok(self.into_sexp())
1128            }
1129            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1130                self.try_into_sexp()
1131            }
1132            fn into_sexp(self) -> crate::SEXP {
1133                let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
1134                vec.into_sexp()
1135            }
1136        }
1137    };
1138}
1139
1140// Sub-i32 integer types in sets coerce to i32 (R's INTSXP)
1141impl IntoR for HashSet<i8> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP {
        let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
        vec.into_sexp()
    }
}
impl IntoR for BTreeSet<i8> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP {
        let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
        vec.into_sexp()
    }
}impl_set_coerce_into_r!(i8);
1142impl IntoR for HashSet<i16> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP {
        let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
        vec.into_sexp()
    }
}
impl IntoR for BTreeSet<i16> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP {
        let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
        vec.into_sexp()
    }
}impl_set_coerce_into_r!(i16);
1143impl IntoR for HashSet<u16> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP {
        let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
        vec.into_sexp()
    }
}
impl IntoR for BTreeSet<u16> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP {
        let vec: Vec<i32> = self.into_iter().map(|x| i32::from(x)).collect();
        vec.into_sexp()
    }
}impl_set_coerce_into_r!(u16);
1144// endregion
1145
1146// region: Option<Collection> conversions
1147//
1148// These return NULL (R_NilValue) for None, and the converted collection for Some.
1149// This differs from Option<scalar> which returns NA for None.
1150
1151/// Convert `Option<Vec<T>>` to R: `Some(vec)` → the R vector `Vec<T>`
1152/// produces, `None` → NULL, for every `T` with a `Vec<T>: IntoR` conversion.
1153impl<T> IntoR for Option<Vec<T>>
1154where
1155    Vec<T>: IntoR,
1156{
1157    type Error = <Vec<T> as IntoR>::Error;
1158    #[inline]
1159    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1160        match self {
1161            Some(v) => v.try_into_sexp(),
1162            None => Ok(crate::SEXP::nil()),
1163        }
1164    }
1165    #[inline]
1166    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1167        match self {
1168            Some(v) => unsafe { v.try_into_sexp_unchecked() },
1169            None => Ok(crate::SEXP::nil()),
1170        }
1171    }
1172    #[inline]
1173    fn into_sexp(self) -> crate::SEXP {
1174        match self {
1175            Some(v) => v.into_sexp(),
1176            None => crate::SEXP::nil(),
1177        }
1178    }
1179    #[inline]
1180    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1181        match self {
1182            Some(v) => unsafe { v.into_sexp_unchecked() },
1183            None => crate::SEXP::nil(),
1184        }
1185    }
1186}
1187
1188/// Convert `Option<Box<[T]>>` to R exactly as `Option<Vec<T>>` (`into_vec()`
1189/// is an O(1) widen): `Some` → the R vector `Vec<T>` produces, `None` → NULL.
1190impl<T> IntoR for Option<Box<[T]>>
1191where
1192    Vec<T>: IntoR,
1193{
1194    type Error = <Vec<T> as IntoR>::Error;
1195    #[inline]
1196    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1197        self.map(<[T]>::into_vec).try_into_sexp()
1198    }
1199    #[inline]
1200    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1201        unsafe { self.map(<[T]>::into_vec).try_into_sexp_unchecked() }
1202    }
1203    #[inline]
1204    fn into_sexp(self) -> crate::SEXP {
1205        self.map(<[T]>::into_vec).into_sexp()
1206    }
1207    #[inline]
1208    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1209        unsafe { self.map(<[T]>::into_vec).into_sexp_unchecked() }
1210    }
1211}
1212
1213/// Convert `Option<&[T]>` to R as the slice converts: `Some` → the R vector
1214/// `&[T]` produces, `None` → NULL.
1215impl<'a, T> IntoR for Option<&'a [T]>
1216where
1217    &'a [T]: IntoR,
1218{
1219    type Error = <&'a [T] as IntoR>::Error;
1220    #[inline]
1221    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1222        match self {
1223            Some(v) => v.try_into_sexp(),
1224            None => Ok(crate::SEXP::nil()),
1225        }
1226    }
1227    #[inline]
1228    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1229        match self {
1230            Some(v) => unsafe { v.try_into_sexp_unchecked() },
1231            None => Ok(crate::SEXP::nil()),
1232        }
1233    }
1234    #[inline]
1235    fn into_sexp(self) -> crate::SEXP {
1236        match self {
1237            Some(v) => v.into_sexp(),
1238            None => crate::SEXP::nil(),
1239        }
1240    }
1241    #[inline]
1242    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1243        match self {
1244            Some(v) => unsafe { v.into_sexp_unchecked() },
1245            None => crate::SEXP::nil(),
1246        }
1247    }
1248}
1249
1250/// Convert `Option<HashMap<String, V>>` to R: Some(map) -> named list, None -> NULL.
1251impl<V: IntoR> IntoR for Option<HashMap<String, V>> {
1252    type Error = crate::into_r_error::IntoRError;
1253    #[inline]
1254    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1255        Ok(self.into_sexp())
1256    }
1257    #[inline]
1258    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1259        Ok(unsafe { self.into_sexp_unchecked() })
1260    }
1261    #[inline]
1262    fn into_sexp(self) -> crate::SEXP {
1263        match self {
1264            Some(v) => v.into_sexp(),
1265            None => crate::SEXP::nil(),
1266        }
1267    }
1268    #[inline]
1269    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1270        match self {
1271            Some(v) => unsafe { v.into_sexp_unchecked() },
1272            None => crate::SEXP::nil(),
1273        }
1274    }
1275}
1276
1277/// Convert `Option<BTreeMap<String, V>>` to R: Some(map) -> named list, None -> NULL.
1278impl<V: IntoR> IntoR for Option<BTreeMap<String, V>> {
1279    type Error = crate::into_r_error::IntoRError;
1280    #[inline]
1281    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1282        Ok(self.into_sexp())
1283    }
1284    #[inline]
1285    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1286        Ok(unsafe { self.into_sexp_unchecked() })
1287    }
1288    #[inline]
1289    fn into_sexp(self) -> crate::SEXP {
1290        match self {
1291            Some(v) => v.into_sexp(),
1292            None => crate::SEXP::nil(),
1293        }
1294    }
1295    #[inline]
1296    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1297        match self {
1298            Some(v) => unsafe { v.into_sexp_unchecked() },
1299            None => crate::SEXP::nil(),
1300        }
1301    }
1302}
1303
1304/// Convert `Option<HashSet<T>>` to R: Some(set) -> vector, None -> NULL.
1305impl<T: crate::RNativeType + Eq + Hash> IntoR for Option<HashSet<T>> {
1306    type Error = std::convert::Infallible;
1307    #[inline]
1308    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1309        Ok(self.into_sexp())
1310    }
1311    #[inline]
1312    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1313        Ok(unsafe { self.into_sexp_unchecked() })
1314    }
1315    #[inline]
1316    fn into_sexp(self) -> crate::SEXP {
1317        match self {
1318            Some(v) => v.into_sexp(),
1319            None => crate::SEXP::nil(),
1320        }
1321    }
1322    #[inline]
1323    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1324        match self {
1325            Some(v) => unsafe { v.into_sexp_unchecked() },
1326            None => crate::SEXP::nil(),
1327        }
1328    }
1329}
1330
1331/// Convert `Option<BTreeSet<T>>` to R: Some(set) -> vector, None -> NULL.
1332impl<T: crate::RNativeType + Ord> IntoR for Option<BTreeSet<T>> {
1333    type Error = std::convert::Infallible;
1334    #[inline]
1335    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1336        Ok(self.into_sexp())
1337    }
1338    #[inline]
1339    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1340        Ok(unsafe { self.into_sexp_unchecked() })
1341    }
1342    #[inline]
1343    fn into_sexp(self) -> crate::SEXP {
1344        match self {
1345            Some(v) => v.into_sexp(),
1346            None => crate::SEXP::nil(),
1347        }
1348    }
1349    #[inline]
1350    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1351        match self {
1352            Some(v) => unsafe { v.into_sexp_unchecked() },
1353            None => crate::SEXP::nil(),
1354        }
1355    }
1356}
1357
1358macro_rules! impl_option_collection_into_r {
1359    ($(#[$meta:meta])* $ty:ty) => {
1360        $(#[$meta])*
1361        impl IntoR for Option<$ty> {
1362            type Error = crate::into_r_error::IntoRError;
1363            #[inline]
1364            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1365                Ok(self.into_sexp())
1366            }
1367            #[inline]
1368            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1369                Ok(unsafe { self.into_sexp_unchecked() })
1370            }
1371            #[inline]
1372            fn into_sexp(self) -> crate::SEXP {
1373                match self {
1374                    Some(v) => v.into_sexp(),
1375                    None => crate::SEXP::nil(),
1376                }
1377            }
1378            #[inline]
1379            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1380                match self {
1381                    Some(v) => unsafe { v.into_sexp_unchecked() },
1382                    None => crate::SEXP::nil(),
1383                }
1384            }
1385        }
1386    };
1387}
1388
1389#[doc =
r" Convert `Option<HashSet<String>>` to R: Some(set) -> character vector, None -> NULL."]
impl IntoR for Option<HashSet<String>> {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        match self { Some(v) => v.into_sexp(), None => crate::SEXP::nil(), }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        match self {
            Some(v) => unsafe { v.into_sexp_unchecked() },
            None => crate::SEXP::nil(),
        }
    }
}impl_option_collection_into_r!(
1390    /// Convert `Option<HashSet<String>>` to R: Some(set) -> character vector, None -> NULL.
1391    HashSet<String>
1392);
1393#[doc =
r" Convert `Option<BTreeSet<String>>` to R: Some(set) -> character vector, None -> NULL."]
impl IntoR for Option<BTreeSet<String>> {
    type Error = crate::into_r_error::IntoRError;
    #[inline]
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        match self { Some(v) => v.into_sexp(), None => crate::SEXP::nil(), }
    }
    #[inline]
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        match self {
            Some(v) => unsafe { v.into_sexp_unchecked() },
            None => crate::SEXP::nil(),
        }
    }
}impl_option_collection_into_r!(
1394    /// Convert `Option<BTreeSet<String>>` to R: Some(set) -> character vector, None -> NULL.
1395    BTreeSet<String>
1396);
1397
1398/// Helper: allocate STRSXP and fill from a string iterator (checked).
1399///
1400/// Routes the alloc + protect through [`StrVecBuilder`] over a local
1401/// [`ProtectScope`]; the CHARSXP policy (empty-string → `R_BlankString`) stays
1402/// here via [`str_to_charsxp`].
1403pub(crate) fn str_iter_to_strsxp<'a>(iter: impl ExactSizeIterator<Item = &'a str>) -> crate::SEXP {
1404    unsafe {
1405        let scope = ProtectScope::new();
1406        let builder = StrVecBuilder::new(&scope, iter.len());
1407        let vec = builder.as_sexp();
1408        for (i, s) in iter.enumerate() {
1409            vec.set_string_elt(i as isize, str_to_charsxp(s));
1410        }
1411        builder.into_sexp()
1412    }
1413}
1414
1415/// Helper: allocate STRSXP and fill from a string iterator (unchecked).
1416pub(crate) unsafe fn str_iter_to_strsxp_unchecked<'a>(
1417    iter: impl ExactSizeIterator<Item = &'a str>,
1418) -> crate::SEXP {
1419    unsafe {
1420        let scope = ProtectScope::new();
1421        let builder = StrVecBuilder::new_unchecked(&scope, iter.len());
1422        let vec = builder.as_sexp();
1423        for (i, s) in iter.enumerate() {
1424            vec.set_string_elt_unchecked(i as isize, str_to_charsxp_unchecked(s));
1425        }
1426        builder.into_sexp()
1427    }
1428}
1429
1430/// Helper: allocate STRSXP and fill from an optional-string iterator (checked).
1431///
1432/// `None` becomes `NA_character_`. Shared by the `Vec<Option<…str>>` impls.
1433pub(crate) fn opt_str_iter_to_strsxp<'a>(
1434    iter: impl ExactSizeIterator<Item = Option<&'a str>>,
1435) -> crate::SEXP {
1436    unsafe {
1437        let scope = ProtectScope::new();
1438        let builder = StrVecBuilder::new(&scope, iter.len());
1439        let vec = builder.as_sexp();
1440        for (i, opt_s) in iter.enumerate() {
1441            let charsxp = match opt_s {
1442                Some(s) => str_to_charsxp(s),
1443                None => crate::SEXP::na_string(),
1444            };
1445            vec.set_string_elt(i as isize, charsxp);
1446        }
1447        builder.into_sexp()
1448    }
1449}
1450
1451/// Helper: allocate STRSXP and fill from an optional-string iterator (unchecked).
1452pub(crate) unsafe fn opt_str_iter_to_strsxp_unchecked<'a>(
1453    iter: impl ExactSizeIterator<Item = Option<&'a str>>,
1454) -> crate::SEXP {
1455    unsafe {
1456        let scope = ProtectScope::new();
1457        let builder = StrVecBuilder::new_unchecked(&scope, iter.len());
1458        let vec = builder.as_sexp();
1459        for (i, opt_s) in iter.enumerate() {
1460            let charsxp = match opt_s {
1461                Some(s) => str_to_charsxp_unchecked(s),
1462                None => crate::SEXP::na_string(),
1463            };
1464            vec.set_string_elt_unchecked(i as isize, charsxp);
1465        }
1466        builder.into_sexp()
1467    }
1468}
1469
1470/// Convert `Vec<String>` to R character vector (STRSXP).
1471impl IntoR for Vec<String> {
1472    type Error = std::convert::Infallible;
1473    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1474        Ok(self.into_sexp())
1475    }
1476    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1477        Ok(unsafe { self.into_sexp_unchecked() })
1478    }
1479    fn into_sexp(self) -> crate::SEXP {
1480        str_iter_to_strsxp(self.iter().map(|s| s.as_str()))
1481    }
1482
1483    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1484        unsafe { str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_str())) }
1485    }
1486}
1487
1488/// Convert `&[String]` to R character vector (STRSXP).
1489impl IntoR for &[String] {
1490    type Error = std::convert::Infallible;
1491    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1492        Ok(self.into_sexp())
1493    }
1494    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1495        Ok(unsafe { self.into_sexp_unchecked() })
1496    }
1497    fn into_sexp(self) -> crate::SEXP {
1498        str_iter_to_strsxp(self.iter().map(|s| s.as_str()))
1499    }
1500
1501    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1502        unsafe { str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_str())) }
1503    }
1504}
1505
1506/// Convert &[&str] to R character vector (STRSXP).
1507impl IntoR for &[&str] {
1508    type Error = std::convert::Infallible;
1509    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1510        Ok(self.into_sexp())
1511    }
1512    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1513        Ok(unsafe { self.into_sexp_unchecked() })
1514    }
1515    fn into_sexp(self) -> crate::SEXP {
1516        str_iter_to_strsxp(self.iter().copied())
1517    }
1518
1519    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1520        unsafe { str_iter_to_strsxp_unchecked(self.iter().copied()) }
1521    }
1522}
1523
1524/// Convert `Vec<Cow<'_, str>>` to R character vector (STRSXP).
1525impl IntoR for Vec<std::borrow::Cow<'_, str>> {
1526    type Error = std::convert::Infallible;
1527    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1528        Ok(self.into_sexp())
1529    }
1530    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1531        Ok(unsafe { self.into_sexp_unchecked() })
1532    }
1533    fn into_sexp(self) -> crate::SEXP {
1534        str_iter_to_strsxp(self.iter().map(|s| s.as_ref()))
1535    }
1536    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1537        unsafe { str_iter_to_strsxp_unchecked(self.iter().map(|s| s.as_ref())) }
1538    }
1539}
1540
1541/// Convert `Vec<Option<Cow<'_, str>>>` to R character vector with NA support.
1542///
1543/// `None` values become `NA_character_` in R.
1544impl IntoR for Vec<Option<std::borrow::Cow<'_, str>>> {
1545    type Error = std::convert::Infallible;
1546    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1547        Ok(self.into_sexp())
1548    }
1549    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1550        Ok(unsafe { self.into_sexp_unchecked() })
1551    }
1552    fn into_sexp(self) -> crate::SEXP {
1553        opt_str_iter_to_strsxp(self.iter().map(|o| o.as_ref().map(|c| c.as_ref())))
1554    }
1555    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1556        unsafe {
1557            opt_str_iter_to_strsxp_unchecked(self.iter().map(|o| o.as_ref().map(|c| c.as_ref())))
1558        }
1559    }
1560}
1561
1562// region: Vec<Option<borrowed string>>
1563/// Convert `Vec<Option<&str>>` to R character vector with NA support.
1564///
1565/// `None` values become `NA_character_` in R. Borrowed analogue of `Vec<Option<String>>`.
1566impl IntoR for Vec<Option<&str>> {
1567    type Error = std::convert::Infallible;
1568    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1569        Ok(self.into_sexp())
1570    }
1571    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1572        Ok(unsafe { self.into_sexp_unchecked() })
1573    }
1574    fn into_sexp(self) -> crate::SEXP {
1575        opt_str_iter_to_strsxp(self.iter().copied())
1576    }
1577    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1578        unsafe { opt_str_iter_to_strsxp_unchecked(self.iter().copied()) }
1579    }
1580}
1581// endregion
1582
1583/// Convert `Vec<&str>` to R character vector (STRSXP).
1584impl IntoR for Vec<&str> {
1585    type Error = std::convert::Infallible;
1586    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1587        Ok(self.into_sexp())
1588    }
1589    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1590        Ok(unsafe { self.into_sexp_unchecked() })
1591    }
1592    fn into_sexp(self) -> crate::SEXP {
1593        self.as_slice().into_sexp()
1594    }
1595
1596    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1597        unsafe { self.as_slice().into_sexp_unchecked() }
1598    }
1599}
1600// endregion
1601
1602// region: VECSXP-from-iterator helpers
1603
1604/// Build a VECSXP from an exact-size iterator of child `SEXP`s (checked).
1605///
1606/// Routes through [`ListBuilder`]: the list is allocated and protected by a
1607/// local [`ProtectScope`] before iteration begins, then the iterator is consumed
1608/// inside the protected window so each child produced lazily (typically via a
1609/// `.map(|c| c.into_sexp())` adaptor at the callsite) is inserted immediately
1610/// via [`ListBuilder::set`], closing the GC gap.
1611///
1612/// The element type is `SEXP` (not a generic `IntoR`) deliberately: the caller
1613/// performs the conversion lazily in the iterator adaptor, which keeps the
1614/// trait solver from chasing the recursive `Vec<Option<Vec<T>>>` impl.
1615///
1616/// # Safety
1617///
1618/// Must be called from the R main thread.
1619#[inline]
1620unsafe fn vecsxp_from_iter<I>(iter: I) -> crate::SEXP
1621where
1622    I: ExactSizeIterator<Item = crate::SEXP>,
1623{
1624    unsafe {
1625        let scope = ProtectScope::new();
1626        let builder = ListBuilder::new(&scope, iter.len());
1627        for (i, child) in iter.enumerate() {
1628            builder.set(i as isize, child);
1629        }
1630        builder.into_sexp()
1631    }
1632}
1633
1634/// `_unchecked` twin of [`vecsxp_from_iter`] — uses [`ListBuilder::set_unchecked`].
1635/// For ALTREP / `with_r_thread` / unwind contexts. The caller's adaptor must
1636/// produce children via `into_sexp_unchecked()`.
1637///
1638/// # Safety
1639///
1640/// Must be called from the R main thread, in a context where the checked-FFI
1641/// assertion is intentionally bypassed.
1642#[inline]
1643unsafe fn vecsxp_from_iter_unchecked<I>(iter: I) -> crate::SEXP
1644where
1645    I: ExactSizeIterator<Item = crate::SEXP>,
1646{
1647    unsafe {
1648        let scope = ProtectScope::new();
1649        let builder = ListBuilder::new_unchecked(&scope, iter.len());
1650        for (i, child) in iter.enumerate() {
1651            builder.set_unchecked(i as isize, child);
1652        }
1653        builder.into_sexp()
1654    }
1655}
1656
1657// endregion
1658
1659// region: Nested vector conversions (list of vectors)
1660//
1661// One generic impl per list-of-vectors shape, each bounded on the element
1662// vector's own conversion (`Vec<T>: IntoR`, or `&[T]: IntoR` for borrowed
1663// rows). Every row therefore lands exactly as the matching flat vector would:
1664// `Vec<Vec<usize>>` gives each row the smart INTSXP-or-REALSXP choice of
1665// `Vec<usize>`, `Vec<Vec<String>>` gives character vectors, and so on. The
1666// fallible paths propagate the row conversion's error type.
1667
1668/// Fallible twin of [`vecsxp_from_iter`]: stops at the first row whose
1669/// conversion fails. The list stays protected by the local scope until it
1670/// returns, so the partially filled list is released on the error path.
1671///
1672/// # Safety
1673///
1674/// Must be called from the R main thread.
1675#[inline]
1676unsafe fn try_vecsxp_from_iter<I, E>(iter: I) -> Result<crate::SEXP, E>
1677where
1678    I: ExactSizeIterator<Item = Result<crate::SEXP, E>>,
1679{
1680    unsafe {
1681        let scope = ProtectScope::new();
1682        let builder = ListBuilder::new(&scope, iter.len());
1683        for (i, child) in iter.enumerate() {
1684            builder.set(i as isize, child?);
1685        }
1686        Ok(builder.into_sexp())
1687    }
1688}
1689
1690/// `_unchecked` twin of [`try_vecsxp_from_iter`] — uses
1691/// [`ListBuilder::set_unchecked`]. The caller's adaptor must produce children
1692/// via `try_into_sexp_unchecked()`.
1693///
1694/// # Safety
1695///
1696/// Must be called from the R main thread, in a context where the checked-FFI
1697/// assertion is intentionally bypassed.
1698#[inline]
1699unsafe fn try_vecsxp_from_iter_unchecked<I, E>(iter: I) -> Result<crate::SEXP, E>
1700where
1701    I: ExactSizeIterator<Item = Result<crate::SEXP, E>>,
1702{
1703    unsafe {
1704        let scope = ProtectScope::new();
1705        let builder = ListBuilder::new_unchecked(&scope, iter.len());
1706        for (i, child) in iter.enumerate() {
1707            builder.set_unchecked(i as isize, child?);
1708        }
1709        Ok(builder.into_sexp())
1710    }
1711}
1712
1713/// Convert `Vec<Vec<T>>` to an R list of vectors (VECSXP), for every `T` with
1714/// a `Vec<T>: IntoR` conversion. Each row is converted by that impl, so it has
1715/// the R type `Vec<T>` produces (for `usize` / `u64` / `i64` / `isize` / `u32`:
1716/// integer when every value fits, else double, decided per row).
1717impl<T> IntoR for Vec<Vec<T>>
1718where
1719    Vec<T>: IntoR,
1720{
1721    type Error = <Vec<T> as IntoR>::Error;
1722    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1723        unsafe { try_vecsxp_from_iter(self.into_iter().map(IntoR::try_into_sexp)) }
1724    }
1725    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1726        unsafe {
1727            try_vecsxp_from_iter_unchecked(self.into_iter().map(|c| c.try_into_sexp_unchecked()))
1728        }
1729    }
1730    fn into_sexp(self) -> crate::SEXP {
1731        unsafe { vecsxp_from_iter(self.into_iter().map(IntoR::into_sexp)) }
1732    }
1733    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1734        unsafe { vecsxp_from_iter_unchecked(self.into_iter().map(|c| c.into_sexp_unchecked())) }
1735    }
1736}
1737
1738/// Convert `Vec<&[T]>` to an R list of vectors (VECSXP), for every `T` with a
1739/// `&[T]: IntoR` conversion.
1740///
1741/// Borrowed analogue of `Vec<Vec<T>>` — each slice is copied into a fresh R
1742/// vector of the type `&[T]` (and `Vec<T>`) produces.
1743impl<'a, T> IntoR for Vec<&'a [T]>
1744where
1745    &'a [T]: IntoR,
1746{
1747    type Error = <&'a [T] as IntoR>::Error;
1748    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1749        unsafe { try_vecsxp_from_iter(self.into_iter().map(IntoR::try_into_sexp)) }
1750    }
1751    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1752        unsafe {
1753            try_vecsxp_from_iter_unchecked(self.into_iter().map(|c| c.try_into_sexp_unchecked()))
1754        }
1755    }
1756    fn into_sexp(self) -> crate::SEXP {
1757        unsafe { vecsxp_from_iter(self.into_iter().map(IntoR::into_sexp)) }
1758    }
1759    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1760        unsafe { vecsxp_from_iter_unchecked(self.into_iter().map(|c| c.into_sexp_unchecked())) }
1761    }
1762}
1763// endregion
1764
1765// region: NA-aware vector conversions
1766
1767/// Macro for NA-aware `Vec<Option<T>> → R` vector conversions.
1768///
1769/// Uses `alloc_r_vector` to get a mutable slice, then fills it.
1770///
1771/// Unlike the sibling `Vec<Option<T>>` macros (`impl_vec_option_smart_i64_into_r!`
1772/// / `impl_vec_option_coerce_into_r!`, which route through `into_r_infallible!`
1773/// and inherit the default-unchecked policy), this one is written out by hand
1774/// because it carries a *real* `into_sexp_unchecked` path (`alloc_r_vector_unchecked`)
1775/// that the others have no analogue for. The divergence is deliberate.
1776macro_rules! impl_vec_option_into_r {
1777    ($t:ty, $na_value:expr) => {
1778        impl IntoR for Vec<Option<$t>> {
1779            type Error = std::convert::Infallible;
1780            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1781                Ok(self.into_sexp())
1782            }
1783            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1784                Ok(unsafe { self.into_sexp_unchecked() })
1785            }
1786            fn into_sexp(self) -> crate::SEXP {
1787                unsafe {
1788                    let (sexp, dst) = alloc_r_vector::<$t>(self.len());
1789                    for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
1790                        *slot = val.unwrap_or($na_value);
1791                    }
1792                    sexp
1793                }
1794            }
1795
1796            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1797                unsafe {
1798                    let (sexp, dst) = alloc_r_vector_unchecked::<$t>(self.len());
1799                    for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
1800                        *slot = val.unwrap_or($na_value);
1801                    }
1802                    sexp
1803                }
1804            }
1805        }
1806    };
1807}
1808
1809impl IntoR for Vec<Option<f64>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<f64>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = val.unwrap_or(NA_REAL);
            }
            sexp
        }
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<f64>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = val.unwrap_or(NA_REAL);
            }
            sexp
        }
    }
}impl_vec_option_into_r!(f64, NA_REAL); // NA_real_
1810impl IntoR for Vec<Option<i32>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = val.unwrap_or(NA_INTEGER);
            }
            sexp
        }
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        unsafe {
            let (sexp, dst) = alloc_r_vector_unchecked::<i32>(self.len());
            for (slot, val) in dst.iter_mut().zip(self.into_iter()) {
                *slot = val.unwrap_or(NA_INTEGER);
            }
            sexp
        }
    }
}impl_vec_option_into_r!(i32, NA_INTEGER); // NA_integer_
1811
1812/// Macro for NA-aware `Vec<Option<T>> → R` smart vector conversion.
1813/// Checks if all non-None values fit i32 → INTSXP, otherwise REALSXP.
1814///
1815/// Allocates the R vector directly and coerces in-place — no intermediate Vec.
1816macro_rules! impl_vec_option_smart_i64_into_r {
1817    ($t:ty, $fits_i32:expr) => {
1818        // Default-unchecked policy, single-sourced through `into_r_infallible!`
1819        // (no bespoke unchecked path — the checked allocation is the only one).
1820        into_r_infallible!(Vec<Option<$t>>, |this| unsafe {
1821            if this.iter().all(|opt| match opt {
1822                Some(x) => $fits_i32(*x),
1823                None => true,
1824            }) {
1825                let (sexp, dst) = alloc_r_vector::<i32>(this.len());
1826                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
1827                    *slot = match val {
1828                        Some(x) => x as i32,
1829                        None => NA_INTEGER,
1830                    };
1831                }
1832                sexp
1833            } else {
1834                let (sexp, dst) = alloc_r_vector::<f64>(this.len());
1835                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
1836                    *slot = match val {
1837                        Some(x) => x as f64,
1838                        None => NA_REAL,
1839                    };
1840                }
1841                sexp
1842            }
1843        });
1844    };
1845}
1846
1847// i32::MIN is NA_integer_ in R, so exclude it
1848impl crate::into_r::IntoR for Vec<Option<i64>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        unsafe {
            if this.iter().all(|opt|
                        match opt {
                            Some(x) =>
                                (|x: i64| x > i32::MIN as i64 && x <= i32::MAX as i64)(*x),
                            None => true,
                        }) {
                let (sexp, dst) = alloc_r_vector::<i32>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot =
                        match val { Some(x) => x as i32, None => NA_INTEGER, };
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot = match val { Some(x) => x as f64, None => NA_REAL, };
                }
                sexp
            }
        }
    }
}impl_vec_option_smart_i64_into_r!(i64, |x: i64| x > i32::MIN as i64 && x <= i32::MAX as i64);
1849impl crate::into_r::IntoR for Vec<Option<u64>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        unsafe {
            if this.iter().all(|opt|
                        match opt {
                            Some(x) => (|x: u64| x <= i32::MAX as u64)(*x),
                            None => true,
                        }) {
                let (sexp, dst) = alloc_r_vector::<i32>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot =
                        match val { Some(x) => x as i32, None => NA_INTEGER, };
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot = match val { Some(x) => x as f64, None => NA_REAL, };
                }
                sexp
            }
        }
    }
}impl_vec_option_smart_i64_into_r!(u64, |x: u64| x <= i32::MAX as u64);
1850impl crate::into_r::IntoR for Vec<Option<isize>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        unsafe {
            if this.iter().all(|opt|
                        match opt {
                            Some(x) =>
                                (|x: isize|
                                        x > i32::MIN as isize && x <= i32::MAX as isize)(*x),
                            None => true,
                        }) {
                let (sexp, dst) = alloc_r_vector::<i32>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot =
                        match val { Some(x) => x as i32, None => NA_INTEGER, };
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot = match val { Some(x) => x as f64, None => NA_REAL, };
                }
                sexp
            }
        }
    }
}impl_vec_option_smart_i64_into_r!(isize, |x: isize| x > i32::MIN as isize
1851    && x <= i32::MAX as isize);
1852impl crate::into_r::IntoR for Vec<Option<usize>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        unsafe {
            if this.iter().all(|opt|
                        match opt {
                            Some(x) => (|x: usize| x <= i32::MAX as usize)(*x),
                            None => true,
                        }) {
                let (sexp, dst) = alloc_r_vector::<i32>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot =
                        match val { Some(x) => x as i32, None => NA_INTEGER, };
                }
                sexp
            } else {
                let (sexp, dst) = alloc_r_vector::<f64>(this.len());
                for (slot, val) in dst.iter_mut().zip(this.into_iter()) {
                    *slot = match val { Some(x) => x as f64, None => NA_REAL, };
                }
                sexp
            }
        }
    }
}impl_vec_option_smart_i64_into_r!(usize, |x: usize| x <= i32::MAX as usize);
1853
1854/// Macro for `Vec<Option<T>>` where `T` coerces to a type with existing Option impl.
1855///
1856/// Delegates to the target type's `Vec<Option<$to>>` impl (which itself uses alloc_r_vector).
1857macro_rules! impl_vec_option_coerce_into_r {
1858    ($from:ty => $to:ty) => {
1859        // Default-unchecked policy, single-sourced through `into_r_infallible!`;
1860        // `into_sexp` delegates to the target `Vec<Option<$to>>` impl.
1861        into_r_infallible!(Vec<Option<$from>>, |this| {
1862            let coerced: Vec<Option<$to>> = this
1863                .into_iter()
1864                .map(|opt| opt.map(|x| <$to>::from(x)))
1865                .collect();
1866            coerced.into_sexp()
1867        });
1868    };
1869}
1870
1871impl crate::into_r::IntoR for Vec<Option<i8>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        {
            let coerced: Vec<Option<i32>> =
                this.into_iter().map(|opt|
                            opt.map(|x| <i32>::from(x))).collect();
            coerced.into_sexp()
        }
    }
}impl_vec_option_coerce_into_r!(i8 => i32);
1872impl crate::into_r::IntoR for Vec<Option<i16>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        {
            let coerced: Vec<Option<i32>> =
                this.into_iter().map(|opt|
                            opt.map(|x| <i32>::from(x))).collect();
            coerced.into_sexp()
        }
    }
}impl_vec_option_coerce_into_r!(i16 => i32);
1873impl crate::into_r::IntoR for Vec<Option<u16>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        {
            let coerced: Vec<Option<i32>> =
                this.into_iter().map(|opt|
                            opt.map(|x| <i32>::from(x))).collect();
            coerced.into_sexp()
        }
    }
}impl_vec_option_coerce_into_r!(u16 => i32);
1874impl crate::into_r::IntoR for Vec<Option<u32>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        {
            let coerced: Vec<Option<i64>> =
                this.into_iter().map(|opt|
                            opt.map(|x| <i64>::from(x))).collect();
            coerced.into_sexp()
        }
    }
}impl_vec_option_coerce_into_r!(u32 => i64); // delegates to smart i64 path
1875impl crate::into_r::IntoR for Vec<Option<f32>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        {
            let coerced: Vec<Option<f64>> =
                this.into_iter().map(|opt|
                            opt.map(|x| <f64>::from(x))).collect();
            coerced.into_sexp()
        }
    }
}impl_vec_option_coerce_into_r!(f32 => f64);
1876
1877/// Helper: allocate LGLSXP and fill from an i32 iterator (checked).
1878///
1879/// Uses `alloc_r_vector` — logical vectors are `RLogical` (repr(transparent) i32).
1880fn logical_iter_to_lglsxp(n: usize, iter: impl Iterator<Item = i32>) -> crate::SEXP {
1881    unsafe {
1882        let (sexp, dst) = alloc_r_vector::<crate::RLogical>(n);
1883        // RLogical is repr(transparent) over i32, safe to write i32 values.
1884        let dst_i32: &mut [i32] = std::slice::from_raw_parts_mut(dst.as_mut_ptr().cast::<i32>(), n);
1885        for (slot, val) in dst_i32.iter_mut().zip(iter) {
1886            *slot = val;
1887        }
1888        sexp
1889    }
1890}
1891
1892/// Helper: allocate LGLSXP and fill from an i32 iterator (unchecked).
1893unsafe fn logical_iter_to_lglsxp_unchecked(
1894    n: usize,
1895    iter: impl Iterator<Item = i32>,
1896) -> crate::SEXP {
1897    unsafe {
1898        let (sexp, dst) = alloc_r_vector_unchecked::<crate::RLogical>(n);
1899        let dst_i32: &mut [i32] = std::slice::from_raw_parts_mut(dst.as_mut_ptr().cast::<i32>(), n);
1900        for (slot, val) in dst_i32.iter_mut().zip(iter) {
1901            *slot = val;
1902        }
1903        sexp
1904    }
1905}
1906
1907/// Convert `Vec<bool>` to R logical vector.
1908impl IntoR for Vec<bool> {
1909    type Error = std::convert::Infallible;
1910    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1911        Ok(self.into_sexp())
1912    }
1913    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1914        Ok(unsafe { self.into_sexp_unchecked() })
1915    }
1916    fn into_sexp(self) -> crate::SEXP {
1917        let n = self.len();
1918        logical_iter_to_lglsxp(n, self.into_iter().map(i32::from))
1919    }
1920
1921    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1922        let n = self.len();
1923        unsafe { logical_iter_to_lglsxp_unchecked(n, self.into_iter().map(i32::from)) }
1924    }
1925}
1926
1927/// Convert `&[bool]` to R logical vector.
1928impl IntoR for &[bool] {
1929    type Error = std::convert::Infallible;
1930    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1931        Ok(self.into_sexp())
1932    }
1933    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1934        Ok(unsafe { self.into_sexp_unchecked() })
1935    }
1936    fn into_sexp(self) -> crate::SEXP {
1937        let n = self.len();
1938        logical_iter_to_lglsxp(n, self.iter().map(|&v| i32::from(v)))
1939    }
1940
1941    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1942        let n = self.len();
1943        unsafe { logical_iter_to_lglsxp_unchecked(n, self.iter().map(|&v| i32::from(v))) }
1944    }
1945}
1946
1947/// Convert `Vec<Rboolean>` to R logical vector (no NA: Rboolean is TRUE/FALSE only).
1948impl IntoR for Vec<crate::Rboolean> {
1949    type Error = std::convert::Infallible;
1950    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1951        Ok(self.into_sexp())
1952    }
1953    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1954        Ok(unsafe { self.into_sexp_unchecked() })
1955    }
1956    fn into_sexp(self) -> crate::SEXP {
1957        let n = self.len();
1958        logical_iter_to_lglsxp(n, self.into_iter().map(|b| b as i32))
1959    }
1960
1961    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1962        let n = self.len();
1963        unsafe { logical_iter_to_lglsxp_unchecked(n, self.into_iter().map(|b| b as i32)) }
1964    }
1965}
1966
1967/// Convert `&[Rboolean]` to R logical vector (no NA: Rboolean is TRUE/FALSE only).
1968impl IntoR for &[crate::Rboolean] {
1969    type Error = std::convert::Infallible;
1970    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1971        Ok(self.into_sexp())
1972    }
1973    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1974        Ok(unsafe { self.into_sexp_unchecked() })
1975    }
1976    fn into_sexp(self) -> crate::SEXP {
1977        let n = self.len();
1978        logical_iter_to_lglsxp(n, self.iter().map(|&b| b as i32))
1979    }
1980
1981    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
1982        let n = self.len();
1983        unsafe { logical_iter_to_lglsxp_unchecked(n, self.iter().map(|&b| b as i32)) }
1984    }
1985}
1986
1987macro_rules! impl_vec_option_logical_into_r {
1988    ($(#[$meta:meta])* $t:ty, $convert:expr) => {
1989        $(#[$meta])*
1990        impl IntoR for Vec<Option<$t>> {
1991            type Error = std::convert::Infallible;
1992            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
1993                Ok(self.into_sexp())
1994            }
1995            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
1996                Ok(unsafe { self.into_sexp_unchecked() })
1997            }
1998            fn into_sexp(self) -> crate::SEXP {
1999                let n = self.len();
2000                logical_iter_to_lglsxp(n, self.into_iter().map($convert))
2001            }
2002
2003            unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
2004                let n = self.len();
2005                unsafe { logical_iter_to_lglsxp_unchecked(n, self.into_iter().map($convert)) }
2006            }
2007        }
2008    };
2009}
2010
2011#[doc = r" Convert `Vec<Option<bool>>` to R logical vector with NA support."]
impl IntoR for Vec<Option<bool>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        let n = self.len();
        logical_iter_to_lglsxp(n,
            self.into_iter().map(|v: Option<bool>|
                    match v {
                        Some(true) => 1,
                        Some(false) => 0,
                        None => NA_LOGICAL,
                    }))
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        let n = self.len();
        unsafe {
            logical_iter_to_lglsxp_unchecked(n,
                self.into_iter().map(|v: Option<bool>|
                        match v {
                            Some(true) => 1,
                            Some(false) => 0,
                            None => NA_LOGICAL,
                        }))
        }
    }
}impl_vec_option_logical_into_r!(
2012    /// Convert `Vec<Option<bool>>` to R logical vector with NA support.
2013    bool,
2014    |v: Option<bool>| match v {
2015        Some(true) => 1,
2016        Some(false) => 0,
2017        None => NA_LOGICAL,
2018    }
2019);
2020#[doc =
r" Convert `Vec<Option<Rboolean>>` to R logical vector with NA support."]
impl IntoR for Vec<Option<crate::Rboolean>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        let n = self.len();
        logical_iter_to_lglsxp(n,
            self.into_iter().map(|v: Option<crate::Rboolean>|
                    match v { Some(b) => b as i32, None => NA_LOGICAL, }))
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        let n = self.len();
        unsafe {
            logical_iter_to_lglsxp_unchecked(n,
                self.into_iter().map(|v: Option<crate::Rboolean>|
                        match v { Some(b) => b as i32, None => NA_LOGICAL, }))
        }
    }
}impl_vec_option_logical_into_r!(
2021    /// Convert `Vec<Option<Rboolean>>` to R logical vector with NA support.
2022    crate::Rboolean,
2023    |v: Option<crate::Rboolean>| match v {
2024        Some(b) => b as i32,
2025        None => NA_LOGICAL,
2026    }
2027);
2028#[doc =
r" Convert `Vec<Option<RLogical>>` to R logical vector with NA support."]
impl IntoR for Vec<Option<crate::RLogical>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        Ok(unsafe { self.into_sexp_unchecked() })
    }
    fn into_sexp(self) -> crate::SEXP {
        let n = self.len();
        logical_iter_to_lglsxp(n,
            self.into_iter().map(|v: Option<crate::RLogical>|
                    match v { Some(b) => b.to_i32(), None => NA_LOGICAL, }))
    }
    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
        let n = self.len();
        unsafe {
            logical_iter_to_lglsxp_unchecked(n,
                self.into_iter().map(|v: Option<crate::RLogical>|
                        match v { Some(b) => b.to_i32(), None => NA_LOGICAL, }))
        }
    }
}impl_vec_option_logical_into_r!(
2029    /// Convert `Vec<Option<RLogical>>` to R logical vector with NA support.
2030    crate::RLogical,
2031    |v: Option<crate::RLogical>| match v {
2032        Some(b) => b.to_i32(),
2033        None => NA_LOGICAL,
2034    }
2035);
2036
2037/// Convert `Vec<Option<String>>` to R character vector with NA support.
2038///
2039/// `None` values become `NA_character_` in R.
2040impl IntoR for Vec<Option<String>> {
2041    type Error = std::convert::Infallible;
2042    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2043        Ok(self.into_sexp())
2044    }
2045    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2046        Ok(unsafe { self.into_sexp_unchecked() })
2047    }
2048    fn into_sexp(self) -> crate::SEXP {
2049        opt_str_iter_to_strsxp(self.iter().map(|o| o.as_deref()))
2050    }
2051
2052    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
2053        unsafe { opt_str_iter_to_strsxp_unchecked(self.iter().map(|o| o.as_deref())) }
2054    }
2055}
2056// endregion
2057
2058// region: Tuple to list conversions
2059
2060// Reuse the protected streaming list builder for both tuple-row shapes.
2061// Failed rows leave NULL slots while later rows are checked; the partial list
2062// never escapes on failure. Each successful row is rooted before the next runs.
2063macro_rules! impl_tuple_vec_into_r {
2064    (($($T:ident),+), $row:ty) => {
2065        impl<$($T: IntoR),+> IntoR for Vec<$row> {
2066            type Error = crate::into_r_error::IntoRError;
2067
2068            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2069                let mut errors = crate::from_r::BatchedErrors::default();
2070                let result = unsafe {
2071                    vecsxp_from_iter(self.into_iter().enumerate().map(|(index, row)| {
2072                        match row.try_into_sexp() {
2073                            Ok(child) => child,
2074                            Err(error) => {
2075                                errors.push(index, || error.to_string());
2076                                crate::SEXP::nil()
2077                            }
2078                        }
2079                    }))
2080                };
2081                if errors.is_empty() {
2082                    Ok(result)
2083                } else {
2084                    Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
2085                }
2086            }
2087
2088            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2089                let mut errors = crate::from_r::BatchedErrors::default();
2090                let result = unsafe {
2091                    vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index, row)| {
2092                        match row.try_into_sexp_unchecked() {
2093                            Ok(child) => child,
2094                            Err(error) => {
2095                                errors.push(index, || error.to_string());
2096                                crate::SEXP::nil()
2097                            }
2098                        }
2099                    }))
2100                };
2101                if errors.is_empty() {
2102                    Ok(result)
2103                } else {
2104                    Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
2105                }
2106            }
2107        }
2108    };
2109}
2110
2111/// Convert Rust tuples to unnamed R lists, collecting every failing field.
2112/// Field error types may differ; their messages share the existing batched
2113/// conversion format with 1-based positions, wrapped in `IntoRError::Inner`.
2114macro_rules! impl_tuple_into_r {
2115    ($n:literal, $name:literal; $($T:ident $R:ident $idx:tt),+) => {
2116        impl<$($T: IntoR),+> IntoR for ($($T,)+) {
2117            type Error = crate::into_r_error::IntoRError;
2118
2119            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2120                unsafe {
2121                    let scope = ProtectScope::new();
2122                    let builder = ListBuilder::new(&scope, $n);
2123                    let mut errors = crate::from_r::BatchedErrors::default();
2124                    $(
2125                        match self.$idx.try_into_sexp() {
2126                            Ok(child) => builder.set($idx as isize, child),
2127                            Err(error) => errors.push($idx, || error.to_string()),
2128                        }
2129                    )+
2130                    if errors.is_empty() {
2131                        Ok(builder.into_sexp())
2132                    } else {
2133                        Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
2134                    }
2135                }
2136            }
2137
2138            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2139                unsafe {
2140                    let scope = ProtectScope::new();
2141                    let builder = ListBuilder::new_unchecked(&scope, $n);
2142                    let mut errors = crate::from_r::BatchedErrors::default();
2143                    $(
2144                        match self.$idx.try_into_sexp_unchecked() {
2145                            Ok(child) => builder.set_unchecked($idx as isize, child),
2146                            Err(error) => errors.push($idx, || error.to_string()),
2147                        }
2148                    )+
2149                    if errors.is_empty() {
2150                        Ok(builder.into_sexp())
2151                    } else {
2152                        Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
2153                    }
2154                }
2155            }
2156        }
2157
2158        impl<$($T: IntoR),+> IntoR for Option<($($T,)+)> {
2159            type Error = <($($T,)+) as IntoR>::Error;
2160
2161            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2162                self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
2163            }
2164
2165            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2166                self.map_or_else(|| Ok(crate::SEXP::nil()), |value| unsafe { value.try_into_sexp_unchecked() })
2167            }
2168        }
2169
2170        impl_tuple_vec_into_r!(($($T),+), ($($T,)+));
2171        impl_tuple_vec_into_r!(($($T),+), Option<($($T,)+)>);
2172    };
2173}
2174
2175impl<A: IntoR> IntoR for (A,) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 1);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 1);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR> IntoR for Option<(A,)> {
    type Error = <(A,) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR> IntoR for Vec<(A,)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR> IntoR for Vec<Option<(A,)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR> IntoR for (A, B) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 2);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 2);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR> IntoR for Option<(A, B)> {
    type Error = <(A, B) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR> IntoR for Vec<(A, B)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR> IntoR for Vec<Option<(A, B)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR> IntoR for (A, B, C) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 3);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 3);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR> IntoR for Option<(A, B, C)> {
    type Error = <(A, B, C) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR> IntoR for Vec<(A, B, C)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR> IntoR for Vec<Option<(A, B, C)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR> IntoR for (A, B, C, D) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 4);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 4);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR> IntoR for Option<(A, B, C, D)> {
    type Error = <(A, B, C, D) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR> IntoR for Vec<(A, B, C, D)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR> IntoR for
    Vec<Option<(A, B, C, D)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR> IntoR for
    (A, B, C, D, E) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 5);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 5);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR> IntoR for
    Option<(A, B, C, D, E)> {
    type Error = <(A, B, C, D, E) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR> IntoR for
    Vec<(A, B, C, D, E)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR> IntoR for
    Vec<Option<(A, B, C, D, E)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR> IntoR for
    (A, B, C, D, E, F) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 6);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp() {
                Ok(child) => builder.set(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 6);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR> IntoR for
    Option<(A, B, C, D, E, F)> {
    type Error = <(A, B, C, D, E, F) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR> IntoR for
    Vec<(A, B, C, D, E, F)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR> IntoR for
    Vec<Option<(A, B, C, D, E, F)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR>
    IntoR for (A, B, C, D, E, F, G) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 7);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp() {
                Ok(child) => builder.set(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp() {
                Ok(child) => builder.set(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 7);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR>
    IntoR for Option<(A, B, C, D, E, F, G)> {
    type Error = <(A, B, C, D, E, F, G) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR>
    IntoR for Vec<(A, B, C, D, E, F, G)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR>
    IntoR for Vec<Option<(A, B, C, D, E, F, G)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR> IntoR for (A, B, C, D, E, F, G, H) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 8);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp() {
                Ok(child) => builder.set(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp() {
                Ok(child) => builder.set(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp() {
                Ok(child) => builder.set(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 8);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR> IntoR for Option<(A, B, C, D, E, F, G, H)> {
    type Error = <(A, B, C, D, E, F, G, H) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR> IntoR for Vec<(A, B, C, D, E, F, G, H)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR> IntoR for Vec<Option<(A, B, C, D, E, F, G, H)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR> IntoR for (A, B, C, D, E, F, G, H, I) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 9);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp() {
                Ok(child) => builder.set(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp() {
                Ok(child) => builder.set(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp() {
                Ok(child) => builder.set(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp() {
                Ok(child) => builder.set(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 9);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR> IntoR for Option<(A, B, C, D, E, F, G, H, I)> {
    type Error = <(A, B, C, D, E, F, G, H, I) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR> IntoR for Vec<(A, B, C, D, E, F, G, H, I)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR> IntoR for Vec<Option<(A, B, C, D, E, F, G, H, I)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR> IntoR for (A, B, C, D, E, F, G, H, I, J) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 10);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp() {
                Ok(child) => builder.set(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp() {
                Ok(child) => builder.set(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp() {
                Ok(child) => builder.set(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp() {
                Ok(child) => builder.set(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            match self.9.try_into_sexp() {
                Ok(child) => builder.set(9 as isize, child),
                Err(error) => errors.push(9, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 10);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            match self.9.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(9 as isize, child),
                Err(error) => errors.push(9, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR> IntoR for
    Option<(A, B, C, D, E, F, G, H, I, J)> {
    type Error = <(A, B, C, D, E, F, G, H, I, J) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR> IntoR for
    Vec<(A, B, C, D, E, F, G, H, I, J)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR> IntoR for
    Vec<Option<(A, B, C, D, E, F, G, H, I, J)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR> IntoR for
    (A, B, C, D, E, F, G, H, I, J, K) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 11);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp() {
                Ok(child) => builder.set(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp() {
                Ok(child) => builder.set(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp() {
                Ok(child) => builder.set(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp() {
                Ok(child) => builder.set(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            match self.9.try_into_sexp() {
                Ok(child) => builder.set(9 as isize, child),
                Err(error) => errors.push(9, || error.to_string()),
            }
            match self.10.try_into_sexp() {
                Ok(child) => builder.set(10 as isize, child),
                Err(error) => errors.push(10, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 11);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            match self.9.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(9 as isize, child),
                Err(error) => errors.push(9, || error.to_string()),
            }
            match self.10.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(10 as isize, child),
                Err(error) => errors.push(10, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR> IntoR for
    Option<(A, B, C, D, E, F, G, H, I, J, K)> {
    type Error = <(A, B, C, D, E, F, G, H, I, J, K) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR> IntoR for
    Vec<(A, B, C, D, E, F, G, H, I, J, K)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR> IntoR for
    Vec<Option<(A, B, C, D, E, F, G, H, I, J, K)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR, L: IntoR> IntoR for
    (A, B, C, D, E, F, G, H, I, J, K, L) {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new(&scope, 12);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp() {
                Ok(child) => builder.set(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp() {
                Ok(child) => builder.set(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp() {
                Ok(child) => builder.set(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp() {
                Ok(child) => builder.set(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp() {
                Ok(child) => builder.set(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp() {
                Ok(child) => builder.set(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp() {
                Ok(child) => builder.set(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp() {
                Ok(child) => builder.set(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp() {
                Ok(child) => builder.set(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            match self.9.try_into_sexp() {
                Ok(child) => builder.set(9 as isize, child),
                Err(error) => errors.push(9, || error.to_string()),
            }
            match self.10.try_into_sexp() {
                Ok(child) => builder.set(10 as isize, child),
                Err(error) => errors.push(10, || error.to_string()),
            }
            match self.11.try_into_sexp() {
                Ok(child) => builder.set(11 as isize, child),
                Err(error) => errors.push(11, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        unsafe {
            let scope = ProtectScope::new();
            let builder = ListBuilder::new_unchecked(&scope, 12);
            let mut errors = crate::from_r::BatchedErrors::default();
            match self.0.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(0 as isize, child),
                Err(error) => errors.push(0, || error.to_string()),
            }
            match self.1.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(1 as isize, child),
                Err(error) => errors.push(1, || error.to_string()),
            }
            match self.2.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(2 as isize, child),
                Err(error) => errors.push(2, || error.to_string()),
            }
            match self.3.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(3 as isize, child),
                Err(error) => errors.push(3, || error.to_string()),
            }
            match self.4.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(4 as isize, child),
                Err(error) => errors.push(4, || error.to_string()),
            }
            match self.5.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(5 as isize, child),
                Err(error) => errors.push(5, || error.to_string()),
            }
            match self.6.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(6 as isize, child),
                Err(error) => errors.push(6, || error.to_string()),
            }
            match self.7.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(7 as isize, child),
                Err(error) => errors.push(7, || error.to_string()),
            }
            match self.8.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(8 as isize, child),
                Err(error) => errors.push(8, || error.to_string()),
            }
            match self.9.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(9 as isize, child),
                Err(error) => errors.push(9, || error.to_string()),
            }
            match self.10.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(10 as isize, child),
                Err(error) => errors.push(10, || error.to_string()),
            }
            match self.11.try_into_sexp_unchecked() {
                Ok(child) => builder.set_unchecked(11 as isize, child),
                Err(error) => errors.push(11, || error.to_string()),
            }
            if errors.is_empty() {
                Ok(builder.into_sexp())
            } else {
                Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
            }
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR, L: IntoR> IntoR for
    Option<(A, B, C, D, E, F, G, H, I, J, K, L)> {
    type Error = <(A, B, C, D, E, F, G, H, I, J, K, L) as IntoR>::Error;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()), IntoR::try_into_sexp)
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.map_or_else(|| Ok(crate::SEXP::nil()),
            |value| unsafe { value.try_into_sexp_unchecked() })
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR, L: IntoR> IntoR for
    Vec<(A, B, C, D, E, F, G, H, I, J, K, L)> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}
impl<A: IntoR, B: IntoR, C: IntoR, D: IntoR, E: IntoR, F: IntoR, G: IntoR,
    H: IntoR, I: IntoR, J: IntoR, K: IntoR, L: IntoR> IntoR for
    Vec<Option<(A, B, C, D, E, F, G, H, I, J, K, L)>> {
    type Error = crate::into_r_error::IntoRError;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        let mut errors = crate::from_r::BatchedErrors::default();
        let result =
            unsafe {
                vecsxp_from_iter_unchecked(self.into_iter().enumerate().map(|(index,
                                row)|
                            {
                                match row.try_into_sexp_unchecked() {
                                    Ok(child) => child,
                                    Err(error) => {
                                        errors.push(index, || error.to_string());
                                        crate::SEXP::nil()
                                    }
                                }
                            }))
            };
        if errors.is_empty() {
            Ok(result)
        } else {
            Err(crate::into_r_error::IntoRError::Inner(errors.element_message()))
        }
    }
}crate::tuple_macros::for_each_tuple!(impl_tuple_into_r);
2176// endregion
2177
2178// region: ALTREP zero-copy extension trait
2179
2180/// Extension trait for ALTREP conversions.
2181///
2182/// This trait provides ergonomic methods for converting Rust types to R ALTREP
2183/// vectors without copying data. The data stays in Rust memory (wrapped in an
2184/// ExternalPtr) and R accesses it via ALTREP callbacks.
2185///
2186/// # Performance Characteristics
2187///
2188/// | Operation | Regular (IntoR) | ALTREP (IntoRAltrep) |
2189/// |-----------|-----------------|------------------------|
2190/// | Creation | O(n) copy | O(1) wrap |
2191/// | Memory | Duplicated in R | Single copy in Rust |
2192/// | Element access | Direct pointer | Callback (~10ns overhead) |
2193/// | DATAPTR ops | O(1) | O(1) if Vec/Box, N/A if lazy |
2194///
2195/// # When to Use ALTREP
2196///
2197/// **Good candidates**:
2198/// - ✅ Large vectors (>1000 elements)
2199/// - ✅ Lazy/computed data (avoid eager materialization)
2200/// - ✅ External data sources (files, databases, APIs)
2201/// - ✅ Data that might not be fully accessed by R
2202///
2203/// **Not recommended**:
2204/// - ❌ Small vectors (<100 elements) - copy overhead is negligible
2205/// - ❌ Data R will immediately modify (triggers copy anyway)
2206/// - ❌ Temporary results (extra indirection not worth it)
2207///
2208/// # Example
2209///
2210/// ```rust,ignore
2211/// use miniextendr_api::{miniextendr, IntoRAltrep, IntoR, SEXP};
2212///
2213/// #[miniextendr]
2214/// fn large_dataset() -> SEXP {
2215///     let data: Vec<f64> = (0..1_000_000).map(|i| i as f64).collect();
2216///
2217///     // Zero-copy: wraps pointer instead of copying 1M elements
2218///     data.into_sexp_altrep()
2219/// }
2220///
2221/// #[miniextendr]
2222/// fn small_result() -> SEXP {
2223///     let data = vec![1, 2, 3, 4, 5];
2224///
2225///     // Regular copy is fine for small data
2226///     data.into_sexp()
2227/// }
2228/// ```
2229pub trait IntoRAltrep {
2230    /// Convert to R SEXP using ALTREP zero-copy representation.
2231    ///
2232    /// This is equivalent to `Altrep(self).into_sexp()` but more discoverable
2233    /// and explicit about the zero-copy intent.
2234    fn into_sexp_altrep(self) -> crate::SEXP;
2235
2236    /// Convert to R SEXP using ALTREP, skipping debug thread assertions.
2237    ///
2238    /// # Safety
2239    ///
2240    /// Caller must ensure they are on R's main thread.
2241    unsafe fn into_sexp_altrep_unchecked(self) -> crate::SEXP
2242    where
2243        Self: Sized,
2244    {
2245        self.into_sexp_altrep()
2246    }
2247
2248    /// Create an `Altrep<Self>` wrapper.
2249    ///
2250    /// This returns the wrapper explicitly, allowing you to store it or
2251    /// further process it before conversion.
2252    fn into_altrep(self) -> Altrep<Self>
2253    where
2254        Self: Sized,
2255    {
2256        Altrep(self)
2257    }
2258}
2259
2260impl<T> IntoRAltrep for T
2261where
2262    T: crate::altrep::RegisterAltrep + crate::externalptr::TypedExternal,
2263{
2264    fn into_sexp_altrep(self) -> crate::SEXP {
2265        Altrep(self).into_sexp()
2266    }
2267
2268    unsafe fn into_sexp_altrep_unchecked(self) -> crate::SEXP {
2269        unsafe { Altrep(self).into_sexp_unchecked() }
2270    }
2271}
2272// endregion
2273
2274// region: Additional collection type conversions for DataFrameRow support
2275
2276/// Convert `Vec<Box<[T]>>` to an R list of vectors, for every `T` with a
2277/// `Vec<T>: IntoR` conversion. Each boxed slice becomes the R vector its
2278/// `Vec<T>` would (`into_vec()` is an O(1) widen).
2279impl<T> IntoR for Vec<Box<[T]>>
2280where
2281    Vec<T>: IntoR,
2282{
2283    type Error = <Vec<T> as IntoR>::Error;
2284    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2285        unsafe { try_vecsxp_from_iter(self.into_iter().map(|b| b.into_vec().try_into_sexp())) }
2286    }
2287    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2288        unsafe {
2289            try_vecsxp_from_iter_unchecked(
2290                self.into_iter()
2291                    .map(|b| b.into_vec().try_into_sexp_unchecked()),
2292            )
2293        }
2294    }
2295    fn into_sexp(self) -> crate::SEXP {
2296        unsafe { vecsxp_from_iter(self.into_iter().map(|b| b.into_vec().into_sexp())) }
2297    }
2298    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
2299        unsafe {
2300            vecsxp_from_iter_unchecked(self.into_iter().map(|b| b.into_vec().into_sexp_unchecked()))
2301        }
2302    }
2303}
2304
2305/// Convert `Vec<[T; N]>` to an R list of vectors, for every `T` with a
2306/// `Vec<T>: IntoR` conversion. Each array becomes the R vector its `Vec<T>`
2307/// would.
2308impl<T, const N: usize> IntoR for Vec<[T; N]>
2309where
2310    Vec<T>: IntoR,
2311{
2312    type Error = <Vec<T> as IntoR>::Error;
2313    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2314        unsafe { try_vecsxp_from_iter(self.into_iter().map(|a| Vec::from(a).try_into_sexp())) }
2315    }
2316    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2317        unsafe {
2318            try_vecsxp_from_iter_unchecked(
2319                self.into_iter()
2320                    .map(|a| Vec::from(a).try_into_sexp_unchecked()),
2321            )
2322        }
2323    }
2324    fn into_sexp(self) -> crate::SEXP {
2325        unsafe { vecsxp_from_iter(self.into_iter().map(|a| Vec::from(a).into_sexp())) }
2326    }
2327    unsafe fn into_sexp_unchecked(self) -> crate::SEXP {
2328        unsafe {
2329            vecsxp_from_iter_unchecked(self.into_iter().map(|a| Vec::from(a).into_sexp_unchecked()))
2330        }
2331    }
2332}
2333
2334/// Helper: convert a Vec of IntoR items to an R list (VECSXP).
2335fn vec_of_into_r_to_list<T: IntoR>(items: Vec<T>) -> crate::SEXP {
2336    unsafe { vecsxp_from_iter(items.into_iter().map(|item| item.into_sexp())) }
2337}
2338
2339// region: Vec<Option<Collection>> conversions
2340
2341/// Helper: convert `Vec<Option<C: IntoR>>` to a VECSXP, with `None` mapping to
2342/// `R_NilValue` (NULL) and `Some(v)` mapping to whatever `v.into_sexp()` produces.
2343fn vec_option_of_into_r_to_list<T: IntoR>(items: Vec<Option<T>>) -> crate::SEXP {
2344    unsafe {
2345        vecsxp_from_iter(items.into_iter().map(|item| match item {
2346            Some(v) => v.into_sexp(),
2347            None => crate::SEXP::nil(),
2348        }))
2349    }
2350}
2351
2352/// Convert `Vec<Option<Vec<T>>>` to an R list where `None` → NULL and
2353/// `Some(v)` → the R vector `Vec<T>` produces, for every `T` with a
2354/// `Vec<T>: IntoR` conversion.
2355impl<T> IntoR for Vec<Option<Vec<T>>>
2356where
2357    Vec<T>: IntoR,
2358{
2359    type Error = <Vec<T> as IntoR>::Error;
2360    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2361        unsafe {
2362            try_vecsxp_from_iter(self.into_iter().map(|item| match item {
2363                Some(v) => v.try_into_sexp(),
2364                None => Ok(crate::SEXP::nil()),
2365            }))
2366        }
2367    }
2368    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2369        unsafe {
2370            try_vecsxp_from_iter_unchecked(self.into_iter().map(|item| match item {
2371                Some(v) => v.try_into_sexp_unchecked(),
2372                None => Ok(crate::SEXP::nil()),
2373            }))
2374        }
2375    }
2376    fn into_sexp(self) -> crate::SEXP {
2377        vec_option_of_into_r_to_list(self)
2378    }
2379}
2380
2381/// Convert `Vec<Option<Box<[T]>>>` exactly as `Vec<Option<Vec<T>>>` (each
2382/// `into_vec()` is an O(1) widen). The enum `DataFrameRow` companion stores an
2383/// opaque `Box<[T]>` variant field in this shape.
2384impl<T> IntoR for Vec<Option<Box<[T]>>>
2385where
2386    Vec<T>: IntoR,
2387{
2388    type Error = <Vec<T> as IntoR>::Error;
2389    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2390        unsafe {
2391            try_vecsxp_from_iter(self.into_iter().map(|item| match item {
2392                Some(b) => b.into_vec().try_into_sexp(),
2393                None => Ok(crate::SEXP::nil()),
2394            }))
2395        }
2396    }
2397    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2398        unsafe {
2399            try_vecsxp_from_iter_unchecked(self.into_iter().map(|item| match item {
2400                Some(b) => b.into_vec().try_into_sexp_unchecked(),
2401                None => Ok(crate::SEXP::nil()),
2402            }))
2403        }
2404    }
2405    fn into_sexp(self) -> crate::SEXP {
2406        vec_option_of_into_r_to_list::<Vec<T>>(
2407            self.into_iter().map(|b| b.map(<[T]>::into_vec)).collect(),
2408        )
2409    }
2410}
2411
2412/// Convert `Vec<Option<HashSet<T>>>` to R list where `None` → NULL, `Some(s)` → unordered vector.
2413impl<T: crate::RNativeType + Eq + Hash> IntoR for Vec<Option<HashSet<T>>>
2414where
2415    HashSet<T>: IntoR,
2416{
2417    type Error = std::convert::Infallible;
2418    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2419        Ok(self.into_sexp())
2420    }
2421    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2422        self.try_into_sexp()
2423    }
2424    fn into_sexp(self) -> crate::SEXP {
2425        vec_option_of_into_r_to_list(self)
2426    }
2427}
2428
2429// Convert `Vec<Option<HashSet<String>>>` to R list where `None` → NULL, `Some(s)` → character vector.
2430impl crate::into_r::IntoR for Vec<Option<HashSet<String>>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        { vec_option_of_into_r_to_list(this) }
    }
}into_r_infallible!(Vec<Option<HashSet<String>>>, |this| {
2431    vec_option_of_into_r_to_list(this)
2432});
2433
2434/// Convert `Vec<Option<BTreeSet<T>>>` to R list where `None` → NULL, `Some(s)` → sorted vector.
2435impl<T: crate::RNativeType + Ord> IntoR for Vec<Option<BTreeSet<T>>>
2436where
2437    BTreeSet<T>: IntoR,
2438{
2439    type Error = std::convert::Infallible;
2440    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2441        Ok(self.into_sexp())
2442    }
2443    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2444        self.try_into_sexp()
2445    }
2446    fn into_sexp(self) -> crate::SEXP {
2447        vec_option_of_into_r_to_list(self)
2448    }
2449}
2450
2451// Convert `Vec<Option<BTreeSet<String>>>` to R list where `None` → NULL, `Some(s)` → sorted character vector.
2452impl crate::into_r::IntoR for Vec<Option<BTreeSet<String>>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        { vec_option_of_into_r_to_list(this) }
    }
}into_r_infallible!(Vec<Option<BTreeSet<String>>>, |this| {
2453    vec_option_of_into_r_to_list(this)
2454});
2455
2456/// Convert `Vec<Option<HashMap<String, V>>>` to R list where `None` → NULL, `Some(m)` → named list.
2457impl<V: IntoR> IntoR for Vec<Option<HashMap<String, V>>> {
2458    type Error = std::convert::Infallible;
2459    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2460        Ok(self.into_sexp())
2461    }
2462    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2463        self.try_into_sexp()
2464    }
2465    fn into_sexp(self) -> crate::SEXP {
2466        vec_option_of_into_r_to_list(self)
2467    }
2468}
2469
2470/// Convert `Vec<Option<BTreeMap<String, V>>>` to R list where `None` → NULL, `Some(m)` → named list.
2471impl<V: IntoR> IntoR for Vec<Option<BTreeMap<String, V>>> {
2472    type Error = std::convert::Infallible;
2473    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2474        Ok(self.into_sexp())
2475    }
2476    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2477        self.try_into_sexp()
2478    }
2479    fn into_sexp(self) -> crate::SEXP {
2480        vec_option_of_into_r_to_list(self)
2481    }
2482}
2483
2484/// Convert `Vec<Option<&[T]>>` to an R list where `None` → NULL and
2485/// `Some(s)` → the R vector `&[T]` produces, for every `T` with a
2486/// `&[T]: IntoR` conversion.
2487///
2488/// Borrowed analogue of `Vec<Option<Vec<T>>>` — each slice is copied into a fresh R vector.
2489impl<'a, T> IntoR for Vec<Option<&'a [T]>>
2490where
2491    &'a [T]: IntoR,
2492{
2493    type Error = <&'a [T] as IntoR>::Error;
2494    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2495        unsafe {
2496            try_vecsxp_from_iter(self.into_iter().map(|item| match item {
2497                Some(v) => v.try_into_sexp(),
2498                None => Ok(crate::SEXP::nil()),
2499            }))
2500        }
2501    }
2502    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2503        unsafe {
2504            try_vecsxp_from_iter_unchecked(self.into_iter().map(|item| match item {
2505                Some(v) => v.try_into_sexp_unchecked(),
2506                None => Ok(crate::SEXP::nil()),
2507            }))
2508        }
2509    }
2510    fn into_sexp(self) -> crate::SEXP {
2511        vec_option_of_into_r_to_list(self)
2512    }
2513}
2514
2515// endregion
2516
2517/// Convert `Vec<HashSet<T>>` to R list of vectors (for RNativeType elements).
2518/// Each HashSet becomes an R vector (unordered).
2519impl<T: crate::RNativeType> IntoR for Vec<std::collections::HashSet<T>>
2520where
2521    Vec<T>: IntoR,
2522{
2523    type Error = std::convert::Infallible;
2524    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2525        Ok(self.into_sexp())
2526    }
2527    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2528        self.try_into_sexp()
2529    }
2530    fn into_sexp(self) -> crate::SEXP {
2531        let converted: Vec<Vec<T>> = self.into_iter().map(|s| s.into_iter().collect()).collect();
2532        vec_of_into_r_to_list(converted)
2533    }
2534}
2535
2536/// Convert `Vec<BTreeSet<T>>` to R list of vectors (for RNativeType elements).
2537/// Each BTreeSet becomes an R vector (sorted).
2538impl<T: crate::RNativeType> IntoR for Vec<std::collections::BTreeSet<T>>
2539where
2540    Vec<T>: IntoR,
2541{
2542    type Error = std::convert::Infallible;
2543    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2544        Ok(self.into_sexp())
2545    }
2546    unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2547        self.try_into_sexp()
2548    }
2549    fn into_sexp(self) -> crate::SEXP {
2550        let converted: Vec<Vec<T>> = self.into_iter().map(|s| s.into_iter().collect()).collect();
2551        vec_of_into_r_to_list(converted)
2552    }
2553}
2554
2555// Convert `Vec<HashSet<String>>` to R list of character vectors.
2556impl crate::into_r::IntoR for Vec<std::collections::HashSet<String>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        {
            let converted: Vec<Vec<String>> =
                this.into_iter().map(|s| s.into_iter().collect()).collect();
            vec_of_into_r_to_list(converted)
        }
    }
}into_r_infallible!(Vec<std::collections::HashSet<String>>, |this| {
2557    let converted: Vec<Vec<String>> = this.into_iter().map(|s| s.into_iter().collect()).collect();
2558    vec_of_into_r_to_list(converted)
2559});
2560
2561// Convert `Vec<BTreeSet<String>>` to R list of character vectors.
2562impl crate::into_r::IntoR for Vec<std::collections::BTreeSet<String>> {
    type Error = ::std::convert::Infallible;
    #[inline]
    fn try_into_sexp(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        ::core::result::Result::Ok(self.into_sexp())
    }
    #[inline]
    unsafe fn try_into_sexp_unchecked(self)
        -> ::core::result::Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    #[inline]
    fn into_sexp(self) -> crate::SEXP {
        let this = self;
        {
            let converted: Vec<Vec<String>> =
                this.into_iter().map(|s| s.into_iter().collect()).collect();
            vec_of_into_r_to_list(converted)
        }
    }
}into_r_infallible!(Vec<std::collections::BTreeSet<String>>, |this| {
2563    let converted: Vec<Vec<String>> = this.into_iter().map(|s| s.into_iter().collect()).collect();
2564    vec_of_into_r_to_list(converted)
2565});
2566
2567macro_rules! impl_vec_map_into_r {
2568    ($(#[$meta:meta])* $map_ty:ident) => {
2569        $(#[$meta])*
2570        impl<V: IntoR> IntoR for Vec<$map_ty<String, V>> {
2571            type Error = std::convert::Infallible;
2572            fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
2573                Ok(self.into_sexp())
2574            }
2575            unsafe fn try_into_sexp_unchecked(self) -> Result<crate::SEXP, Self::Error> {
2576                self.try_into_sexp()
2577            }
2578            fn into_sexp(self) -> crate::SEXP {
2579                vec_of_maps_to_list(self)
2580            }
2581        }
2582    };
2583}
2584
2585#[doc = r" Convert `Vec<HashMap<String, V>>` to R list of named lists."]
impl<V: IntoR> IntoR for Vec<HashMap<String, V>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP { vec_of_maps_to_list(self) }
}impl_vec_map_into_r!(
2586    /// Convert `Vec<HashMap<String, V>>` to R list of named lists.
2587    HashMap
2588);
2589#[doc = r" Convert `Vec<BTreeMap<String, V>>` to R list of named lists."]
impl<V: IntoR> IntoR for Vec<BTreeMap<String, V>> {
    type Error = std::convert::Infallible;
    fn try_into_sexp(self) -> Result<crate::SEXP, Self::Error> {
        Ok(self.into_sexp())
    }
    unsafe fn try_into_sexp_unchecked(self)
        -> Result<crate::SEXP, Self::Error> {
        self.try_into_sexp()
    }
    fn into_sexp(self) -> crate::SEXP { vec_of_maps_to_list(self) }
}impl_vec_map_into_r!(
2590    /// Convert `Vec<BTreeMap<String, V>>` to R list of named lists.
2591    BTreeMap
2592);
2593
2594/// Helper to convert a Vec of map-like types to an R list of named lists.
2595fn vec_of_maps_to_list<T: IntoR>(vec: Vec<T>) -> crate::SEXP {
2596    unsafe { vecsxp_from_iter(vec.into_iter().map(|c| c.into_sexp())) }
2597}
2598// endregion
2599
2600// region: R connections — IntoR impls (issue #175, #176)
2601
2602#[cfg(feature = "connections")]
2603mod connections_into_r {
2604    use crate::SEXP;
2605    use crate::connection::{RNullConnection, RStderr, RStdin, RStdout};
2606    use crate::into_r::IntoR;
2607
2608    // Evaluate a no-arg base function and return the resulting SEXP
2609    // (unprotected). An R error panics with R's message.
2610    //
2611    // # Safety
2612    // Must be called from the R main thread.
2613    unsafe fn eval_base_noarg(name: &str) -> SEXP {
2614        unsafe { crate::expression::RCall::new(name).eval_base() }
2615            .unwrap_or_else(|e| panic!("failed to evaluate {name}(): {e}"))
2616    }
2617
2618    impl IntoR for RStdin {
2619        type Error = std::convert::Infallible;
2620
2621        fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
2622            Ok(self.into_sexp())
2623        }
2624
2625        fn into_sexp(self) -> SEXP {
2626            unsafe { eval_base_noarg("stdin") }
2627        }
2628    }
2629
2630    impl IntoR for RStdout {
2631        type Error = std::convert::Infallible;
2632
2633        fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
2634            Ok(self.into_sexp())
2635        }
2636
2637        fn into_sexp(self) -> SEXP {
2638            unsafe { eval_base_noarg("stdout") }
2639        }
2640    }
2641
2642    impl IntoR for RStderr {
2643        type Error = std::convert::Infallible;
2644
2645        fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
2646            Ok(self.into_sexp())
2647        }
2648
2649        fn into_sexp(self) -> SEXP {
2650            unsafe { eval_base_noarg("stderr") }
2651        }
2652    }
2653
2654    /// Returns the held SEXP and disarms the `Drop` guard (no double-close).
2655    impl IntoR for RNullConnection {
2656        type Error = std::convert::Infallible;
2657
2658        fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
2659            Ok(self.into_sexp())
2660        }
2661
2662        fn into_sexp(self) -> SEXP {
2663            let sexp = self.sexp();
2664            // Transfer ownership to R: release from precious list (R's connection
2665            // table keeps the connection alive), then forget self to skip Drop.
2666            unsafe { crate::sys::R_ReleaseObject(sexp) };
2667            std::mem::forget(self);
2668            sexp
2669        }
2670    }
2671}
2672
2673// endregion
2674
2675// region: txtProgressBar — IntoR (issue #177)
2676
2677#[cfg(feature = "connections")]
2678mod txt_progress_bar_into_r {
2679    use crate::SEXP;
2680    use crate::into_r::IntoR;
2681    use crate::txt_progress_bar::RTxtProgressBar;
2682
2683    /// Transfer ownership of the `RTxtProgressBar` back to R.
2684    ///
2685    /// Releases the SEXP from the precious list and forgets `self` (so `Drop`
2686    /// is a no-op). R's environment keeps the bar alive after this call.
2687    impl IntoR for RTxtProgressBar {
2688        type Error = std::convert::Infallible;
2689
2690        fn try_into_sexp(self) -> Result<SEXP, Self::Error> {
2691            Ok(self.into_sexp())
2692        }
2693
2694        fn into_sexp(self) -> SEXP {
2695            let sexp = self.sexp();
2696            // Release from precious list; R manages lifetime from here on.
2697            unsafe { crate::sys::R_ReleaseObject(sexp) };
2698            std::mem::forget(self); // Disarm Drop guard — no double-release.
2699            sexp
2700        }
2701    }
2702}
2703
2704// endregion