Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/zerovec/src/flexzerovec/   (Fast Lexical Analyzer Version 2.6©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  owned.rs

  Sprache: Rust
 

// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use alloc::vec;
use alloc::vec::Vec;
use core::fmt;
use core::iter::FromIterator;
use core::ops::Deref;

use super::FlexZeroSlice;
use super::FlexZeroVec;

/// The fully-owned variant of [`FlexZeroVec`]. Contains all mutation methods.
// Safety invariant: the inner bytes must deref to a valid `FlexZeroSlice`
#[derive(Clone, PartialEq, Eq)]
pub struct FlexZeroVecOwned(Vec<u8>);

impl FlexZeroVecOwned {
    /// Creates a new [`FlexZeroVecOwned`] with zero elements.
    pub fn new_empty() -> Self {
        Self(vec![1])
    }

    /// Creates a [`FlexZeroVecOwned`] from a [`FlexZeroSlice`].
    pub fn from_slice(other: &FlexZeroSlice) -> FlexZeroVecOwned {
        // safety: the bytes originate from a valid FlexZeroSlice
        Self(other.as_bytes().to_vec())
    }

    /// Obtains this [`FlexZeroVecOwned`] as a [`FlexZeroSlice`].
    pub fn as_slice(&self) -> &FlexZeroSlice {
        let slice: &[u8] = &self.0;
        unsafe {
            // safety: the slice is known to come from a valid parsed FlexZeroSlice
            FlexZeroSlice::from_byte_slice_unchecked(slice)
        }
    }

    /// Mutably obtains this `FlexZeroVecOwned` as a [`FlexZeroSlice`].
    pub(cratefn as_mut_slice(&mut self) -> &mut FlexZeroSlice {
        let slice: &mut [u8] = &mut self.0;
        unsafe {
            // safety: the slice is known to come from a valid parsed FlexZeroSlice
            FlexZeroSlice::from_byte_slice_mut_unchecked(slice)
        }
    }

    /// Converts this `FlexZeroVecOwned` into a [`FlexZeroVec::Owned`].
    #[inline]
    pub fn into_flexzerovec(self) -> FlexZeroVec<'static> {
        FlexZeroVec::Owned(self)
    }

    /// Clears all values out of this `FlexZeroVecOwned`.
    #[inline]
    pub fn clear(&mut self) {
        *self = Self::new_empty()
    }

    /// Appends an item to the end of the vector.
    ///
    /// # Panics
    ///
    /// Panics if inserting the element would require allocating more than `usize::MAX` bytes.
    ///
    /// # Examples
    ///
    /// ```
    /// use zerovec::vecs::FlexZeroVec;
    ///
    /// let mut zv: FlexZeroVec = [22, 44, 66].iter().copied().collect();
    /// zv.to_mut().push(33);
    /// assert_eq!(zv.to_vec(), vec![22, 44, 66, 33]);
    /// ```
    pub fn push(&mut self, item: usize) {
        let insert_info = self.get_insert_info(item);
        self.0.resize(insert_info.new_bytes_len, 0);
        let insert_index = insert_info.new_count - 1;
        self.as_mut_slice().insert_impl(insert_info, insert_index);
    }

    /// Inserts an element into the middle of the vector.
    ///
    /// Caution: Both arguments to this function are of type `usize`. Please be careful to pass
    /// the index first followed by the value second.
    ///
    /// # Panics
    ///
    /// Panics if `index > len`.
    ///
    /// Panics if inserting the element would require allocating more than `usize::MAX` bytes.
    ///
    /// # Examples
    ///
    /// ```
    /// use zerovec::vecs::FlexZeroVec;
    ///
    /// let mut zv: FlexZeroVec = [22, 44, 66].iter().copied().collect();
    /// zv.to_mut().insert(2, 33);
    /// assert_eq!(zv.to_vec(), vec![22, 44, 33, 66]);
    /// ```
    pub fn insert(&mut self, index: usize, item: usize) {
        #[allow(clippy::panic)] // panic is documented in function contract
        if index > self.len() {
            panic!("index {} out of range {}", index, self.len());
        }
        let insert_info = self.get_insert_info(item);
        self.0.resize(insert_info.new_bytes_len, 0);
        self.as_mut_slice().insert_impl(insert_info, index);
    }

    /// Inserts an element into an ascending sorted vector
    /// at a position that keeps the vector sorted.
    ///
    /// # Panics
    ///
    /// Panics if inserting the element would require allocating more than `usize::MAX` bytes.
    ///
    /// # Examples
    ///
    /// ```
    /// use zerovec::vecs::FlexZeroVecOwned;
    ///
    /// let mut fzv = FlexZeroVecOwned::new_empty();
    /// fzv.insert_sorted(10);
    /// fzv.insert_sorted(5);
    /// fzv.insert_sorted(8);
    ///
    /// assert!(Iterator::eq(fzv.iter(), [5, 8, 10].iter().copied()));
    /// ```
    pub fn insert_sorted(&mut self, item: usize) {
        let index = match self.binary_search(item) {
            Ok(i) => i,
            Err(i) => i,
        };
        let insert_info = self.get_insert_info(item);
        self.0.resize(insert_info.new_bytes_len, 0);
        self.as_mut_slice().insert_impl(insert_info, index);
    }

    /// Removes and returns the element at the specified index.
    ///
    /// # Panics
    ///
    /// Panics if `index >= len`.
    ///
    /// # Examples
    ///
    /// ```
    /// use zerovec::vecs::FlexZeroVec;
    ///
    /// let mut zv: FlexZeroVec = [22, 44, 66].iter().copied().collect();
    /// let removed_item = zv.to_mut().remove(1);
    /// assert_eq!(44, removed_item);
    /// assert_eq!(zv.to_vec(), vec![22, 66]);
    /// ```
    pub fn remove(&mut self, index: usize) -> usize {
        #[allow(clippy::panic)] // panic is documented in function contract
        if index >= self.len() {
            panic!("index {} out of range {}", index, self.len());
        }
        let remove_info = self.get_remove_info(index);
        // Safety: `remove_index` is a valid index
        let item = unsafe { self.get_unchecked(remove_info.remove_index) };
        let new_bytes_len = remove_info.new_bytes_len;
        self.as_mut_slice().remove_impl(remove_info);
        self.0.truncate(new_bytes_len);
        item
    }

    /// Removes and returns the last element from an ascending sorted vector.
    ///
    /// If the vector is not sorted, use [`FlexZeroVecOwned::remove()`] instead. Calling this
    /// function would leave the FlexZeroVec in a safe, well-defined state; however, information
    /// may be lost and/or the equality invariant might not hold.
    ///
    /// # Panics
    ///
    /// Panics if `self.is_empty()`.
    ///
    /// # Examples
    ///
    /// ```
    /// use zerovec::vecs::FlexZeroVec;
    ///
    /// let mut zv: FlexZeroVec = [22, 44, 66].iter().copied().collect();
    /// let popped_item = zv.to_mut().pop_sorted();
    /// assert_eq!(66, popped_item);
    /// assert_eq!(zv.to_vec(), vec![22, 44]);
    /// ```
    ///
    /// Calling this function on a non-ascending vector could cause surprising results:
    ///
    /// ```
    /// use zerovec::vecs::FlexZeroVec;
    ///
    /// let mut zv1: FlexZeroVec = [444, 222, 111].iter().copied().collect();
    /// let popped_item = zv1.to_mut().pop_sorted();
    /// assert_eq!(111, popped_item);
    ///
    /// // Oops!
    /// assert_eq!(zv1.to_vec(), vec![188, 222]);
    /// ```
    pub fn pop_sorted(&mut self) -> usize {
        #[allow(clippy::panic)] // panic is documented in function contract
        if self.is_empty() {
            panic!("cannot pop from an empty vector");
        }
        let remove_info = self.get_sorted_pop_info();
        // Safety: `remove_index` is a valid index
        let item = unsafe { self.get_unchecked(remove_info.remove_index) };
        let new_bytes_len = remove_info.new_bytes_len;
        self.as_mut_slice().remove_impl(remove_info);
        self.0.truncate(new_bytes_len);
        item
    }
}

impl Deref for FlexZeroVecOwned {
    type Target = FlexZeroSlice;
    fn deref(&self) -> &Self::Target {
        self.as_slice()
    }
}

impl fmt::Debug for FlexZeroVecOwned {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}"self.to_vec())
    }
}

