<commit_before>use ffi;
use libc;
use std::{mem, num, ptr, raw};

/// Types that can be used as to store data passed to and from FFTW.
pub trait BackingStorage<T> {
    /// Get a pointer to that data.
    fn storage_slice<'a>(&'a mut self) -> &'a mut [T];
}

impl<'x, T> BackingStorage<T> for &'x mut [T] {
    fn storage_slice<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
}
impl<T> BackingStorage<T> for Vec<T> {
    fn storage_slice<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
}

/// A non-resizable vector allocated using FFTWs allocator.
pub struct FFTWVec<T> {
    dat: *mut T,
    len: uint
}

impl<T> FFTWVec<T> {
    /// Allocate a `FFTWVec` without initialising the elements at all.
    pub unsafe fn uninit(n: uint) -> FFTWVec<T> {
        let size = n.checked_mul(&mem::size_of::<T>()).expect("FFTWVec::uninit: size overflow");
        let dat = ffi::fftw_malloc(size as libc::size_t);

        if dat.is_null() {
            panic!("FFTWVec::uninit: fftw_malloc failed");
        }

        FFTWVec { dat: dat as *mut T, len: n }
    }

    /// View the contents as an immutable slice.
    pub fn as_slice<'a>(&'a self) -> &'a [T] {
        unsafe {mem::transmute(raw::Slice { data: self.dat as *const T, len: self.len })}
    }
    /// View the contents as a mutable slice.
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        unsafe {mem::transmute(raw::Slice { data: self.dat as *const T, len: self.len })}
    }
}

impl<T: num::Zero> FFTWVec<T> {
    /// Allocate a `FFTWVec` of length `n` containing zeros.
    pub fn zeros(n: uint) -> FFTWVec<T> {
        let mut v = unsafe {FFTWVec::uninit(n)};
        for elem in v.as_mut_slice().iter_mut() {
            *elem = num::zero();
        }

        v
    }
}
#[unsafe_destructor]
impl<T> Drop for FFTWVec<T> {
    fn drop(&mut self) {
        // free everything
        for p in self.as_slice().iter() {
            unsafe {ptr::read(p);}
        }
        unsafe {ffi::fftw_free(self.dat as *mut libc::c_void)}
    }
}
<commit_msg>Make FFTWVec::zeros safe with all types.<commit_after>//! Memory backing.

use ffi;
use libc;
use std::{mem, num, ptr, raw};



/// Types that can be used as to store data passed to and from FFTW.
pub trait BackingStorage<T> {
    /// Get a pointer to that data.
    fn storage_slice<'a>(&'a mut self) -> &'a mut [T];
}

impl<'x, T> BackingStorage<T> for &'x mut [T] {
    fn storage_slice<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
}
impl<T> BackingStorage<T> for Vec<T> {
    fn storage_slice<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
}

struct RawVec<T> {
    dat: *mut T,
    len: uint
}
impl<T> RawVec<T> {
    unsafe fn uninit(n: uint) -> RawVec<T> {
        let size = n.checked_mul(&mem::size_of::<T>()).expect("FFTWVec::uninit: size overflow");
        let dat = ffi::fftw_malloc(size as libc::size_t);

        if dat.is_null() {
            panic!("FFTWVec::uninit: fftw_malloc failed");
        }

        RawVec { dat: dat as *mut T, len: n }
    }

    fn as_slice(&self) -> &[T] {
        unsafe {mem::transmute(raw::Slice { data: self.dat as *const T, len: self.len })}
    }
    fn as_slice_mut(&mut self) -> &mut [T] {
        unsafe {mem::transmute(raw::Slice { data: self.dat as *const T, len: self.len })}
    }
}

#[unsafe_destructor]
impl<T> Drop for RawVec<T> {
    fn drop(&mut self) {
        unsafe {ffi::fftw_free(self.dat as *mut libc::c_void)}
    }
}


/// A non-resizable vector allocated using FFTWs allocator.
pub struct FFTWVec<T> {
    dat: RawVec<T>
}

impl<T> FFTWVec<T> {
    /// Allocate a `FFTWVec` without initialising the elements at all.
    pub unsafe fn uninit(n: uint) -> FFTWVec<T> {
        FFTWVec { dat: RawVec::uninit(n) }
    }

    /// View the contents as an immutable slice.
    pub fn as_slice<'a>(&'a self) -> &'a [T] {
        self.dat.as_slice()
    }
    /// View the contents as a mutable slice.
    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.dat.as_slice_mut()
    }
}


#[unsafe_destructor]
impl<T> Drop for FFTWVec<T> {
    fn drop(&mut self) {
        // free everything
        for p in self.as_slice().iter() {
            unsafe {ptr::read(p);}
        }
    }
}

struct PartialVec<T> {
    dat: RawVec<T>,
    idx: uint
}

impl<T: num::Zero> FFTWVec<T> {
    /// Allocate a `FFTWVec` of length `n` containing zeros.
    pub fn zeros(n: uint) -> FFTWVec<T> {
        let mut v = PartialVec {
            dat: unsafe {RawVec::uninit(n)},
            idx: 0,
        };

        while v.idx < n {
            unsafe {
                ptr::write(v.dat.dat.offset(v.idx as int), num::zero());
            }
            v.idx += 1
        }

        unsafe {
            let ret = FFTWVec {
                dat: ptr::read(&v.dat)
            };
            mem::forget(v);
            ret
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for PartialVec<T> {
    fn drop(&mut self) {
        for p in self.dat.as_slice().slice_to(self.idx).iter() {
            unsafe {ptr::read(p);}
        }
    }
}

{'fraction_non_alphanumeric': 0.16455946266297905, 'fraction_numerical': 0.0003951007506914263, 'mean_word_length': 2.2919375812743823, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1937723', 'n_tokens_mistral': 1919, 'n_tokens_neox': 1890, 'n_words': 507}