<commit_before>use std::marker::PhantomData;

use num::BigUint;
use num::pow::Pow;

use Construct;
use Of;
use ToPos;
use Count;
use Data;
use ToIndex;
use Zero;

/// Dimension is natural number, position is a list of numbers.
pub struct PowerSet<T = Data>(PhantomData<T>);

impl<T> Construct for PowerSet<T> {
    fn new() -> PowerSet<T> { PowerSet(PhantomData) }
}

impl Count<usize> for PowerSet<Data> {
    type N = usize;
    fn count(&self, dim: &usize) -> usize {
        1 << *dim
    }
}

impl Count<BigUint> for PowerSet<Data> {
    type N = BigUint;
    fn count(&self, dim: &BigUint) -> BigUint {
        use std::convert::TryInto;

        let _two: BigUint = 2usize.into();
        let dim: u32 = dim.try_into().unwrap();
        _two.pow(dim)
    }
}

impl<T, U> Count<U> for PowerSet<Of<T>>
    where
        T: Construct + Count<U>,
        <T as Count<U>>::N: From<usize> + Pow<<T as Count<U>>::N, Output = <T as Count<U>>::N>,
{
    type N = <T as Count<U>>::N;
    fn count(&self, dim: &U) -> Self::N {
        let _two: Self::N = 2usize.into();
        let of: T = Construct::new();
        _two.pow(of.count(dim))
    }
}

impl Zero<usize, Vec<usize>> for PowerSet<Data> {
    fn zero(&self, _dim: &usize) -> Vec<usize> {
        vec![]
    }
}

impl<T, U, V> Zero<U, Vec<V>> for PowerSet<Of<T>>
    where T: Construct + Count<U> + Zero<U, V>
{
    fn zero(&self, _dim: &U) -> Vec<V> {
        vec![]
    }
}

impl ToIndex<usize, Vec<usize>> for PowerSet<Data> {
    fn to_index(
        &self,
        _dim: &usize,
        pos: &Vec<usize>
    ) -> usize {
        let mut index = 0;
        for &i in pos.iter() {
            index |= 1 << i;
        }
        index
    }
}

impl<T, U, V>
ToIndex<U, Vec<V>> for PowerSet<Of<T>><commit_msg>Impl `Zero<BigUint, Vec<BigUint>>` for `PowerSet`<commit_after>use std::marker::PhantomData;

use num::BigUint;
use num::pow::Pow;

use Construct;
use Of;
use ToPos;
use Count;
use Data;
use ToIndex;
use Zero;

/// Dimension is natural number, position is a list of numbers.
pub struct PowerSet<T = Data>(PhantomData<T>);

impl<T> Construct for PowerSet<T> {
    fn new() -> PowerSet<T> { PowerSet(PhantomData) }
}

impl Count<usize> for PowerSet<Data> {
    type N = usize;
    fn count(&self, dim: &usize) -> usize {
        1 << *dim
    }
}

impl Count<BigUint> for PowerSet<Data> {
    type N = BigUint;
    fn count(&self, dim: &BigUint) -> BigUint {
        use std::convert::TryInto;

        let _two: BigUint = 2usize.into();
        let dim: u32 = dim.try_into().unwrap();
        _two.pow(dim)
    }
}

impl<T, U> Count<U> for PowerSet<Of<T>>
    where
        T: Construct + Count<U>,
        <T as Count<U>>::N: From<usize> + Pow<<T as Count<U>>::N, Output = <T as Count<U>>::N>,
{
    type N = <T as Count<U>>::N;
    fn count(&self, dim: &U) -> Self::N {
        let _two: Self::N = 2usize.into();
        let of: T = Construct::new();
        _two.pow(of.count(dim))
    }
}

impl Zero<usize, Vec<usize>> for PowerSet<Data> {
    fn zero(&self, _dim: &usize) -> Vec<usize> {
        vec![]
    }
}

impl Zero<BigUint, Vec<BigUint>> for PowerSet<Data> {
    fn zero(&self, _dim: &BigUint) -> Vec<BigUint> {
        vec![]
    }
}

impl<T, U, V> Zero<U, Vec<V>> for PowerSet<Of<T>>
    where T: Construct + Count<U> + Zero<U, V>
{
    fn zero(&self, _dim: &U) -> Vec<V> {
        vec![]
    }
}

impl ToIndex<usize, Vec<usize>> for PowerSet<Data> {
    fn to_index(
        &self,
        _dim: &usize,
        pos: &Vec<usize>
    ) -> usize {
        let mut index = 0;
        for &i in pos.iter() {
            index |= 1 << i;
        }
        index
    }
}

impl<T, U, V>
ToIndex<U, Vec<V>> for PowerSet<Of<T>>
{'fraction_non_alphanumeric': 0.17662969975655937, 'fraction_numerical': 0.0037868542061130646, 'mean_word_length': 2.5185537583254045, 'pattern_counts': {'":': 0, '<': 107, '<?xml version=': 0, '>': 114, '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': '5652594', 'n_tokens_mistral': 1449, 'n_tokens_neox': 1436, 'n_words': 374}