impl From<&FlexZeroSlice> for FlexZeroVecOwned {
    fn from(other: &FlexZeroSlice) -> Self {
        Self::from_slice(other)
    }
}

impl FromIterator<usize> for FlexZeroVecOwned {
    /// Creates a [`FlexZeroVecOwned`] from an iterator of `usize`.
    fn from_iter<I>(iter: I) -> Self
    where
        I: IntoIterator<Item = usize>,
    {
        let mut result = FlexZeroVecOwned::new_empty();
        for item in iter {
            result.push(item);
        }
        result
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn check_contents(fzv: &FlexZeroSlice, expected: &[usize]) {
        assert_eq!(fzv.len(), expected.len(), "len: {fzv:?} != {expected:?}");
        assert_eq!(
            fzv.is_empty(),
            expected.is_empty(),
            "is_empty: {fzv:?} != {expected:?}"
        );
        assert_eq!(
            fzv.first(),
            expected.first().copied(),
            "first: {fzv:?} != {expected:?}"
        );
        assert_eq!(
            fzv.last(),
            expected.last().copied(),
            "last:  {fzv:?} != {expected:?}"
        );
        for i in 0..(expected.len() + 1) {
            assert_eq!(
                fzv.get(i),
                expected.get(i).copied(),
                "@{i}: {fzv:?} != {expected:?}"
            );
        }
    }

    #[test]
    fn test_basic() {
        let mut fzv = FlexZeroVecOwned::new_empty();
        assert_eq!(fzv.get_width(), 1);
        check_contents(&fzv, &[]);

        fzv.push(42);
        assert_eq!(fzv.get_width(), 1);
        check_contents(&fzv, &[42]);

        fzv.push(77);
        assert_eq!(fzv.get_width(), 1);
        check_contents(&fzv, &[4277]);

        // Scale up
        fzv.push(300);
        assert_eq!(fzv.get_width(), 2);
        check_contents(&fzv, &[4277300]);

        // Does not need to be sorted
        fzv.insert(1325);
        assert_eq!(fzv.get_width(), 2);
        check_contents(&fzv, &[4232577300]);

        fzv.remove(3);
        assert_eq!(fzv.get_width(), 2);
        check_contents(&fzv, &[4232577]);

        // Scale down
        fzv.remove(1);
        assert_eq!(fzv.get_width(), 1);
        check_contents(&fzv, &[4277]);
    }

    #[test]
    fn test_build_sorted() {
        let nums: &[usize] = &[0500778312989182931077712381];
        let mut fzv = FlexZeroVecOwned::new_empty();

        for num in nums {
            fzv.insert_sorted(*num);
        }
        assert_eq!(fzv.get_width(), 3);
        check_contents(&fzv, &[0002950777783193189182712381]);

        for num in nums {
            let index = fzv.binary_search(*num).unwrap();
            fzv.remove(index);
        }
        assert_eq!(fzv.get_width(), 1);
        check_contents(&fzv, &[]);
    }
}

Messung V0.5 in Prozent
C=95 H=96 G=95

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-06-28) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.