Skip to main content

polars_arrow/array/primitive/
mod.rs

1use std::ops::Range;
2
3use either::Either;
4use polars_buffer::Buffer;
5use polars_utils::float16::pf16;
6
7use super::{Array, Splitable};
8use crate::array::iterator::NonNullValuesIter;
9use crate::bitmap::Bitmap;
10use crate::bitmap::utils::{BitmapIter, ZipValidity};
11use crate::datatypes::*;
12use crate::trusted_len::TrustedLen;
13use crate::types::{NativeType, days_ms, i256, months_days_ns};
14
15mod ffi;
16pub(super) mod fmt;
17mod from_natural;
18pub mod iterator;
19#[cfg(feature = "proptest")]
20pub mod proptest;
21
22mod mutable;
23pub use mutable::*;
24mod builder;
25pub use builder::*;
26use polars_error::{PolarsResult, polars_bail};
27use polars_utils::index::{Bounded, Indexable, NullCount};
28use polars_utils::slice::SliceAble;
29
30/// A [`PrimitiveArray`] is Arrow's semantically equivalent of an immutable `Vec<Option<T>>` where
31/// T is [`NativeType`] (e.g. [`i32`]). It implements [`Array`].
32///
33/// One way to think about a [`PrimitiveArray`] is `(DataType, Arc<Vec<T>>, Option<Arc<Vec<u8>>>)`
34/// where:
35/// * the first item is the array's logical type
36/// * the second is the immutable values
37/// * the third is the immutable validity (whether a value is null or not as a bitmap).
38///
39/// The size of this struct is `O(1)`, as all data is stored behind an [`std::sync::Arc`].
40/// # Example
41/// ```
42/// use polars_arrow::array::PrimitiveArray;
43/// use polars_arrow::bitmap::Bitmap;
44/// use polars_buffer::Buffer;
45///
46/// let array = PrimitiveArray::from([Some(1i32), None, Some(10)]);
47/// assert_eq!(array.value(0), 1);
48/// assert_eq!(array.iter().collect::<Vec<_>>(), vec![Some(&1i32), None, Some(&10)]);
49/// assert_eq!(array.values_iter().copied().collect::<Vec<_>>(), vec![1, 0, 10]);
50/// // the underlying representation
51/// assert_eq!(array.values(), &Buffer::from(vec![1i32, 0, 10]));
52/// assert_eq!(array.validity(), Some(&Bitmap::from([true, false, true])));
53///
54/// ```
55#[derive(Clone)]
56pub struct PrimitiveArray<T: NativeType> {
57    dtype: ArrowDataType,
58    values: Buffer<T>,
59    validity: Option<Bitmap>,
60}
61
62pub(super) fn check<T: NativeType>(
63    dtype: &ArrowDataType,
64    values: &[T],
65    validity_len: Option<usize>,
66) -> PolarsResult<()> {
67    if validity_len.is_some_and(|len| len != values.len()) {
68        polars_bail!(ComputeError: "validity mask length must match the number of values")
69    }
70
71    if dtype.to_physical_type() != PhysicalType::Primitive(T::PRIMITIVE) {
72        polars_bail!(ComputeError: "PrimitiveArray can only be initialized with a DataType whose physical type is Primitive")
73    }
74    Ok(())
75}
76
77impl<T: NativeType> PrimitiveArray<T> {
78    /// The canonical method to create a [`PrimitiveArray`] out of its internal components.
79    /// # Implementation
80    /// This function is `O(1)`.
81    ///
82    /// # Errors
83    /// This function errors iff:
84    /// * The validity is not `None` and its length is different from `values`'s length
85    /// * The `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive(T::PRIMITIVE)`]
86    pub fn try_new(
87        dtype: ArrowDataType,
88        values: Buffer<T>,
89        validity: Option<Bitmap>,
90    ) -> PolarsResult<Self> {
91        check(&dtype, &values, validity.as_ref().map(|v| v.len()))?;
92        Ok(Self {
93            dtype,
94            values,
95            validity,
96        })
97    }
98
99    /// # Safety
100    /// Doesn't check invariants
101    pub unsafe fn new_unchecked(
102        dtype: ArrowDataType,
103        values: Buffer<T>,
104        validity: Option<Bitmap>,
105    ) -> Self {
106        if cfg!(debug_assertions) {
107            check(&dtype, &values, validity.as_ref().map(|v| v.len())).unwrap();
108        }
109
110        Self {
111            dtype,
112            values,
113            validity,
114        }
115    }
116
117    /// Returns a new [`PrimitiveArray`] with a different logical type.
118    ///
119    /// This function is useful to assign a different [`ArrowDataType`] to the array.
120    /// Used to change the arrays' logical type (see example).
121    /// # Example
122    /// ```
123    /// use polars_arrow::array::Int32Array;
124    /// use polars_arrow::datatypes::ArrowDataType;
125    ///
126    /// let array = Int32Array::from(&[Some(1), None, Some(2)]).to(ArrowDataType::Date32);
127    /// assert_eq!(
128    ///    format!("{:?}", array),
129    ///    "Date32[1970-01-02, None, 1970-01-03]"
130    /// );
131    /// ```
132    /// # Panics
133    /// Panics iff the `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive(T::PRIMITIVE)`]
134    #[inline]
135    #[must_use]
136    pub fn to(self, dtype: ArrowDataType) -> Self {
137        check(
138            &dtype,
139            &self.values,
140            self.validity.as_ref().map(|v| v.len()),
141        )
142        .unwrap();
143        Self {
144            dtype,
145            values: self.values,
146            validity: self.validity,
147        }
148    }
149
150    /// Creates a (non-null) [`PrimitiveArray`] from a vector of values.
151    /// This function is `O(1)`.
152    /// # Examples
153    /// ```
154    /// use polars_arrow::array::PrimitiveArray;
155    ///
156    /// let array = PrimitiveArray::from_vec(vec![1, 2, 3]);
157    /// assert_eq!(format!("{:?}", array), "Int32[1, 2, 3]");
158    /// ```
159    pub fn from_vec(values: Vec<T>) -> Self {
160        Self::new(T::PRIMITIVE.into(), values.into(), None)
161    }
162
163    /// Returns an iterator over the values and validity, `Option<&T>`.
164    #[inline]
165    pub fn iter(&self) -> ZipValidity<&T, std::slice::Iter<'_, T>, BitmapIter<'_>> {
166        ZipValidity::new_with_validity(self.values().iter(), self.validity())
167    }
168
169    /// Returns an iterator of the values, `&T`, ignoring the arrays' validity.
170    #[inline]
171    pub fn values_iter(&self) -> std::slice::Iter<'_, T> {
172        self.values().iter()
173    }
174
175    /// Returns an iterator of the non-null values `T`.
176    #[inline]
177    pub fn non_null_values_iter(&self) -> NonNullValuesIter<'_, [T]> {
178        NonNullValuesIter::new(self.values(), self.validity())
179    }
180
181    /// Returns the length of this array
182    #[inline]
183    pub fn len(&self) -> usize {
184        self.values.len()
185    }
186
187    /// The values [`Buffer`].
188    /// Values on null slots are undetermined (they can be anything).
189    #[inline]
190    pub fn values(&self) -> &Buffer<T> {
191        &self.values
192    }
193
194    /// Returns the optional validity.
195    #[inline]
196    pub fn validity(&self) -> Option<&Bitmap> {
197        self.validity.as_ref()
198    }
199
200    /// Returns the arrays' [`ArrowDataType`].
201    #[inline]
202    pub fn dtype(&self) -> &ArrowDataType {
203        &self.dtype
204    }
205
206    /// Returns the value at slot `i`.
207    ///
208    /// Equivalent to `self.values()[i]`. The value of a null slot is undetermined (it can be anything).
209    /// # Panic
210    /// This function panics iff `i >= self.len`.
211    #[inline]
212    pub fn value(&self, i: usize) -> T {
213        self.values[i]
214    }
215
216    /// Returns the value at index `i`.
217    /// The value on null slots is undetermined (it can be anything).
218    ///
219    /// # Safety
220    /// Caller must be sure that `i < self.len()`
221    #[inline]
222    pub unsafe fn value_unchecked(&self, i: usize) -> T {
223        *self.values.get_unchecked(i)
224    }
225
226    // /// Returns the element at index `i` or `None` if it is null
227    // /// # Panics
228    // /// iff `i >= self.len()`
229    // #[inline]
230    // pub fn get(&self, i: usize) -> Option<T> {
231    //     if !self.is_null(i) {
232    //         // soundness: Array::is_null panics if i >= self.len
233    //         unsafe { Some(self.value_unchecked(i)) }
234    //     } else {
235    //         None
236    //     }
237    // }
238
239    /// Slices this [`PrimitiveArray`] by an offset and length.
240    /// # Implementation
241    /// This operation is `O(1)`.
242    #[inline]
243    pub fn slice(&mut self, offset: usize, length: usize) {
244        assert!(
245            offset + length <= self.len(),
246            "offset + length may not exceed length of array"
247        );
248        unsafe { self.slice_unchecked(offset, length) }
249    }
250
251    /// Slices this [`PrimitiveArray`] by an offset and length.
252    /// # Implementation
253    /// This operation is `O(1)`.
254    ///
255    /// # Safety
256    /// The caller must ensure that `offset + length <= self.len()`.
257    #[inline]
258    pub unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
259        self.validity = self
260            .validity
261            .take()
262            .map(|bitmap| bitmap.sliced_unchecked(offset, length))
263            .filter(|bitmap| bitmap.unset_bits() > 0);
264        self.values
265            .slice_in_place_unchecked(offset..offset + length);
266    }
267
268    impl_sliced!();
269    impl_mut_validity!();
270    impl_into_array!();
271
272    /// Returns this [`PrimitiveArray`] with new values.
273    /// # Panics
274    /// This function panics iff `values.len() != self.len()`.
275    #[must_use]
276    pub fn with_values(mut self, values: Buffer<T>) -> Self {
277        self.set_values(values);
278        self
279    }
280
281    /// Update the values of this [`PrimitiveArray`].
282    /// # Panics
283    /// This function panics iff `values.len() != self.len()`.
284    pub fn set_values(&mut self, values: Buffer<T>) {
285        assert_eq!(
286            values.len(),
287            self.len(),
288            "values' length must be equal to this arrays' length"
289        );
290        self.values = values;
291    }
292
293    /// Applies a function `f` to the validity of this array.
294    ///
295    /// # Panics
296    /// This function panics if the function `f` modifies the length of the [`Bitmap`].
297    pub fn apply_validity<F: FnOnce(Bitmap) -> Bitmap>(&mut self, f: F) {
298        if let Some(validity) = std::mem::take(&mut self.validity) {
299            self.set_validity(Some(f(validity)))
300        }
301    }
302
303    /// Applies a function `f` to the values of this array, ignoring validity,
304    /// in-place if possible.
305    pub fn with_values_mut<F: FnOnce(&mut [T])>(&mut self, f: F) {
306        if let Some(slice) = self.values.get_mut_slice() {
307            f(slice)
308        } else {
309            let mut values = self.values.as_slice().to_vec();
310            f(&mut values);
311            self.values = Buffer::from(values);
312        }
313    }
314
315    /// Returns an option of a mutable reference to the values of this [`PrimitiveArray`].
316    pub fn get_mut_values(&mut self) -> Option<&mut [T]> {
317        self.values.get_mut_slice()
318    }
319
320    /// Returns its internal representation
321    #[must_use]
322    pub fn into_inner(self) -> (ArrowDataType, Buffer<T>, Option<Bitmap>) {
323        let Self {
324            dtype,
325            values,
326            validity,
327        } = self;
328        (dtype, values, validity)
329    }
330
331    /// Creates a [`PrimitiveArray`] from its internal representation.
332    /// This is the inverted from [`PrimitiveArray::into_inner`]
333    pub fn from_inner(
334        dtype: ArrowDataType,
335        values: Buffer<T>,
336        validity: Option<Bitmap>,
337    ) -> PolarsResult<Self> {
338        check(&dtype, &values, validity.as_ref().map(|v| v.len()))?;
339        Ok(unsafe { Self::from_inner_unchecked(dtype, values, validity) })
340    }
341
342    /// Creates a [`PrimitiveArray`] from its internal representation.
343    /// This is the inverted from [`PrimitiveArray::into_inner`]
344    ///
345    /// # Safety
346    /// Callers must ensure all invariants of this struct are upheld.
347    pub unsafe fn from_inner_unchecked(
348        dtype: ArrowDataType,
349        values: Buffer<T>,
350        validity: Option<Bitmap>,
351    ) -> Self {
352        Self {
353            dtype,
354            values,
355            validity,
356        }
357    }
358
359    /// Try to convert this [`PrimitiveArray`] to a [`MutablePrimitiveArray`] via copy-on-write semantics.
360    ///
361    /// A [`PrimitiveArray`] is backed by a [`Buffer`] and [`Bitmap`] which are essentially `Arc<Vec<_>>`.
362    /// This function returns a [`MutablePrimitiveArray`] (via [`std::sync::Arc::get_mut`]) iff both values
363    /// and validity have not been cloned / are unique references to their underlying vectors.
364    ///
365    /// This function is primarily used to reuse memory regions.
366    #[must_use]
367    pub fn into_mut(self) -> Either<Self, MutablePrimitiveArray<T>> {
368        use Either::*;
369
370        if let Some(bitmap) = self.validity {
371            match bitmap.into_mut() {
372                Left(bitmap) => Left(PrimitiveArray::new(self.dtype, self.values, Some(bitmap))),
373                Right(mutable_bitmap) => match self.values.into_mut() {
374                    Right(values) => Right(
375                        MutablePrimitiveArray::try_new(self.dtype, values, Some(mutable_bitmap))
376                            .unwrap(),
377                    ),
378                    Left(values) => Left(PrimitiveArray::new(
379                        self.dtype,
380                        values,
381                        Some(mutable_bitmap.into()),
382                    )),
383                },
384            }
385        } else {
386            match self.values.into_mut() {
387                Right(values) => {
388                    Right(MutablePrimitiveArray::try_new(self.dtype, values, None).unwrap())
389                },
390                Left(values) => Left(PrimitiveArray::new(self.dtype, values, None)),
391            }
392        }
393    }
394
395    /// Returns a new empty (zero-length) [`PrimitiveArray`].
396    pub fn new_empty(dtype: ArrowDataType) -> Self {
397        Self::new(dtype, Buffer::new(), None)
398    }
399
400    /// Returns a new [`PrimitiveArray`] where all slots are null / `None`.
401    #[inline]
402    pub fn new_null(dtype: ArrowDataType, length: usize) -> Self {
403        Self::new(
404            dtype,
405            vec![T::default(); length].into(),
406            Some(Bitmap::new_zeroed(length)),
407        )
408    }
409
410    /// Creates a (non-null) [`PrimitiveArray`] from an iterator of values.
411    /// # Implementation
412    /// This does not assume that the iterator has a known length.
413    pub fn from_values<I: IntoIterator<Item = T>>(iter: I) -> Self {
414        Self::new(T::PRIMITIVE.into(), Vec::<T>::from_iter(iter).into(), None)
415    }
416
417    /// Creates a (non-null) [`PrimitiveArray`] from a slice of values.
418    /// # Implementation
419    /// This is essentially a memcopy and is thus `O(N)`
420    pub fn from_slice<P: AsRef<[T]>>(slice: P) -> Self {
421        Self::new(
422            T::PRIMITIVE.into(),
423            Vec::<T>::from(slice.as_ref()).into(),
424            None,
425        )
426    }
427
428    /// Calls f with a [`PrimitiveArray`] backed by this slice.
429    ///
430    /// Aborts if any clones of the [`PrimitiveArray`] still live when `f` returns.
431    pub fn with_slice<R, F: FnOnce(PrimitiveArray<T>) -> R>(slice: &[T], f: F) -> R {
432        Buffer::with_slice(slice, |buf| f(Self::new(T::PRIMITIVE.into(), buf, None)))
433    }
434
435    /// Creates a (non-null) [`PrimitiveArray`] from a [`TrustedLen`] of values.
436    /// # Implementation
437    /// This does not assume that the iterator has a known length.
438    pub fn from_trusted_len_values_iter<I: TrustedLen<Item = T>>(iter: I) -> Self {
439        MutablePrimitiveArray::<T>::from_trusted_len_values_iter(iter).into()
440    }
441
442    /// Creates a new [`PrimitiveArray`] from an iterator over values
443    ///
444    /// # Safety
445    /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
446    /// I.e. that `size_hint().1` correctly reports its length.
447    pub unsafe fn from_trusted_len_values_iter_unchecked<I: Iterator<Item = T>>(iter: I) -> Self {
448        MutablePrimitiveArray::<T>::from_trusted_len_values_iter_unchecked(iter).into()
449    }
450
451    /// Creates a [`PrimitiveArray`] from a [`TrustedLen`] of optional values.
452    pub fn from_trusted_len_iter<I: TrustedLen<Item = Option<T>>>(iter: I) -> Self {
453        MutablePrimitiveArray::<T>::from_trusted_len_iter(iter).into()
454    }
455
456    /// Creates a [`PrimitiveArray`] from an iterator of optional values.
457    ///
458    /// # Safety
459    /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
460    /// I.e. that `size_hint().1` correctly reports its length.
461    pub unsafe fn from_trusted_len_iter_unchecked<I: Iterator<Item = Option<T>>>(iter: I) -> Self {
462        MutablePrimitiveArray::<T>::from_trusted_len_iter_unchecked(iter).into()
463    }
464
465    /// Alias for `Self::try_new(..).unwrap()`.
466    /// # Panics
467    /// This function errors iff:
468    /// * The validity is not `None` and its length is different from `values`'s length
469    /// * The `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive`].
470    pub fn new(dtype: ArrowDataType, values: Buffer<T>, validity: Option<Bitmap>) -> Self {
471        Self::try_new(dtype, values, validity).unwrap()
472    }
473
474    /// Transmute this PrimitiveArray into another PrimitiveArray.
475    ///
476    /// T and U must have the same size and alignment.
477    pub fn transmute<U: NativeType>(self) -> PrimitiveArray<U> {
478        let PrimitiveArray {
479            values, validity, ..
480        } = self;
481        PrimitiveArray::new(
482            U::PRIMITIVE.into(),
483            Buffer::try_transmute::<U>(values).unwrap(),
484            validity,
485        )
486    }
487
488    /// Fills this entire array with the given value, leaving the validity mask intact.
489    ///
490    /// Reuses the memory of the PrimitiveArray if possible.
491    pub fn fill_with(mut self, value: T) -> Self {
492        if let Some(values) = self.get_mut_values() {
493            for x in values.iter_mut() {
494                *x = value;
495            }
496            self
497        } else {
498            let values = vec![value; self.len()];
499            Self::new(T::PRIMITIVE.into(), values.into(), self.validity)
500        }
501    }
502}
503
504impl<T: NativeType> Array for PrimitiveArray<T> {
505    impl_common_array!();
506
507    fn validity(&self) -> Option<&Bitmap> {
508        self.validity.as_ref()
509    }
510
511    #[inline]
512    fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
513        Box::new(self.clone().with_validity(validity))
514    }
515}
516
517impl<T: NativeType> Splitable for PrimitiveArray<T> {
518    #[inline(always)]
519    fn check_bound(&self, offset: usize) -> bool {
520        offset <= self.len()
521    }
522
523    unsafe fn _split_at_unchecked(&self, offset: usize) -> (Self, Self) {
524        let (lhs_values, rhs_values) = unsafe { self.values.split_at_unchecked(offset) };
525        let (lhs_validity, rhs_validity) = unsafe { self.validity.split_at_unchecked(offset) };
526
527        (
528            Self {
529                dtype: self.dtype.clone(),
530                values: lhs_values,
531                validity: lhs_validity,
532            },
533            Self {
534                dtype: self.dtype.clone(),
535                values: rhs_values,
536                validity: rhs_validity,
537            },
538        )
539    }
540}
541
542impl<T: NativeType> SliceAble for PrimitiveArray<T> {
543    unsafe fn slice_unchecked(&self, range: Range<usize>) -> Self {
544        self.clone().sliced_unchecked(range.start, range.len())
545    }
546
547    fn slice(&self, range: Range<usize>) -> Self {
548        self.clone().sliced(range.start, range.len())
549    }
550}
551
552impl<T: NativeType> Indexable for PrimitiveArray<T> {
553    type Item = Option<T>;
554
555    fn get(&self, i: usize) -> Self::Item {
556        if !self.is_null(i) {
557            // soundness: Array::is_null panics if i >= self.len
558            unsafe { Some(self.value_unchecked(i)) }
559        } else {
560            None
561        }
562    }
563
564    unsafe fn get_unchecked(&self, i: usize) -> Self::Item {
565        if !self.is_null_unchecked(i) {
566            Some(self.value_unchecked(i))
567        } else {
568            None
569        }
570    }
571}
572
573/// A type definition [`PrimitiveArray`] for `i8`
574pub type Int8Array = PrimitiveArray<i8>;
575/// A type definition [`PrimitiveArray`] for `i16`
576pub type Int16Array = PrimitiveArray<i16>;
577/// A type definition [`PrimitiveArray`] for `i32`
578pub type Int32Array = PrimitiveArray<i32>;
579/// A type definition [`PrimitiveArray`] for `i64`
580pub type Int64Array = PrimitiveArray<i64>;
581/// A type definition [`PrimitiveArray`] for `i128`
582pub type Int128Array = PrimitiveArray<i128>;
583/// A type definition [`PrimitiveArray`] for `i256`
584pub type Int256Array = PrimitiveArray<i256>;
585/// A type definition [`PrimitiveArray`] for [`days_ms`]
586pub type DaysMsArray = PrimitiveArray<days_ms>;
587/// A type definition [`PrimitiveArray`] for [`months_days_ns`]
588pub type MonthsDaysNsArray = PrimitiveArray<months_days_ns>;
589/// A type definition [`PrimitiveArray`] for `f16`
590pub type Float16Array = PrimitiveArray<pf16>;
591/// A type definition [`PrimitiveArray`] for `f32`
592pub type Float32Array = PrimitiveArray<f32>;
593/// A type definition [`PrimitiveArray`] for `f64`
594pub type Float64Array = PrimitiveArray<f64>;
595/// A type definition [`PrimitiveArray`] for `u8`
596pub type UInt8Array = PrimitiveArray<u8>;
597/// A type definition [`PrimitiveArray`] for `u16`
598pub type UInt16Array = PrimitiveArray<u16>;
599/// A type definition [`PrimitiveArray`] for `u32`
600pub type UInt32Array = PrimitiveArray<u32>;
601/// A type definition [`PrimitiveArray`] for `u64`
602pub type UInt64Array = PrimitiveArray<u64>;
603/// A type definition [`PrimitiveArray`] for `u128`
604pub type UInt128Array = PrimitiveArray<u128>;
605
606/// A type definition [`MutablePrimitiveArray`] for `i8`
607pub type Int8Vec = MutablePrimitiveArray<i8>;
608/// A type definition [`MutablePrimitiveArray`] for `i16`
609pub type Int16Vec = MutablePrimitiveArray<i16>;
610/// A type definition [`MutablePrimitiveArray`] for `i32`
611pub type Int32Vec = MutablePrimitiveArray<i32>;
612/// A type definition [`MutablePrimitiveArray`] for `i64`
613pub type Int64Vec = MutablePrimitiveArray<i64>;
614/// A type definition [`MutablePrimitiveArray`] for `i128`
615pub type Int128Vec = MutablePrimitiveArray<i128>;
616/// A type definition [`MutablePrimitiveArray`] for `i256`
617pub type Int256Vec = MutablePrimitiveArray<i256>;
618/// A type definition [`MutablePrimitiveArray`] for [`days_ms`]
619pub type DaysMsVec = MutablePrimitiveArray<days_ms>;
620/// A type definition [`MutablePrimitiveArray`] for [`months_days_ns`]
621pub type MonthsDaysNsVec = MutablePrimitiveArray<months_days_ns>;
622/// A type definition [`MutablePrimitiveArray`] for `f16`
623pub type Float16Vec = MutablePrimitiveArray<pf16>;
624/// A type definition [`MutablePrimitiveArray`] for `f32`
625pub type Float32Vec = MutablePrimitiveArray<f32>;
626/// A type definition [`MutablePrimitiveArray`] for `f64`
627pub type Float64Vec = MutablePrimitiveArray<f64>;
628/// A type definition [`MutablePrimitiveArray`] for `u8`
629pub type UInt8Vec = MutablePrimitiveArray<u8>;
630/// A type definition [`MutablePrimitiveArray`] for `u16`
631pub type UInt16Vec = MutablePrimitiveArray<u16>;
632/// A type definition [`MutablePrimitiveArray`] for `u32`
633pub type UInt32Vec = MutablePrimitiveArray<u32>;
634/// A type definition [`MutablePrimitiveArray`] for `u64`
635pub type UInt64Vec = MutablePrimitiveArray<u64>;
636/// A type definition [`MutablePrimitiveArray`] for `u128`
637pub type UInt128Vec = MutablePrimitiveArray<u128>;
638
639impl<T: NativeType> Default for PrimitiveArray<T> {
640    fn default() -> Self {
641        PrimitiveArray::new(T::PRIMITIVE.into(), Default::default(), None)
642    }
643}
644
645impl<T: NativeType> Bounded for PrimitiveArray<T> {
646    fn len(&self) -> usize {
647        self.values.len()
648    }
649}
650
651impl<T: NativeType> NullCount for PrimitiveArray<T> {
652    fn null_count(&self) -> usize {
653        <Self as Array>::null_count(self)
654    }
655}