<commit_before>#![feature(phase)]
#[phase(plugin)] extern crate rust_debug = "rust-debug";

#[phase(plugin, link)] extern crate debug;

extern crate collections;
extern crate getopts;

use std::io;
use getopts::{optopt,getopts, OptGroup, short_usage, usage};
use std::os;
use std::io::File;

mod lexer;
mod parser;
mod token;
mod view_writer;

fn get_file_contents(file_path: &str) -> Result<String, io::IoError> {
    let path = from_str::<Path>(file_path).unwrap();

    File::open(&path).and_then(|file| {
        let mut file = file;
        file.read_to_str()
    })
}

fn output_file_from_input(input_file_path: &str) -> Path {
    let input_path = from_str::<Path>(input_file_path).unwrap();

    if input_file_path.ends_with(".rs.html") {
        from_str::<Path>(input_file_path.slice_to(input_file_path.len() - 5)).unwrap()
    } else {
        input_path.with_extension("rs")
    }
}

fn view_name(input_file_path: &str) -> String {
    let path = match from_str::<Path>(input_file_path) {
        Some(path) => {
            path
        },
        None => {
            return "View".to_string();
        }
    };
    match path.filestem_str() {
        Some(fs) => {
            let name = if fs.ends_with(".rs") {
                fs.slice_to(fs.len() - 3)
            } else {
                fs
            };

            let mut view_name = String::with_capacity(name.len());
            let mut capitilize = true;

            for c in name.chars() {
                match c {
                    '.' | '_' | '-' => capitilize = true,
                    _ => {
                        view_name.push_char(if capitilize {
                                                c.to_uppercase()
                                            } else {
                                                c
                                            });
                        capitilize = false
                    }
                }
            }

            view_name
        },
        None => {
            "View".to_string()
        }
    }
}

fn print_usage(program_name: &str, options: &[OptGroup]) {
    println!("{}", usage(short_usage(program_name, options).as_slice(), options));
}

fn main() {
    let opts = [
        optopt("o", "out", "Filename of the generated rust code", "")
    ];
    let args: Vec<String> = os::args().iter()
                                .map(|a| a.to_string())
                                .collect();
    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(e) => fail!("Unable to get options: {}", e)
    };

    if matches.free.is_empty() {
        print_usage(args.get(0).as_slice(), opts);
        return;
    }

    let input_file_name = matches.free.get(0).as_slice();
    let output_file_name = match matches.opt_str("o") {
        Some(ofn) => from_str::<Path>(ofn.as_slice()).unwrap(),
        None => output_file_from_input(input_file_name)
    };

    let contents = match get_file_contents(input_file_name) {
        Ok(contents) => contents,
        Err(e) => fail!(e.to_str())
    };

    let mut parser = parser::Parser::new(contents.as_slice());
    parser.parse();

    //for section in parser.sections.iter() {
    //    println!("{}", section);
    //}

    view_writer::write_view(view_name(input_file_name).as_slice(), &output_file_name, &parser.sections);
}
<commit_msg>Update to rustc master<commit_after>#![feature(phase)]
#[phase(plugin)] extern crate rust_debug = "rust-debug";

#[phase(plugin, link)] extern crate debug;

extern crate collections;
extern crate getopts;

use std::io;
use getopts::{optopt,getopts, OptGroup, short_usage, usage};
use std::os;
use std::io::File;

mod lexer;
mod parser;
mod token;
mod view_writer;

fn get_file_contents(file_path: &str) -> Result<String, io::IoError> {
    let path = from_str::<Path>(file_path).unwrap();

    File::open(&path).and_then(|file| {
        let mut file = file;
        file.read_to_string()
    })
}

fn output_file_from_input(input_file_path: &str) -> Path {
    let input_path = from_str::<Path>(input_file_path).unwrap();

    if input_file_path.ends_with(".rs.html") {
        from_str::<Path>(input_file_path.slice_to(input_file_path.len() - 5)).unwrap()
    } else {
        input_path.with_extension("rs")
    }
}

fn view_name(input_file_path: &str) -> String {
    let path = match from_str::<Path>(input_file_path) {
        Some(path) => {
            path
        },
        None => {
            return "View".to_string();
        }
    };
    match path.filestem_str() {
        Some(fs) => {
            let name = if fs.ends_with(".rs") {
                fs.slice_to(fs.len() - 3)
            } else {
                fs
            };

            let mut view_name = String::with_capacity(name.len());
            let mut capitilize = true;

            for c in name.chars() {
                match c {
                    '.' | '_' | '-' => capitilize = true,
                    _ => {
                        view_name.push_char(if capitilize {
                                                c.to_uppercase()
                                            } else {
                                                c
                                            });
                        capitilize = false
                    }
                }
            }

            view_name
        },
        None => {
            "View".to_string()
        }
    }
}

fn print_usage(program_name: &str, options: &[OptGroup]) {
    println!("{}", usage(short_usage(program_name, options).as_slice(), options));
}

fn main() {
    let opts = [
        optopt("o", "out", "Filename of the generated rust code", "")
    ];
    let args: Vec<String> = os::args().iter()
                                .map(|a| a.to_string())
                                .collect();
    let matches = match getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(e) => fail!("Unable to get options: {}", e)
    };

    if matches.free.is_empty() {
        print_usage(args.get(0).as_slice(), opts);
        return;
    }

    let input_file_name = matches.free.get(0).as_slice();
    let output_file_name = match matches.opt_str("o") {
        Some(ofn) => from_str::<Path>(ofn.as_slice()).unwrap(),
        None => output_file_from_input(input_file_name)
    };

    let contents = match get_file_contents(input_file_name) {
        Ok(contents) => contents,
        Err(e) => fail!(e.to_string())
    };

    let mut parser = parser::Parser::new(contents.as_slice());
    parser.parse();

    //for section in parser.sections.iter() {
    //    println!("{}", section);
    //}

    view_writer::write_view(view_name(input_file_name).as_slice(), &output_file_name, &parser.sections);
}
<|endoftext|>


<commit_before>//! Functions for manipulating the contrast of images.

use image::{GenericImage, GrayImage, ImageBuffer, Luma};

/// Returns the Otsu threshold level of an 8bpp image.
/// This threshold will optimally binarize an image that
/// contains two classes of pixels which have distributions
/// with equal variances. For details see:
/// Xu, X., et al. Pattern recognition letters 32.7 (2011)
pub fn otsu_level<I>(image: &I) -> u8
    where I: GenericImage<Pixel = Luma<u8>>
{
    let hist = histogram(image);
    let levels = hist.len();
    let mut histc = [0i32; 256];
    let mut meanc = [0.0f64; 256];
    let mut pixel_count = hist[0] as f64;

    histc[0] = hist[0];

    for i in 1..levels {
        pixel_count += hist[i] as f64;
        histc[i] = histc[i - 1] + hist[i];
        meanc[i] = meanc[i - 1] + (hist[i] as f64) * (i as f64);
    }

    let mut sigma_max = -1f64;
    let mut otsu = 0f64;
    let mut otsu2 = 0f64;

    for i in 0..levels {
        meanc[i] /= pixel_count;

        let p0 = (histc[i] as f64) / pixel_count;
        let p1 = 1f64 - p0;
        let mu0 = meanc[i] / p0;
        let mu1 = (meanc[levels - 1] / pixel_count - meanc[i]) / p1;

        let sigma = p0 * p1 * (mu0 - mu1).powi(2);
        if sigma >= sigma_max {
            if sigma > sigma_max {
                otsu = i as f64;
                sigma_max = sigma;
            } else {
                otsu2 = i as f64;
            }
        }
    }
    ((otsu + otsu2) / 2.0).ceil() as u8
}

/// Returns a binarized image from an input 8bpp grayscale image
/// obtained by applying the given threshold.
pub fn threshold<I>(image: &I, thresh: u8) -> GrayImage
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut out: GrayImage = ImageBuffer::new(image.width(), image.height());
    out.copy_from(image, 0, 0);
    threshold_mut(&mut out, thresh);
    out
}

/// Mutates given image to form a binarized version produced by applying
/// the given threshold.
pub fn threshold_mut<I>(image: &mut I, thresh: u8)
    where I: GenericImage<Pixel = Luma<u8>>
{
    for y in 0..image.height() {
        for x in 0..image.width() {
            unsafe {
                if image.unsafe_get_pixel(x, y)[0] as u8 <= thresh {
                    image.unsafe_put_pixel(x, y, Luma([0]));
                } else {
                    image.unsafe_put_pixel(x, y, Luma([255]));
                }
            }
        }
    }
}

/// Returns the histogram of grayscale values in an 8pp
/// grayscale image.
pub fn histogram<I>(image: &I) -> [i32; 256]
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut hist = [0i32; 256];

    for pix in image.pixels() {
        hist[pix.2[0] as usize] += 1;
    }

    hist
}

/// Returns the cumulative histogram of grayscale values in an 8bpp
/// grayscale image.
pub fn cumulative_histogram<I>(image: &I) -> [i32; 256]
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut hist = histogram(image);

    for i in 1..hist.len() {
        hist[i] += hist[i - 1];
    }

    hist
}

/// Equalises the histogram of an 8bpp grayscale image in place.
/// https://en.wikipedia.org/wiki/Histogram_equalization
pub fn equalize_histogram_mut<I>(image: &mut I)
    where I: GenericImage<Pixel = Luma<u8>>
{
    let hist = cumulative_histogram(image);
    let total = hist[255] as f32;

    for y in 0..image.height() {
        for x in 0..image.width() {
            let original = unsafe { image.unsafe_get_pixel(x, y)[0] as usize };
            let fraction = hist[original] as f32 / total;
            let out = f32::min(255f32, 255f32 * fraction);
            unsafe { image.unsafe_put_pixel(x, y, Luma([out as u8])); }
        }
    }
}

/// Equalises the histogram of an 8bpp grayscale image.
/// https://en.wikipedia.org/wiki/Histogram_equalization
pub fn equalize_histogram<I>(image: &I) -> GrayImage
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut out: GrayImage = ImageBuffer::new(image.width(), image.height());
    out.copy_from(image, 0, 0);
    equalize_histogram_mut(&mut out);
    out
}

/// Adjusts contrast of an 8bpp grayscale image in place so that its
/// histogram is as close as possible to that of the target image.
pub fn match_histogram_mut<I, J>(image: &mut I, target: &J)
    where I : GenericImage<Pixel = Luma<u8>>,
          J : GenericImage<Pixel = Luma<u8>>
{
    let image_histc = cumulative_histogram(image);
    let target_histc = cumulative_histogram(target);
    let lut = histogram_lut(&image_histc, &target_histc);

    for y in 0..image.height() {
        for x in 0..image.width() {
            unsafe {
                let pix = image.unsafe_get_pixel(x, y)[0] as usize;
                image.unsafe_put_pixel(x, y, Luma([lut[pix] as u8]));
            }
        }
    }
}

/// Adjusts contrast of an 8bpp grayscale image so that its
/// histogram is as close as possible to that of the target image.
pub fn match_histogram<I, J>(image: &I, target: &J) -> GrayImage
    where I : GenericImage<Pixel = Luma<u8>>,
          J : GenericImage<Pixel = Luma<u8>>
{
    let mut out: GrayImage = ImageBuffer::new(image.width(), image.height());
    out.copy_from(image, 0, 0);
    match_histogram_mut(&mut out, target);
    out
}

/// l = histogram_lut(s, t) is chosen so that target_histc[l[i]] / sum(target_histc)
/// is as close as possible to source_histc[i] / sum(source_histc).
fn histogram_lut(source_histc: &[i32; 256], target_histc: &[i32; 256]) -> [usize; 256] {
    let source_total = source_histc[255] as f32;
    let target_total = target_histc[255] as f32;

    let mut lut = [0usize; 256];
    let mut y = 0usize;
    let mut prev_target_fraction = 0f32;

    for s in 0..256 {
        let source_fraction = source_histc[s] as f32 / source_total;
        let mut target_fraction = target_histc[y] as f32 / target_total;

        while source_fraction > target_fraction && y < 255 {
            y = y + 1;
            prev_target_fraction = target_fraction;
            target_fraction = target_histc[y] as f32 / target_total;
        }

        if y == 0 {
            lut[s] = y;
        }
        else {
            let prev_dist = f32::abs(prev_target_fraction - source_fraction);
            let dist = f32::abs(target_fraction - source_fraction);
            if prev_dist < dist {
                lut[s] = y - 1;
            }
            else {
                lut[s] = y;
            }
        }
    }

    lut
}

#[cfg(test)]
mod test {

    use super::{
        cumulative_histogram,
        equalize_histogram,
        histogram,
        histogram_lut,
        otsu_level,
        threshold};
    use utils::gray_bench_image;
    use image::{GrayImage, ImageBuffer};
    use test;

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_cumulative_histogram() {
        let image: GrayImage = ImageBuffer::from_raw(5, 1, vec![
            1u8, 2u8, 3u8, 2u8, 1u8]).unwrap();

        let hist = cumulative_histogram(&image);

        assert_eq!(hist[0], 0);
        assert_eq!(hist[1], 2);
        assert_eq!(hist[2], 4);
        assert_eq!(hist[3], 5);
        assert!(hist.iter().skip(4).all(|x| *x == 5));
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_histogram() {
        let image: GrayImage = ImageBuffer::from_raw(5, 1, vec![
            1u8, 2u8, 3u8, 2u8, 1u8]).unwrap();

        let hist = histogram(&image);

        assert_eq!(hist[0], 0);
        assert_eq!(hist[1], 2);
        assert_eq!(hist[2], 2);
        assert_eq!(hist[3], 1);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_histogram_lut_source_and_target_equal() {
        let mut histc = [0i32; 256];
        for i in 1..histc.len() {
            histc[i] = 2 * i as i32;
        }

        let lut = histogram_lut(&histc, &histc);
        let expected = (0..256).collect::<Vec<_>>();

        assert_eq!(&lut[0..256], &expected[0..256]);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_histogram_lut_gradient_to_step_contrast() {
        let mut grad_histc = [0i32; 256];
        for i in 0..grad_histc.len() {
            grad_histc[i] = i as i32;
        }

        let mut step_histc = [0i32; 256];
        for i in 30..130 {
            step_histc[i] = 100;
        }
        for i in 130..256 {
            step_histc[i] = 200;
        }

        let lut = histogram_lut(&grad_histc, &step_histc);
        let mut expected = [0usize; 256];

        // No black pixels in either image
        expected[0] = 0;

        for i in 1..64 {
            expected[i] = 29;
        }
        for i in 64..128 {
            expected[i] = 30;
        }
        for i in 128..192 {
            expected[i] = 129;
        }
        for i in 192..256 {
            expected[i] = 130;
        }

        assert_eq!(&lut[0..256], &expected[0..256]);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_otsu_level() {
        let image: GrayImage = ImageBuffer::from_raw(26, 1,
            vec![0u8, 10u8, 20u8, 30u8, 40u8, 50u8, 60u8, 70u8,
                80u8, 90u8, 100u8, 110u8, 120u8, 130u8, 140u8,
                150u8, 160u8, 170u8, 180u8, 190u8, 200u8,  210u8,
                220u8,  230u8,  240u8,  250u8]).unwrap();
        let level = otsu_level(&image);
        assert_eq!(level, 125);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_threshold() {
        let original: GrayImage = ImageBuffer::from_raw(26, 1,
            vec![0u8, 10u8, 20u8, 30u8, 40u8, 50u8, 60u8, 70u8,
                80u8, 90u8, 100u8, 110u8, 120u8, 130u8, 140u8,
                150u8, 160u8, 170u8, 180u8, 190u8, 200u8,  210u8,
                220u8,  230u8,  240u8,  250u8]).unwrap();
        let expected: GrayImage = ImageBuffer::from_raw(26, 1,
            vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
                0u8, 0u8, 0u8, 0u8, 0u8, 255u8, 255u8,
                255u8, 255u8, 255u8, 255u8, 255u8, 255u8,  255u8,
                255u8,  255u8,  255u8,  255u8]).unwrap();

        let actual = threshold(&original, 125u8);
        assert_pixels_eq!(expected, actual);
    }

    #[bench]
    fn bench_equalize_histogram(b: &mut test::Bencher) {
        let image = gray_bench_image(500, 500);
        b.iter(|| {
            let equalized = equalize_histogram(&image);
            test::black_box(equalized);
        });
    }
}
<commit_msg>You accidentally a 'b'.<commit_after>//! Functions for manipulating the contrast of images.

use image::{GenericImage, GrayImage, ImageBuffer, Luma};

/// Returns the Otsu threshold level of an 8bpp image.
/// This threshold will optimally binarize an image that
/// contains two classes of pixels which have distributions
/// with equal variances. For details see:
/// Xu, X., et al. Pattern recognition letters 32.7 (2011)
pub fn otsu_level<I>(image: &I) -> u8
    where I: GenericImage<Pixel = Luma<u8>>
{
    let hist = histogram(image);
    let levels = hist.len();
    let mut histc = [0i32; 256];
    let mut meanc = [0.0f64; 256];
    let mut pixel_count = hist[0] as f64;

    histc[0] = hist[0];

    for i in 1..levels {
        pixel_count += hist[i] as f64;
        histc[i] = histc[i - 1] + hist[i];
        meanc[i] = meanc[i - 1] + (hist[i] as f64) * (i as f64);
    }

    let mut sigma_max = -1f64;
    let mut otsu = 0f64;
    let mut otsu2 = 0f64;

    for i in 0..levels {
        meanc[i] /= pixel_count;

        let p0 = (histc[i] as f64) / pixel_count;
        let p1 = 1f64 - p0;
        let mu0 = meanc[i] / p0;
        let mu1 = (meanc[levels - 1] / pixel_count - meanc[i]) / p1;

        let sigma = p0 * p1 * (mu0 - mu1).powi(2);
        if sigma >= sigma_max {
            if sigma > sigma_max {
                otsu = i as f64;
                sigma_max = sigma;
            } else {
                otsu2 = i as f64;
            }
        }
    }
    ((otsu + otsu2) / 2.0).ceil() as u8
}

/// Returns a binarized image from an input 8bpp grayscale image
/// obtained by applying the given threshold.
pub fn threshold<I>(image: &I, thresh: u8) -> GrayImage
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut out: GrayImage = ImageBuffer::new(image.width(), image.height());
    out.copy_from(image, 0, 0);
    threshold_mut(&mut out, thresh);
    out
}

/// Mutates given image to form a binarized version produced by applying
/// the given threshold.
pub fn threshold_mut<I>(image: &mut I, thresh: u8)
    where I: GenericImage<Pixel = Luma<u8>>
{
    for y in 0..image.height() {
        for x in 0..image.width() {
            unsafe {
                if image.unsafe_get_pixel(x, y)[0] as u8 <= thresh {
                    image.unsafe_put_pixel(x, y, Luma([0]));
                } else {
                    image.unsafe_put_pixel(x, y, Luma([255]));
                }
            }
        }
    }
}

/// Returns the histogram of grayscale values in an 8bpp
/// grayscale image.
pub fn histogram<I>(image: &I) -> [i32; 256]
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut hist = [0i32; 256];

    for pix in image.pixels() {
        hist[pix.2[0] as usize] += 1;
    }

    hist
}

/// Returns the cumulative histogram of grayscale values in an 8bpp
/// grayscale image.
pub fn cumulative_histogram<I>(image: &I) -> [i32; 256]
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut hist = histogram(image);

    for i in 1..hist.len() {
        hist[i] += hist[i - 1];
    }

    hist
}

/// Equalises the histogram of an 8bpp grayscale image in place.
/// https://en.wikipedia.org/wiki/Histogram_equalization
pub fn equalize_histogram_mut<I>(image: &mut I)
    where I: GenericImage<Pixel = Luma<u8>>
{
    let hist = cumulative_histogram(image);
    let total = hist[255] as f32;

    for y in 0..image.height() {
        for x in 0..image.width() {
            let original = unsafe { image.unsafe_get_pixel(x, y)[0] as usize };
            let fraction = hist[original] as f32 / total;
            let out = f32::min(255f32, 255f32 * fraction);
            unsafe { image.unsafe_put_pixel(x, y, Luma([out as u8])); }
        }
    }
}

/// Equalises the histogram of an 8bpp grayscale image.
/// https://en.wikipedia.org/wiki/Histogram_equalization
pub fn equalize_histogram<I>(image: &I) -> GrayImage
    where I: GenericImage<Pixel = Luma<u8>>
{
    let mut out: GrayImage = ImageBuffer::new(image.width(), image.height());
    out.copy_from(image, 0, 0);
    equalize_histogram_mut(&mut out);
    out
}

/// Adjusts contrast of an 8bpp grayscale image in place so that its
/// histogram is as close as possible to that of the target image.
pub fn match_histogram_mut<I, J>(image: &mut I, target: &J)
    where I : GenericImage<Pixel = Luma<u8>>,
          J : GenericImage<Pixel = Luma<u8>>
{
    let image_histc = cumulative_histogram(image);
    let target_histc = cumulative_histogram(target);
    let lut = histogram_lut(&image_histc, &target_histc);

    for y in 0..image.height() {
        for x in 0..image.width() {
            unsafe {
                let pix = image.unsafe_get_pixel(x, y)[0] as usize;
                image.unsafe_put_pixel(x, y, Luma([lut[pix] as u8]));
            }
        }
    }
}

/// Adjusts contrast of an 8bpp grayscale image so that its
/// histogram is as close as possible to that of the target image.
pub fn match_histogram<I, J>(image: &I, target: &J) -> GrayImage
    where I : GenericImage<Pixel = Luma<u8>>,
          J : GenericImage<Pixel = Luma<u8>>
{
    let mut out: GrayImage = ImageBuffer::new(image.width(), image.height());
    out.copy_from(image, 0, 0);
    match_histogram_mut(&mut out, target);
    out
}

/// l = histogram_lut(s, t) is chosen so that target_histc[l[i]] / sum(target_histc)
/// is as close as possible to source_histc[i] / sum(source_histc).
fn histogram_lut(source_histc: &[i32; 256], target_histc: &[i32; 256]) -> [usize; 256] {
    let source_total = source_histc[255] as f32;
    let target_total = target_histc[255] as f32;

    let mut lut = [0usize; 256];
    let mut y = 0usize;
    let mut prev_target_fraction = 0f32;

    for s in 0..256 {
        let source_fraction = source_histc[s] as f32 / source_total;
        let mut target_fraction = target_histc[y] as f32 / target_total;

        while source_fraction > target_fraction && y < 255 {
            y = y + 1;
            prev_target_fraction = target_fraction;
            target_fraction = target_histc[y] as f32 / target_total;
        }

        if y == 0 {
            lut[s] = y;
        }
        else {
            let prev_dist = f32::abs(prev_target_fraction - source_fraction);
            let dist = f32::abs(target_fraction - source_fraction);
            if prev_dist < dist {
                lut[s] = y - 1;
            }
            else {
                lut[s] = y;
            }
        }
    }

    lut
}

#[cfg(test)]
mod test {

    use super::{
        cumulative_histogram,
        equalize_histogram,
        histogram,
        histogram_lut,
        otsu_level,
        threshold};
    use utils::gray_bench_image;
    use image::{GrayImage, ImageBuffer};
    use test;

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_cumulative_histogram() {
        let image: GrayImage = ImageBuffer::from_raw(5, 1, vec![
            1u8, 2u8, 3u8, 2u8, 1u8]).unwrap();

        let hist = cumulative_histogram(&image);

        assert_eq!(hist[0], 0);
        assert_eq!(hist[1], 2);
        assert_eq!(hist[2], 4);
        assert_eq!(hist[3], 5);
        assert!(hist.iter().skip(4).all(|x| *x == 5));
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_histogram() {
        let image: GrayImage = ImageBuffer::from_raw(5, 1, vec![
            1u8, 2u8, 3u8, 2u8, 1u8]).unwrap();

        let hist = histogram(&image);

        assert_eq!(hist[0], 0);
        assert_eq!(hist[1], 2);
        assert_eq!(hist[2], 2);
        assert_eq!(hist[3], 1);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_histogram_lut_source_and_target_equal() {
        let mut histc = [0i32; 256];
        for i in 1..histc.len() {
            histc[i] = 2 * i as i32;
        }

        let lut = histogram_lut(&histc, &histc);
        let expected = (0..256).collect::<Vec<_>>();

        assert_eq!(&lut[0..256], &expected[0..256]);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_histogram_lut_gradient_to_step_contrast() {
        let mut grad_histc = [0i32; 256];
        for i in 0..grad_histc.len() {
            grad_histc[i] = i as i32;
        }

        let mut step_histc = [0i32; 256];
        for i in 30..130 {
            step_histc[i] = 100;
        }
        for i in 130..256 {
            step_histc[i] = 200;
        }

        let lut = histogram_lut(&grad_histc, &step_histc);
        let mut expected = [0usize; 256];

        // No black pixels in either image
        expected[0] = 0;

        for i in 1..64 {
            expected[i] = 29;
        }
        for i in 64..128 {
            expected[i] = 30;
        }
        for i in 128..192 {
            expected[i] = 129;
        }
        for i in 192..256 {
            expected[i] = 130;
        }

        assert_eq!(&lut[0..256], &expected[0..256]);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_otsu_level() {
        let image: GrayImage = ImageBuffer::from_raw(26, 1,
            vec![0u8, 10u8, 20u8, 30u8, 40u8, 50u8, 60u8, 70u8,
                80u8, 90u8, 100u8, 110u8, 120u8, 130u8, 140u8,
                150u8, 160u8, 170u8, 180u8, 190u8, 200u8,  210u8,
                220u8,  230u8,  240u8,  250u8]).unwrap();
        let level = otsu_level(&image);
        assert_eq!(level, 125);
    }

    #[test]
    #[cfg_attr(rustfmt, rustfmt_skip)]
    fn test_threshold() {
        let original: GrayImage = ImageBuffer::from_raw(26, 1,
            vec![0u8, 10u8, 20u8, 30u8, 40u8, 50u8, 60u8, 70u8,
                80u8, 90u8, 100u8, 110u8, 120u8, 130u8, 140u8,
                150u8, 160u8, 170u8, 180u8, 190u8, 200u8,  210u8,
                220u8,  230u8,  240u8,  250u8]).unwrap();
        let expected: GrayImage = ImageBuffer::from_raw(26, 1,
            vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
                0u8, 0u8, 0u8, 0u8, 0u8, 255u8, 255u8,
                255u8, 255u8, 255u8, 255u8, 255u8, 255u8,  255u8,
                255u8,  255u8,  255u8,  255u8]).unwrap();

        let actual = threshold(&original, 125u8);
        assert_pixels_eq!(expected, actual);
    }

    #[bench]
    fn bench_equalize_histogram(b: &mut test::Bencher) {
        let image = gray_bench_image(500, 500);
        b.iter(|| {
            let equalized = equalize_histogram(&image);
            test::black_box(equalized);
        });
    }
}
<|endoftext|>


<commit_before>use crate::Position;
use fixedbitset::FixedBitSet;

#[derive(Debug)]
pub struct Coverage {
    n: usize,
    /// A bit is set, if the row is covered.
    rows: FixedBitSet,
    /// A bit is set, if the column is covered.
    columns: FixedBitSet,
}

impl Coverage {
    #[inline]
    pub fn n(&self) -> usize {
        self.n
    }

    pub fn new(n: usize) -> Coverage {
        assert!(n > 0);
        Coverage {
            n: n,
            rows: FixedBitSet::with_capacity(n),
            columns: FixedBitSet::with_capacity(n),
        }
    }

    /// find a single uncovered (row, column) pair. Iterates in column, row order.
    #[inline]
    pub fn find_uncovered_column_row<F>(&self, mut f: F) -> Option<Position>
    where
        F: FnMut(Position) -> bool,
    {
        let n = self.n();

        for column in 0..n {
            if self.is_column_covered(column) {
                continue;
            }
            for row in 0..n {
                if self.is_row_covered(row) {
                    continue;
                }

                let pos = Position { row, column };
                if f(pos) {
                    return Some(pos);
                }
            }
        }

        return None;
    }

    /// iterates over all uncovered (row, column) pairs in row, column order
    #[inline]
    pub fn iter_uncovered_row_column<F>(&self, mut f: F)
    where
        F: FnMut(Position),
    {
        let n = self.n();

        for row in 0..n {
            if self.is_row_covered(row) {
                continue;
            }

            for column in 0..n {
                if self.is_column_covered(column) {
                    continue;
                }

                f(Position { row, column });
            }
        }
    }

    /// iterates over all uncovered (row, column) pairs in row, column order, and set covered if f returns true.
    #[inline]
    pub fn iter_uncovered_row_column_and_cover<F>(&mut self, mut f: F)
    where
        F: FnMut(Position) -> bool,
    {
        let n = self.n();

        for row in 0..n {
            if self.is_row_covered(row) {
                continue;
            }

            'column: for column in 0..n {
                if self.is_column_covered(column) {
                    continue;
                }

                let pos = Position { row, column };
                if f(pos) {
                    self.cover(pos);
                    // the complete row is covered! break the loop!
                    break 'column;
                }
            }
        }
    }

    #[inline]
    pub fn is_row_covered(&self, row: usize) -> bool {
        debug_assert!(row < self.n());
        self.rows.contains(row)
    }

    #[inline]
    pub fn is_column_covered(&self, column: usize) -> bool {
        debug_assert!(column < self.n());
        self.columns.contains(column)
    }

    #[inline]
    pub fn cover(&mut self, pos: Position) {
        self.cover_row(pos.row);
        self.cover_column(pos.column);
    }

    #[inline]
    pub fn cover_column(&mut self, column: usize) {
        debug_assert!(column < self.n());
        self.columns.set(column, true);
    }

    #[inline]
    pub fn uncover_column(&mut self, column: usize) {
        debug_assert!(column < self.n());
        self.columns.set(column, false);
    }

    #[inline]
    pub fn cover_row(&mut self, row: usize) {
        debug_assert!(row < self.n());
        self.rows.set(row, true);
    }

    pub fn clear(&mut self) {
        self.rows.clear();
        self.columns.clear();
    }

    pub fn all_uncovered(&self) -> bool {
        is_bitset_clear(&self.rows) && is_bitset_clear(&self.columns)
    }
}

fn is_bitset_clear(bitset: &FixedBitSet) -> bool {
    for elm in bitset.as_slice().iter() {
        if *elm != 0 {
            return false;
        }
    }
    return true;
}
<commit_msg>Coverage: rename {rows, columns} -> covered_{rows, columns}<commit_after>use crate::Position;
use fixedbitset::FixedBitSet;

#[derive(Debug)]
pub struct Coverage {
    n: usize,
    /// A bit is set, if the row is covered.
    covered_rows: FixedBitSet,
    /// A bit is set, if the column is covered.
    covered_columns: FixedBitSet,
}

impl Coverage {
    #[inline]
    pub fn n(&self) -> usize {
        self.n
    }

    pub fn new(n: usize) -> Coverage {
        assert!(n > 0);
        Coverage {
            n: n,
            covered_rows: FixedBitSet::with_capacity(n),
            covered_columns: FixedBitSet::with_capacity(n),
        }
    }

    /// find a single uncovered (row, column) pair. Iterates in column, row order.
    #[inline]
    pub fn find_uncovered_column_row<F>(&self, mut f: F) -> Option<Position>
    where
        F: FnMut(Position) -> bool,
    {
        let n = self.n();

        for column in 0..n {
            if self.is_column_covered(column) {
                continue;
            }
            for row in 0..n {
                if self.is_row_covered(row) {
                    continue;
                }

                let pos = Position { row, column };
                if f(pos) {
                    return Some(pos);
                }
            }
        }

        return None;
    }

    /// iterates over all uncovered (row, column) pairs in row, column order
    #[inline]
    pub fn iter_uncovered_row_column<F>(&self, mut f: F)
    where
        F: FnMut(Position),
    {
        let n = self.n();

        for row in 0..n {
            if self.is_row_covered(row) {
                continue;
            }

            for column in 0..n {
                if self.is_column_covered(column) {
                    continue;
                }

                f(Position { row, column });
            }
        }
    }

    /// iterates over all uncovered (row, column) pairs in row, column order, and set covered if f returns true.
    #[inline]
    pub fn iter_uncovered_row_column_and_cover<F>(&mut self, mut f: F)
    where
        F: FnMut(Position) -> bool,
    {
        let n = self.n();

        for row in 0..n {
            if self.is_row_covered(row) {
                continue;
            }

            'column: for column in 0..n {
                if self.is_column_covered(column) {
                    continue;
                }

                let pos = Position { row, column };
                if f(pos) {
                    self.cover(pos);
                    // the complete row is covered! break the loop!
                    break 'column;
                }
            }
        }
    }

    #[inline]
    pub fn is_row_covered(&self, row: usize) -> bool {
        debug_assert!(row < self.n());
        self.covered_rows.contains(row)
    }

    #[inline]
    pub fn is_column_covered(&self, column: usize) -> bool {
        debug_assert!(column < self.n());
        self.covered_columns.contains(column)
    }

    #[inline]
    pub fn cover(&mut self, pos: Position) {
        self.cover_row(pos.row);
        self.cover_column(pos.column);
    }

    #[inline]
    pub fn cover_column(&mut self, column: usize) {
        debug_assert!(column < self.n());
        self.covered_columns.set(column, true);
    }

    #[inline]
    pub fn uncover_column(&mut self, column: usize) {
        debug_assert!(column < self.n());
        self.covered_columns.set(column, false);
    }

    #[inline]
    pub fn cover_row(&mut self, row: usize) {
        debug_assert!(row < self.n());
        self.covered_rows.set(row, true);
    }

    pub fn clear(&mut self) {
        self.covered_rows.clear();
        self.covered_columns.clear();
    }

    pub fn all_uncovered(&self) -> bool {
        is_bitset_clear(&self.covered_rows) && is_bitset_clear(&self.covered_columns)
    }
}

fn is_bitset_clear(bitset: &FixedBitSet) -> bool {
    for elm in bitset.as_slice().iter() {
        if *elm != 0 {
            return false;
        }
    }
    return true;
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::commandinterpreter::SBCommandInterpreter;
use super::error::SBError;
use super::listener::SBListener;
use super::platform::SBPlatform;
use super::stream::SBStream;
use super::structureddata::SBStructuredData;
use super::target::SBTarget;
use std::ffi::{CStr, CString};
use std::fmt;
use std::iter;
use std::ptr;
use sys;

/// Creates [`SBTarget`]s, provides access to them and manages
/// the overall debugging experience.
///
/// # Initialization and Teardown
///
/// LLDB must be initialized before the functionality is used. This
/// is done with `SBDebugger::initialize()`:
///
/// ```
/// use lldb::SBDebugger;
///
/// SBDebugger::initialize();
/// ```
///
/// Similarly, it must be terminated after you are done using it:
///
/// ```
/// use lldb::SBDebugger;
///
/// SBDebugger::initialize();
/// // Use LLDB functionality ...
/// SBDebugger::terminate();
/// ```
///
/// Once you've initialized LLDB, you're ready to create an instance
/// of `SBDebugger`:
///
/// ```
/// use lldb::SBDebugger;
///
/// SBDebugger::initialize();
///
/// let debugger = SBDebugger::create(false);
/// // ... configure the debugger if needed ...
/// // ... create a target and do stuff ...
///
/// SBDebugger::terminate();
/// ```
///
/// # Configuration
///
/// ## Async Mode
///
/// While it is best to use LLDB in asynchronous mode, it does offer a
/// synchronous mode, which can be easier to use for quick experiments
/// or scripts.
///
/// In synchronous mode, calls to the LLDB API do not return until the
/// underlying action has been completed. This means that the thread
/// from which you call LLDB will be blocked during that time, so this
/// is not an ideal way to use LLDB for building interactive tools
/// or a new user interface.
///
/// In asynchronous mode, calls to the LLDB API will return immediately
/// without waiting for the action to complete. This means that actions
/// like launching a target, continuing the execution of a process and
/// so on won't be completed immediately and you must process events
/// to see what the results of an action are.
///
/// Synchronous mode can be enabled by using [`set_async`] and passing it
/// a `false` value. You can see if you're in asynchronous mode or not
/// by calling [`async`].
///
/// # Target Management
///
/// The `SBDebugger` instance tracks the various targets that are
/// currently known to the debugger.
///
/// Typically, you create a target with [`create_target`],
/// [`create_target_simple`] or one of the related methods.
///
/// Sometimes, you'll want to create a target without an associated
/// executable. A common use case for this is to attach to a process
/// by name or process ID where you don't know the executable in advance.
/// The most convenient way to do this is:
///
/// ```
/// # use lldb::SBDebugger;
/// # SBDebugger::initialize();
/// let debugger = SBDebugger::create(false);
/// if let Some(target) = debugger.create_target_simple("") {
///     println!("Got a target: {:?}", target);
///     // Now, maybe we'd like to attach to something.
/// }
/// # SBDebugger::terminate();
/// ```
///
/// You can iterate over these targets which have been created by
/// using [`targets`]:
///
/// ```no_run
/// # use lldb::{SBDebugger, SBTarget};
/// # fn look_at_targets(debugger: SBDebugger) {
/// // Iterate over the targets...
/// for target in debugger.targets() {
///     println!("Hello {:?}!", target);
/// }
/// // Or collect them into a vector!
/// let targets = debugger.targets().collect::<Vec<SBTarget>>();
/// # }
/// ```
///
/// # Platform Management
///
/// ...
///
/// [`SBTarget`]: struct.SBTarget.html
/// [`set_async`]: #method.set_async
/// [`async`]: #method.async
/// [`create_target`]: #method.create_target
/// [`create_target_simple`]: #method.create_target_simple
/// [`targets`]: #method.targets
pub struct SBDebugger {
    /// The underlying raw `SBDebuggerRef`.
    pub raw: sys::SBDebuggerRef,
}

impl SBDebugger {
    /// Initialize LLDB.
    ///
    /// This should be called before LLDB functionality is used.
    pub fn initialize() {
        unsafe { sys::SBDebuggerInitialize() };
    }

    /// Tear down LLDB.
    ///
    /// This should be called once the application no longer needs
    /// to use LLDB functionality. Typically, this is called as the
    /// application exits.
    pub fn terminate() {
        unsafe { sys::SBDebuggerTerminate() };
    }

    /// Create a new instance of `SBDebugger`.
    ///
    /// If `source_init_files` is `true`, then `~/.lldbinit` will
    /// be processed.
    pub fn create(source_init_files: bool) -> SBDebugger {
        SBDebugger {
            raw: unsafe { sys::SBDebuggerCreate2(source_init_files as u8) },
        }
    }

    /// Get whether or not the debugger is in async mode.
    ///
    /// When in async mode, the debugger returns immediately when
    /// stepping or continuing without waiting for the process
    /// to change state.
    pub fn async(&self) -> bool {
        unsafe { sys::SBDebuggerGetAsync(self.raw) != 0 }
    }

    /// Set the debugger to be in async mode or not.
    ///
    /// When in async mode, the debugger returns immediately when
    /// stepping or continuing without waiting for the process
    /// to change state.
    pub fn set_async(&self, async: bool) {
        unsafe { sys::SBDebuggerSetAsync(self.raw, async as u8) }
    }

    #[allow(missing_docs)]
    pub fn command_interpreter(&self) -> SBCommandInterpreter {
        SBCommandInterpreter::wrap(unsafe { sys::SBDebuggerGetCommandInterpreter(self.raw) })
    }

    /// Enable logging (defaults to `stderr`).
    ///
    /// `enable_log("lldb", &["default"])` is useful for troubleshooting in most
    /// cases. Include `"all"` in `categories` for extra verbosity.
    ///
    /// See invocations to `lldb_private::Log::Register` for more channels and
    /// categories.
    pub fn enable_log(&mut self, channel: &str, categories: &[&str]) -> bool {
        let channel = CString::new(channel).unwrap();
        let categories: Vec<_> = categories
            .into_iter()
            .map(|&s| CString::new(s).unwrap())
            .collect();
        let mut categories_ptr: Vec<_> = categories
            .iter()
            .map(|s| s.as_ptr())
            .chain(iter::once(ptr::null()))
            .collect();
        let ret = unsafe {
            sys::SBDebuggerEnableLog(self.raw, channel.as_ptr(), categories_ptr.as_mut_ptr())
        };
        ret != 0
    }

    /// Get the LLDB version string.
    pub fn version() -> String {
        unsafe {
            match CStr::from_ptr(sys::SBDebuggerGetVersionString()).to_str() {
                Ok(s) => s.to_owned(),
                _ => panic!("No version string?"),
            }
        }
    }

    /// Create a target.
    ///
    /// The executable name may be an empty string to create
    /// an empty target.
    pub fn create_target(
        &self,
        executable: &str,
        target_triple: Option<&str>,
        platform_name: Option<&str>,
        add_dependent_modules: bool,
    ) -> Result<SBTarget, SBError> {
        let executable = CString::new(executable).unwrap();
        let target_triple = target_triple.map(|s| CString::new(s).unwrap());
        let platform_name = platform_name.map(|s| CString::new(s).unwrap());
        let error = SBError::new();
        let target = unsafe {
            sys::SBDebuggerCreateTarget(
                self.raw,
                executable.as_ptr(),
                target_triple.map_or(ptr::null(), |s| s.as_ptr()),
                platform_name.map_or(ptr::null(), |s| s.as_ptr()),
                add_dependent_modules as u8,
                error.raw,
            )
        };
        if error.is_success() {
            Ok(SBTarget::wrap(target))
        } else {
            Err(error)
        }
    }

    /// Create a target from just an executable name.
    ///
    /// The executable name may be an empty string to create
    /// an empty target.
    ///
    /// Using [`create_target`] is preferred in most cases as
    /// that provides access to an `SBError` to inform the caller
    /// about what might have gone wrong.
    pub fn create_target_simple(&self, executable: &str) -> Option<SBTarget> {
        let executable = CString::new(executable).unwrap();
        SBTarget::maybe_wrap(unsafe { sys::SBDebuggerCreateTarget2(self.raw, executable.as_ptr()) })
    }

    /// Get an iterator over the [targets] known to this debugger instance.
    ///
    /// [targets]: struct.SBTarget.html
    pub fn targets(&self) -> SBDebuggerTargetIter {
        SBDebuggerTargetIter {
            debugger: self,
            idx: 0,
        }
    }

    /// Get the default [SBListener] associated with the debugger.
    ///
    /// [SBListener]: struct.SBListener.html
    pub fn listener(&self) -> SBListener {
        SBListener::wrap(unsafe { sys::SBDebuggerGetListener(self.raw) })
    }

    /// Get the currently selected [`SBTarget`].
    ///
    /// [SBTarget]: struct.SBTarget.html
    pub fn selected_target(&self) -> Option<SBTarget> {
        SBTarget::maybe_wrap(unsafe { sys::SBDebuggerGetSelectedTarget(self.raw) })
    }

    /// Set the selected [`SBTarget`].
    ///
    /// [SBTarget]: struct.SBTarget.html
    pub fn set_selected_target(&self, target: &SBTarget) {
        unsafe { sys::SBDebuggerSetSelectedTarget(self.raw, target.raw) };
    }

    /// Get the currently selected [`SBPlatform`].
    ///
    /// [`SBPlatform`]: struct.SBPlatform.html
    pub fn selected_platform(&self) -> SBPlatform {
        unsafe {
            SBPlatform {
                raw: sys::SBDebuggerGetSelectedPlatform(self.raw),
            }
        }
    }

    /// Set the selected [`SBPlatform`].
    ///
    /// [`SBPlatform`]: struct.SBPlatform.html
    pub fn set_selected_platform(&self, platform: &SBPlatform) {
        unsafe { sys::SBDebuggerSetSelectedPlatform(self.raw, platform.raw) };
    }

    /// Get an iterator over the [platforms] known to this debugger instance.
    ///
    /// [platforms]: struct.SBPlatform.html
    pub fn platforms(&self) -> SBDebuggerPlatformIter {
        SBDebuggerPlatformIter {
            debugger: self,
            idx: 0,
        }
    }

    /// Get an iterator over the available platforms known to this debugger instance.
    pub fn available_platforms(&self) -> SBDebuggerAvailablePlatformIter {
        SBDebuggerAvailablePlatformIter {
            debugger: self,
            idx: 0,
        }
    }
}

/// Iterate over the [targets] known to a [debugger].
///
/// [targets]: struct.SBTarget.html
/// [debugger]: struct.SBDebugger.html
pub struct SBDebuggerTargetIter<'d> {
    debugger: &'d SBDebugger,
    idx: usize,
}

impl<'d> Iterator for SBDebuggerTargetIter<'d> {
    type Item = SBTarget;

    fn next(&mut self) -> Option<SBTarget> {
        if self.idx < unsafe { sys::SBDebuggerGetNumTargets(self.debugger.raw) as usize } {
            let r = Some(SBTarget {
                raw: unsafe { sys::SBDebuggerGetTargetAtIndex(self.debugger.raw, self.idx as u32) },
            });
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBDebuggerGetNumTargets(self.debugger.raw) } as usize;
        (sz - self.idx, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBDebuggerTargetIter<'d> {}

impl fmt::Debug for SBDebugger {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let stream = SBStream::new();
        unsafe { sys::SBDebuggerGetDescription(self.raw, stream.raw) };
        write!(fmt, "SBDebugger {{ {} }}", stream.data())
    }
}

impl Drop for SBDebugger {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBDebugger(self.raw) };
    }
}

unsafe impl Send for SBDebugger {}
unsafe impl Sync for SBDebugger {}

/// Iterate over the [platforms].
///
/// [platforms]: struct.SBPlatform.html
pub struct SBDebuggerPlatformIter<'d> {
    debugger: &'d SBDebugger,
    idx: u32,
}

impl<'d> Iterator for SBDebuggerPlatformIter<'d> {
    type Item = SBPlatform;

    fn next(&mut self) -> Option<SBPlatform> {
        if self.idx < unsafe { sys::SBDebuggerGetNumPlatforms(self.debugger.raw) } {
            let r = Some(SBPlatform::wrap(unsafe {
                sys::SBDebuggerGetPlatformAtIndex(self.debugger.raw, self.idx)
            }));
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBDebuggerGetNumPlatforms(self.debugger.raw) } as usize;
        (sz - self.idx as usize, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBDebuggerPlatformIter<'d> {}

/// Iterate over the available platforms.
pub struct SBDebuggerAvailablePlatformIter<'d> {
    debugger: &'d SBDebugger,
    idx: u32,
}

impl<'d> Iterator for SBDebuggerAvailablePlatformIter<'d> {
    type Item = SBStructuredData;

    fn next(&mut self) -> Option<SBStructuredData> {
        if self.idx < unsafe { sys::SBDebuggerGetNumAvailablePlatforms(self.debugger.raw) } {
            let r = Some(SBStructuredData::wrap(unsafe {
                sys::SBDebuggerGetAvailablePlatformInfoAtIndex(self.debugger.raw, self.idx)
            }));
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBDebuggerGetNumAvailablePlatforms(self.debugger.raw) } as usize;
        (sz - self.idx as usize, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBDebuggerAvailablePlatformIter<'d> {}

#[cfg(feature = "graphql")]
impl ::juniper::Context for SBDebugger {}

#[cfg(feature = "graphql")]
graphql_object!(SBDebugger: SBDebugger | &self | {
    field targets() -> Vec<SBTarget> {
        self.targets().collect()
    }

    field selected_target() -> Option<SBTarget> {
        self.selected_target()
    }

    field selected_platform() -> SBPlatform {
        self.selected_platform()
    }

    field platforms() -> Vec<SBPlatform> {
        self.platforms().collect()
    }

    field available_platforms() -> Vec<SBStructuredData> {
        self.available_platforms().collect()
    }
});

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

    #[test]
    fn it_works() {
        assert!(!SBDebugger::version().is_empty());
    }
}
<commit_msg>Fix link to SBDebugger::create_target().<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::commandinterpreter::SBCommandInterpreter;
use super::error::SBError;
use super::listener::SBListener;
use super::platform::SBPlatform;
use super::stream::SBStream;
use super::structureddata::SBStructuredData;
use super::target::SBTarget;
use std::ffi::{CStr, CString};
use std::fmt;
use std::iter;
use std::ptr;
use sys;

/// Creates [`SBTarget`]s, provides access to them and manages
/// the overall debugging experience.
///
/// # Initialization and Teardown
///
/// LLDB must be initialized before the functionality is used. This
/// is done with `SBDebugger::initialize()`:
///
/// ```
/// use lldb::SBDebugger;
///
/// SBDebugger::initialize();
/// ```
///
/// Similarly, it must be terminated after you are done using it:
///
/// ```
/// use lldb::SBDebugger;
///
/// SBDebugger::initialize();
/// // Use LLDB functionality ...
/// SBDebugger::terminate();
/// ```
///
/// Once you've initialized LLDB, you're ready to create an instance
/// of `SBDebugger`:
///
/// ```
/// use lldb::SBDebugger;
///
/// SBDebugger::initialize();
///
/// let debugger = SBDebugger::create(false);
/// // ... configure the debugger if needed ...
/// // ... create a target and do stuff ...
///
/// SBDebugger::terminate();
/// ```
///
/// # Configuration
///
/// ## Async Mode
///
/// While it is best to use LLDB in asynchronous mode, it does offer a
/// synchronous mode, which can be easier to use for quick experiments
/// or scripts.
///
/// In synchronous mode, calls to the LLDB API do not return until the
/// underlying action has been completed. This means that the thread
/// from which you call LLDB will be blocked during that time, so this
/// is not an ideal way to use LLDB for building interactive tools
/// or a new user interface.
///
/// In asynchronous mode, calls to the LLDB API will return immediately
/// without waiting for the action to complete. This means that actions
/// like launching a target, continuing the execution of a process and
/// so on won't be completed immediately and you must process events
/// to see what the results of an action are.
///
/// Synchronous mode can be enabled by using [`set_async`] and passing it
/// a `false` value. You can see if you're in asynchronous mode or not
/// by calling [`async`].
///
/// # Target Management
///
/// The `SBDebugger` instance tracks the various targets that are
/// currently known to the debugger.
///
/// Typically, you create a target with [`create_target`],
/// [`create_target_simple`] or one of the related methods.
///
/// Sometimes, you'll want to create a target without an associated
/// executable. A common use case for this is to attach to a process
/// by name or process ID where you don't know the executable in advance.
/// The most convenient way to do this is:
///
/// ```
/// # use lldb::SBDebugger;
/// # SBDebugger::initialize();
/// let debugger = SBDebugger::create(false);
/// if let Some(target) = debugger.create_target_simple("") {
///     println!("Got a target: {:?}", target);
///     // Now, maybe we'd like to attach to something.
/// }
/// # SBDebugger::terminate();
/// ```
///
/// You can iterate over these targets which have been created by
/// using [`targets`]:
///
/// ```no_run
/// # use lldb::{SBDebugger, SBTarget};
/// # fn look_at_targets(debugger: SBDebugger) {
/// // Iterate over the targets...
/// for target in debugger.targets() {
///     println!("Hello {:?}!", target);
/// }
/// // Or collect them into a vector!
/// let targets = debugger.targets().collect::<Vec<SBTarget>>();
/// # }
/// ```
///
/// # Platform Management
///
/// ...
///
/// [`SBTarget`]: struct.SBTarget.html
/// [`set_async`]: #method.set_async
/// [`async`]: #method.async
/// [`create_target`]: #method.create_target
/// [`create_target_simple`]: #method.create_target_simple
/// [`targets`]: #method.targets
pub struct SBDebugger {
    /// The underlying raw `SBDebuggerRef`.
    pub raw: sys::SBDebuggerRef,
}

impl SBDebugger {
    /// Initialize LLDB.
    ///
    /// This should be called before LLDB functionality is used.
    pub fn initialize() {
        unsafe { sys::SBDebuggerInitialize() };
    }

    /// Tear down LLDB.
    ///
    /// This should be called once the application no longer needs
    /// to use LLDB functionality. Typically, this is called as the
    /// application exits.
    pub fn terminate() {
        unsafe { sys::SBDebuggerTerminate() };
    }

    /// Create a new instance of `SBDebugger`.
    ///
    /// If `source_init_files` is `true`, then `~/.lldbinit` will
    /// be processed.
    pub fn create(source_init_files: bool) -> SBDebugger {
        SBDebugger {
            raw: unsafe { sys::SBDebuggerCreate2(source_init_files as u8) },
        }
    }

    /// Get whether or not the debugger is in async mode.
    ///
    /// When in async mode, the debugger returns immediately when
    /// stepping or continuing without waiting for the process
    /// to change state.
    pub fn async(&self) -> bool {
        unsafe { sys::SBDebuggerGetAsync(self.raw) != 0 }
    }

    /// Set the debugger to be in async mode or not.
    ///
    /// When in async mode, the debugger returns immediately when
    /// stepping or continuing without waiting for the process
    /// to change state.
    pub fn set_async(&self, async: bool) {
        unsafe { sys::SBDebuggerSetAsync(self.raw, async as u8) }
    }

    #[allow(missing_docs)]
    pub fn command_interpreter(&self) -> SBCommandInterpreter {
        SBCommandInterpreter::wrap(unsafe { sys::SBDebuggerGetCommandInterpreter(self.raw) })
    }

    /// Enable logging (defaults to `stderr`).
    ///
    /// `enable_log("lldb", &["default"])` is useful for troubleshooting in most
    /// cases. Include `"all"` in `categories` for extra verbosity.
    ///
    /// See invocations to `lldb_private::Log::Register` for more channels and
    /// categories.
    pub fn enable_log(&mut self, channel: &str, categories: &[&str]) -> bool {
        let channel = CString::new(channel).unwrap();
        let categories: Vec<_> = categories
            .into_iter()
            .map(|&s| CString::new(s).unwrap())
            .collect();
        let mut categories_ptr: Vec<_> = categories
            .iter()
            .map(|s| s.as_ptr())
            .chain(iter::once(ptr::null()))
            .collect();
        let ret = unsafe {
            sys::SBDebuggerEnableLog(self.raw, channel.as_ptr(), categories_ptr.as_mut_ptr())
        };
        ret != 0
    }

    /// Get the LLDB version string.
    pub fn version() -> String {
        unsafe {
            match CStr::from_ptr(sys::SBDebuggerGetVersionString()).to_str() {
                Ok(s) => s.to_owned(),
                _ => panic!("No version string?"),
            }
        }
    }

    /// Create a target.
    ///
    /// The executable name may be an empty string to create
    /// an empty target.
    pub fn create_target(
        &self,
        executable: &str,
        target_triple: Option<&str>,
        platform_name: Option<&str>,
        add_dependent_modules: bool,
    ) -> Result<SBTarget, SBError> {
        let executable = CString::new(executable).unwrap();
        let target_triple = target_triple.map(|s| CString::new(s).unwrap());
        let platform_name = platform_name.map(|s| CString::new(s).unwrap());
        let error = SBError::new();
        let target = unsafe {
            sys::SBDebuggerCreateTarget(
                self.raw,
                executable.as_ptr(),
                target_triple.map_or(ptr::null(), |s| s.as_ptr()),
                platform_name.map_or(ptr::null(), |s| s.as_ptr()),
                add_dependent_modules as u8,
                error.raw,
            )
        };
        if error.is_success() {
            Ok(SBTarget::wrap(target))
        } else {
            Err(error)
        }
    }

    /// Create a target from just an executable name.
    ///
    /// The executable name may be an empty string to create
    /// an empty target.
    ///
    /// Using [`create_target`] is preferred in most cases as
    /// that provides access to an `SBError` to inform the caller
    /// about what might have gone wrong.
    ///
    /// [`create_target`]: struct.SBDebugger.html#method.create_target
    pub fn create_target_simple(&self, executable: &str) -> Option<SBTarget> {
        let executable = CString::new(executable).unwrap();
        SBTarget::maybe_wrap(unsafe { sys::SBDebuggerCreateTarget2(self.raw, executable.as_ptr()) })
    }

    /// Get an iterator over the [targets] known to this debugger instance.
    ///
    /// [targets]: struct.SBTarget.html
    pub fn targets(&self) -> SBDebuggerTargetIter {
        SBDebuggerTargetIter {
            debugger: self,
            idx: 0,
        }
    }

    /// Get the default [SBListener] associated with the debugger.
    ///
    /// [SBListener]: struct.SBListener.html
    pub fn listener(&self) -> SBListener {
        SBListener::wrap(unsafe { sys::SBDebuggerGetListener(self.raw) })
    }

    /// Get the currently selected [`SBTarget`].
    ///
    /// [SBTarget]: struct.SBTarget.html
    pub fn selected_target(&self) -> Option<SBTarget> {
        SBTarget::maybe_wrap(unsafe { sys::SBDebuggerGetSelectedTarget(self.raw) })
    }

    /// Set the selected [`SBTarget`].
    ///
    /// [SBTarget]: struct.SBTarget.html
    pub fn set_selected_target(&self, target: &SBTarget) {
        unsafe { sys::SBDebuggerSetSelectedTarget(self.raw, target.raw) };
    }

    /// Get the currently selected [`SBPlatform`].
    ///
    /// [`SBPlatform`]: struct.SBPlatform.html
    pub fn selected_platform(&self) -> SBPlatform {
        unsafe {
            SBPlatform {
                raw: sys::SBDebuggerGetSelectedPlatform(self.raw),
            }
        }
    }

    /// Set the selected [`SBPlatform`].
    ///
    /// [`SBPlatform`]: struct.SBPlatform.html
    pub fn set_selected_platform(&self, platform: &SBPlatform) {
        unsafe { sys::SBDebuggerSetSelectedPlatform(self.raw, platform.raw) };
    }

    /// Get an iterator over the [platforms] known to this debugger instance.
    ///
    /// [platforms]: struct.SBPlatform.html
    pub fn platforms(&self) -> SBDebuggerPlatformIter {
        SBDebuggerPlatformIter {
            debugger: self,
            idx: 0,
        }
    }

    /// Get an iterator over the available platforms known to this debugger instance.
    pub fn available_platforms(&self) -> SBDebuggerAvailablePlatformIter {
        SBDebuggerAvailablePlatformIter {
            debugger: self,
            idx: 0,
        }
    }
}

/// Iterate over the [targets] known to a [debugger].
///
/// [targets]: struct.SBTarget.html
/// [debugger]: struct.SBDebugger.html
pub struct SBDebuggerTargetIter<'d> {
    debugger: &'d SBDebugger,
    idx: usize,
}

impl<'d> Iterator for SBDebuggerTargetIter<'d> {
    type Item = SBTarget;

    fn next(&mut self) -> Option<SBTarget> {
        if self.idx < unsafe { sys::SBDebuggerGetNumTargets(self.debugger.raw) as usize } {
            let r = Some(SBTarget {
                raw: unsafe { sys::SBDebuggerGetTargetAtIndex(self.debugger.raw, self.idx as u32) },
            });
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBDebuggerGetNumTargets(self.debugger.raw) } as usize;
        (sz - self.idx, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBDebuggerTargetIter<'d> {}

impl fmt::Debug for SBDebugger {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let stream = SBStream::new();
        unsafe { sys::SBDebuggerGetDescription(self.raw, stream.raw) };
        write!(fmt, "SBDebugger {{ {} }}", stream.data())
    }
}

impl Drop for SBDebugger {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBDebugger(self.raw) };
    }
}

unsafe impl Send for SBDebugger {}
unsafe impl Sync for SBDebugger {}

/// Iterate over the [platforms].
///
/// [platforms]: struct.SBPlatform.html
pub struct SBDebuggerPlatformIter<'d> {
    debugger: &'d SBDebugger,
    idx: u32,
}

impl<'d> Iterator for SBDebuggerPlatformIter<'d> {
    type Item = SBPlatform;

    fn next(&mut self) -> Option<SBPlatform> {
        if self.idx < unsafe { sys::SBDebuggerGetNumPlatforms(self.debugger.raw) } {
            let r = Some(SBPlatform::wrap(unsafe {
                sys::SBDebuggerGetPlatformAtIndex(self.debugger.raw, self.idx)
            }));
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBDebuggerGetNumPlatforms(self.debugger.raw) } as usize;
        (sz - self.idx as usize, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBDebuggerPlatformIter<'d> {}

/// Iterate over the available platforms.
pub struct SBDebuggerAvailablePlatformIter<'d> {
    debugger: &'d SBDebugger,
    idx: u32,
}

impl<'d> Iterator for SBDebuggerAvailablePlatformIter<'d> {
    type Item = SBStructuredData;

    fn next(&mut self) -> Option<SBStructuredData> {
        if self.idx < unsafe { sys::SBDebuggerGetNumAvailablePlatforms(self.debugger.raw) } {
            let r = Some(SBStructuredData::wrap(unsafe {
                sys::SBDebuggerGetAvailablePlatformInfoAtIndex(self.debugger.raw, self.idx)
            }));
            self.idx += 1;
            r
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBDebuggerGetNumAvailablePlatforms(self.debugger.raw) } as usize;
        (sz - self.idx as usize, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBDebuggerAvailablePlatformIter<'d> {}

#[cfg(feature = "graphql")]
impl ::juniper::Context for SBDebugger {}

#[cfg(feature = "graphql")]
graphql_object!(SBDebugger: SBDebugger | &self | {
    field targets() -> Vec<SBTarget> {
        self.targets().collect()
    }

    field selected_target() -> Option<SBTarget> {
        self.selected_target()
    }

    field selected_platform() -> SBPlatform {
        self.selected_platform()
    }

    field platforms() -> Vec<SBPlatform> {
        self.platforms().collect()
    }

    field available_platforms() -> Vec<SBStructuredData> {
        self.available_platforms().collect()
    }
});

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

    #[test]
    fn it_works() {
        assert!(!SBDebugger::version().is_empty());
    }
}
<|endoftext|>


<commit_before>pub struct Server{
    hostname: &'static str,
    port: u16
}

impl Server {

    pub fn new(hostname: &'static str, port: u16) -> Server {
        Server { hostname:hostname, port:port }
    }

    pub fn hostname(&self) -> &'static str {
        self.hostname
    }

    pub fn port(&self) -> u16 {
        self.port
    }
}

pub struct User {
    nick: &'static str,
    ident: &'static str,
    hostname: &'static str,
    realname: &'static str
}

impl User {

    pub fn new(nick: &'static str, ident: &'static str, hostname: &'static str, realname: &'static str) -> User {
        User { nick:nick, ident:ident, hostname:hostname, realname:realname }
    }

    pub fn nick(&self) -> &'static str {
        self.nick
    }

    pub fn ident(&self) -> &'static str {
        self.ident
    }

    pub fn host(&self) -> &'static str {
        self.hostname
    }

    pub fn realname(&self) -> &'static str {
        self.realname
    }
}

pub struct Channel {
    name: &'static str,
    usercount: u16
}

impl Channel {
    pub fn new(name: &'static str) -> Channel {
        Channel { name:name, usercount: 0u16 }
    }

    pub fn usercount(&self) -> u16 {
        self.usercount
    }

    pub fn name(&self) -> &'static str {
        self.name
    }
}
<commit_msg>Implement Copy for Structures<commit_after>pub struct Server{
    hostname: &'static str,
    port: u16
}

impl Server {

    pub fn new(hostname: &'static str, port: u16) -> Server {
        Server { hostname:hostname, port:port }
    }

    pub fn hostname(&self) -> &'static str {
        self.hostname
    }

    pub fn port(&self) -> u16 {
        self.port
    }
}

impl Copy for Server { }

pub struct User {
    nick: &'static str,
    ident: &'static str,
    hostname: &'static str,
    realname: &'static str
}

impl User {

    pub fn new(nick: &'static str, ident: &'static str, hostname: &'static str, realname: &'static str) -> User {
        User { nick:nick, ident:ident, hostname:hostname, realname:realname }
    }

    pub fn nick(&self) -> &'static str {
        self.nick
    }

    pub fn ident(&self) -> &'static str {
        self.ident
    }

    pub fn host(&self) -> &'static str {
        self.hostname
    }

    pub fn realname(&self) -> &'static str {
        self.realname
    }
}

impl Copy for User { }

pub struct Channel {
    name: &'static str,
    usercount: u16
}

impl Channel {
    pub fn new(name: &'static str) -> Channel {
        Channel { name:name, usercount: 0u16 }
    }

    pub fn usercount(&self) -> u16 {
        self.usercount
    }

    pub fn name(&self) -> &'static str {
        self.name
    }
}

impl Copy for Channel { }
<|endoftext|>


<commit_before>// Copyright (2015-2017) Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

use std::default::Default;
use std::ops::{Mul, Div, MulAssign, DivAssign};
use std::cmp::{min,max};
use std::collections::BTreeMap;

use num;
use num::{One, Num, Integer, FromPrimitive};

use crate::FactorExt;

/// An integer stored as its prime factorization.
///
/// A `Factored` represents a non-negative integer stored in the form
///
/// ```text
/// pow(p1, n1) * pow(p2, n2) * ... * pow(pN, nN)
/// ```
///
/// where `p1, p2, ...` are prime numbers (or zero) and `n1, n2, ...` are positive
/// integers. Some properties are easier to compute in this form, such as the euler
/// totient, or a sum of divisors. Also of note is that because the prime factorization
/// of any given number is unique, any two `Factorization`s constructed from the same
/// `x` are equal.
///
/// Negative numbers, zero, as well as negative powers (i.e. rationals) are not
/// permitted.
///
/// One caveat:  It is not feasible for `Factorization` to enforce that the prime
///  factors it is built from are actually prime.  This is the job of the
///  `TryFactor` used to produce it!  The behavior of any mathematical method
///  on a `Factorization` with a composite factor is **undefined**. (in the sense
///  of nonsensical results; not in the sense that the safety guidelines of Rust
///  may be violated)
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct Factored<X> {
    // powers are currently usize for consistency with the pow() function
    //  in the num crate.
    powers: BTreeMap<X, usize>,
}

// TODO: some of Factorization's methods need to be special cased for Zero

impl<X> Factored<X>
where
    X: Ord,
{
    /// Set the power of a prime factor in the `Factorization`. `prime` is
    ///  assumed to be prime. Note that while composite numbers
    ///  may be accepted, the behavior of the resulting `Factorization` is
    ///  ill-defined.
    // NOTE: No diagnostic is provided because it would require some sort
    //  of additional bound like Zero, One, or NumCast.
    pub fn set(&mut self, prime: X, exp: usize) {
        match exp {
            0 => self.powers.remove(&prime),
            _ => self.powers.insert(prime, exp),
        };
    }

    /// Get the power of a prime factor in the `Factorization`. `prime` is
    ///  assumed to be prime. The value returned for non-prime
    ///  keys is undefined.
    pub fn get(&self, prime: &X) -> usize {
        match self.powers.get(prime) {
            None => 0,
            Some(&exp) => exp,
        }
    }

    /// Create a `Factored` from a single prime.
    ///
    /// Do not use on a composite number (use `factor::factorize`)
    /// or one (use `One::one()`).
    pub fn from_prime(prime: X) -> Self {
        Factored {
            powers: ::std::iter::once((prime, 1)).collect(),
        }
    }

    /// Recover the integer represented by the `Factored`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.product(), 20);
    /// ```
    pub fn product(&self) -> X
    where
        X: Clone + One,
    {
        self.iter().map(clone2).factor_product()
    }

    /// Compute the total number of positive integers which evenly divide
    ///  a number from its prime decomposition.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.divisor_count(), 6);
    /// ```
    pub fn divisor_count(&self) -> X
    where
        X: Clone + FromPrimitive + One,
    {
        self.iter().map(clone2).divisor_count()
    }

    /// Compute the sum of all positive integers which evenly divide the number
    ///  represented by the `Factored` (including 1 and the number itself).
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.divisor_sum(), 42);
    /// ```
    pub fn divisor_sum(&self) -> X
    where
        X: Clone + One + Num,
    {
        self.iter().map(clone2).divisor_sum()
    }

    /// Compute the Euler totient `phi(x)`, the total number of
    ///  positive integers less than `x` that are coprime to `x`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.totient(), 8);
    /// ```
    pub fn totient(&self) -> X
    where
        X: Clone + One + Num,
    {
        self.iter().map(clone2).totient()
    }

    /// Compute the value modulo `m`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f: factor::Factored<_> = (1..=20u64).map(factor::factorize).product();
    /// assert_eq!(f.product_mod(&1297), 278);
    /// ```
    pub fn product_mod(self, modulus: &X) -> X
    where
        X: Clone + One + Integer,
        Self: Sized,
    {
        self.iter().map(clone2).factor_product_mod(modulus)
    }
}

impl<X> Factored<X>
where
    X: Ord,
{
    /// Get the square root of a perfect square.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let mut f = factorize(20u64);
    /// assert!(f.clone().sqrt().is_none());    // 20 is not square!
    ///
    /// f = f * factorize(5);
    /// assert_eq!(f.sqrt().unwrap().product(), 10);  // sqrt(100)
    /// ```
    pub fn sqrt(self) -> Option<Self> {
        self.root(2)
    }

    /// Get the nth root of a perfect nth power.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let mut f = factorize(20u64);
    /// assert!(f.clone().root(3).is_none());    // 20 is not a cube!
    ///
    /// f = f * factorize(50);
    /// assert_eq!(f.root(3).unwrap().product(), 10);  // cbrt(1000)
    /// ```
    pub fn root(mut self, n: usize) -> Option<Self> {
        for (_, v) in self.powers.iter_mut() {
            if *v % n == 1 {
                return None; // Not a root!  Abort!  Abort!
            };

            *v = *v / n;
        }
        Some(self)
    }

    // TODO: Docs & test
    pub fn pow(mut self, pwr: usize) -> Self
    where
        X: Clone,
    {
        for (_, v) in self.powers.iter_mut() {
            *v = *v * pwr;
        }
        self
    }

    /*
        // TODO: Docs & test
        pub fn gcd(mut self, other: mut Self) -> Self
         where X: Clone,
        {
            // Iterate through shorter list
            if other.powers.len() < self.powers.len() {
                return self.gcd(other);
            };

            let mut result: Self = One::one();
            for (k,v) in other {
                self.set(k.clone(), min(self.get(&k), v));
            };
            self
        }

        // TODO: Docs & test
        pub fn lcm(&self, other: &Self) -> Self
         where X: Clone,
        {
            let mut result = self.clone();
            for (k,v) in self.powers.clone().into_iter() {
                self.set(k.clone(), max(self.get(&k), v));
            };
            self
        }
    */

    /// Divide by another factorized value.
    ///
    /// Cannot produce fractional values.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// assert_eq!(factorize(15u64).checked_div(factorize(5u64)), Some(factorize(3u64)));
    /// assert_eq!(factorize(15u64).checked_div(factorize(2u64)), None);
    /// ```
    pub fn checked_div(&self, other: impl FactorExt<X>) -> Option<Factored<X>>
    where
        X: Clone,
    {
        let mut result = self.clone();
        for (k, v) in other {
            let current = result.get(&k);
            match current.checked_sub(v) {
                Some(v) => result.set(k.clone(), v),
                None => return None,
            }
        }
        Some(result)
    }

    /// Iterate over unique prime factors.
    ///
    /// Item type is `&X`.
    pub fn primes(&self) -> Primes<'_, X> {
        self.powers.keys()
    }

    /// Iterate over `(prime, power)` pairs.
    ///
    /// Item type is `(&X, usize)`.
    pub fn iter(&self) -> Iter<'_, X> {
        self.powers.iter()
    }

    /// Immutably borrow the underlying map.
    pub fn as_btree_map(&self) -> &BTreeMap<X, usize> {
        &self.powers
    }
    /// Mutably borrow the underlying map.
    ///
    /// This is provided on the grounds of "eh, why the hell not."  After all,
    /// it's not exactly like `Factored` was doing a very good job at protecting
    /// any of its invariants to begin with.
    pub fn as_mut_btree_map(&mut self) -> &mut BTreeMap<X, usize> {
        &mut self.powers
    }
    /// Consume to obtain the underlying map.
    pub fn into_btree_map(self) -> BTreeMap<X, usize> {
        self.powers
    }

    /// Construct from a map of unique `(prime, power)` pairs.
    pub fn from_btree_map(map: BTreeMap<X, usize>) -> Self {
        Factored { powers: map }
    }

    /// Construct from an iterator of unique `(prime, power)` pairs.
    pub fn from_iter<I: IntoIterator<Item = (X, usize)>>(iter: I) -> Self {
        Factored::from_btree_map(iter.into_iter().collect())
    }

    // TODO: Reasonable (?) methods to implement
    // pub fn is_multiple_of(&self, other: &Self) -> bool
}

impl<X> One for Factored<X>
where
    X: Ord + Clone,
{
    /// Create a `Factored` representing `1`.
    fn one() -> Self {
        Self::from_btree_map(BTreeMap::new())
    }
}

impl<X> Default for Factored<X>
where
    X: Ord + Clone,
{
    /// Create a `Factored` representing `1`.
    fn default() -> Self {
        One::one()
    }
}

impl<X> Mul<Factored<X>> for Factored<X>
where
    X: Ord + Clone,
{
    type Output = Self;
    fn mul(self, other: Self) -> Self {
        let mut result = self;
        for (k, v) in other.powers.into_iter() {
            let current = result.get(&k);
            result.set(k.clone(), current + v);
        }
        result
    }
}

impl<X> std::iter::Product for Factored<X>
where
    X: Ord + Clone,
{
    fn product<I: Iterator<Item=Factored<X>>>(iter: I) -> Self {
        iter.fold(Default::default(), |acc, x| acc * x)
    }
}

impl<X: Ord> IntoIterator for Factored<X>
{
    type Item = (X, usize);
    type IntoIter = IntoIter<X>;

    fn into_iter(self) -> Self::IntoIter { self.powers.into_iter() }
}

//------------------------------------

pub type Iter<'a, T> = ::std::collections::btree_map::Iter<'a, T, usize>;
pub type IntoIter<T> = ::std::collections::btree_map::IntoIter<T, usize>;
pub type Primes<'a, T> = ::std::collections::btree_map::Keys<'a, T, usize>;

#[inline]
fn clone2<A, B>((a, b): (&A, &B)) -> (A, B)
where
    A: Clone,
    B: Clone,
{
    (a.clone(), b.clone())
}
<commit_msg>impl Div,MulAssign,DivAssign for Factored<commit_after>// Copyright (2015-2017) Michael 'ExpHP' Lamparski
//
// Licensed under the terms of the MIT License, available at:
//  http://opensource.org/licenses/MIT
// and also included in the file COPYING at the root of this distribution.
// This file may not be copied, modified, or distributed except according
// to those terms.

use std::default::Default;
use std::ops::{Mul, Div, MulAssign, DivAssign};
use std::cmp::{min,max};
use std::collections::BTreeMap;

use num;
use num::{One, Num, Integer, FromPrimitive};

use crate::FactorExt;

/// An integer stored as its prime factorization.
///
/// A `Factored` represents a non-negative integer stored in the form
///
/// ```text
/// pow(p1, n1) * pow(p2, n2) * ... * pow(pN, nN)
/// ```
///
/// where `p1, p2, ...` are prime numbers (or zero) and `n1, n2, ...` are positive
/// integers. Some properties are easier to compute in this form, such as the euler
/// totient, or a sum of divisors. Also of note is that because the prime factorization
/// of any given number is unique, any two `Factorization`s constructed from the same
/// `x` are equal.
///
/// Negative numbers, zero, as well as negative powers (i.e. rationals) are not
/// permitted.
///
/// One caveat:  It is not feasible for `Factorization` to enforce that the prime
///  factors it is built from are actually prime.  This is the job of the
///  `TryFactor` used to produce it!  The behavior of any mathematical method
///  on a `Factorization` with a composite factor is **undefined**. (in the sense
///  of nonsensical results; not in the sense that the safety guidelines of Rust
///  may be violated)
#[derive(Eq, PartialEq, Debug, Clone)]
pub struct Factored<X> {
    // powers are currently usize for consistency with the pow() function
    //  in the num crate.
    powers: BTreeMap<X, usize>,
}

// TODO: some of Factorization's methods need to be special cased for Zero

impl<X> Factored<X>
where
    X: Ord,
{
    /// Set the power of a prime factor in the `Factorization`. `prime` is
    ///  assumed to be prime. Note that while composite numbers
    ///  may be accepted, the behavior of the resulting `Factorization` is
    ///  ill-defined.
    // NOTE: No diagnostic is provided because it would require some sort
    //  of additional bound like Zero, One, or NumCast.
    pub fn set(&mut self, prime: X, exp: usize) {
        match exp {
            0 => self.powers.remove(&prime),
            _ => self.powers.insert(prime, exp),
        };
    }

    /// Get the power of a prime factor in the `Factorization`. `prime` is
    ///  assumed to be prime. The value returned for non-prime
    ///  keys is undefined.
    pub fn get(&self, prime: &X) -> usize {
        match self.powers.get(prime) {
            None => 0,
            Some(&exp) => exp,
        }
    }

    /// Create a `Factored` from a single prime.
    ///
    /// Do not use on a composite number (use `factor::factorize`)
    /// or one (use `One::one()`).
    pub fn from_prime(prime: X) -> Self {
        Factored {
            powers: ::std::iter::once((prime, 1)).collect(),
        }
    }

    /// Recover the integer represented by the `Factored`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.product(), 20);
    /// ```
    pub fn product(&self) -> X
    where
        X: Clone + One,
    {
        self.iter().map(clone2).factor_product()
    }

    /// Compute the total number of positive integers which evenly divide
    ///  a number from its prime decomposition.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.divisor_count(), 6);
    /// ```
    pub fn divisor_count(&self) -> X
    where
        X: Clone + FromPrimitive + One,
    {
        self.iter().map(clone2).divisor_count()
    }

    /// Compute the sum of all positive integers which evenly divide the number
    ///  represented by the `Factored` (including 1 and the number itself).
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.divisor_sum(), 42);
    /// ```
    pub fn divisor_sum(&self) -> X
    where
        X: Clone + One + Num,
    {
        self.iter().map(clone2).divisor_sum()
    }

    /// Compute the Euler totient `phi(x)`, the total number of
    ///  positive integers less than `x` that are coprime to `x`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let f = factorize(20u64);
    /// assert_eq!(f.totient(), 8);
    /// ```
    pub fn totient(&self) -> X
    where
        X: Clone + One + Num,
    {
        self.iter().map(clone2).totient()
    }

    /// Compute the value modulo `m`.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::prelude::*;
    ///
    /// let f: factor::Factored<_> = (1..=20u64).map(factor::factorize).product();
    /// assert_eq!(f.product_mod(&1297), 278);
    /// ```
    pub fn product_mod(self, modulus: &X) -> X
    where
        X: Clone + One + Integer,
        Self: Sized,
    {
        self.iter().map(clone2).factor_product_mod(modulus)
    }
}

impl<X> Factored<X>
where
    X: Ord,
{
    /// Get the square root of a perfect square.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let mut f = factorize(20u64);
    /// assert!(f.clone().sqrt().is_none());    // 20 is not square!
    ///
    /// f = f * factorize(5);
    /// assert_eq!(f.sqrt().unwrap().product(), 10);  // sqrt(100)
    /// ```
    pub fn sqrt(self) -> Option<Self> {
        self.root(2)
    }

    /// Get the nth root of a perfect nth power.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// let mut f = factorize(20u64);
    /// assert!(f.clone().root(3).is_none());    // 20 is not a cube!
    ///
    /// f = f * factorize(50);
    /// assert_eq!(f.root(3).unwrap().product(), 10);  // cbrt(1000)
    /// ```
    pub fn root(mut self, n: usize) -> Option<Self> {
        for (_, v) in self.powers.iter_mut() {
            if *v % n == 1 {
                return None; // Not a root!  Abort!  Abort!
            };

            *v = *v / n;
        }
        Some(self)
    }

    // TODO: Docs & test
    pub fn pow(mut self, pwr: usize) -> Self
    where
        X: Clone,
    {
        for (_, v) in self.powers.iter_mut() {
            *v = *v * pwr;
        }
        self
    }

    /*
        // TODO: Docs & test
        pub fn gcd(mut self, other: mut Self) -> Self
         where X: Clone,
        {
            // Iterate through shorter list
            if other.powers.len() < self.powers.len() {
                return self.gcd(other);
            };

            let mut result: Self = One::one();
            for (k,v) in other {
                self.set(k.clone(), min(self.get(&k), v));
            };
            self
        }

        // TODO: Docs & test
        pub fn lcm(&self, other: &Self) -> Self
         where X: Clone,
        {
            let mut result = self.clone();
            for (k,v) in self.powers.clone().into_iter() {
                self.set(k.clone(), max(self.get(&k), v));
            };
            self
        }
    */

    /// Divide by another factorized value.
    ///
    /// Cannot produce fractional values.
    ///
    /// # Example:
    ///
    /// ```
    /// use factor::factorize;
    ///
    /// assert_eq!(factorize(15u64).checked_div(factorize(5u64)), Some(factorize(3u64)));
    /// assert_eq!(factorize(15u64).checked_div(factorize(2u64)), None);
    /// ```
    pub fn checked_div(&self, other: impl FactorExt<X>) -> Option<Factored<X>>
    where
        X: Clone,
    {
        let mut result = self.clone();
        result.checked_div_assign(other)?;
        Some(result)
    }

    fn checked_div_assign(&mut self, other: impl FactorExt<X>) -> Option<()>
    where
        X: Clone,
    {
        for (k, v) in other {
            let current = self.get(&k);
            match current.checked_sub(v) {
                Some(v) => self.set(k.clone(), v),
                None => return None,
            }
        }
        Some(())
    }

    /// Iterate over unique prime factors.
    ///
    /// Item type is `&X`.
    pub fn primes(&self) -> Primes<'_, X> {
        self.powers.keys()
    }

    /// Iterate over `(prime, power)` pairs.
    ///
    /// Item type is `(&X, usize)`.
    pub fn iter(&self) -> Iter<'_, X> {
        self.powers.iter()
    }

    /// Immutably borrow the underlying map.
    pub fn as_btree_map(&self) -> &BTreeMap<X, usize> {
        &self.powers
    }
    /// Mutably borrow the underlying map.
    ///
    /// This is provided on the grounds of "eh, why the hell not."  After all,
    /// it's not exactly like `Factored` was doing a very good job at protecting
    /// any of its invariants to begin with.
    pub fn as_mut_btree_map(&mut self) -> &mut BTreeMap<X, usize> {
        &mut self.powers
    }
    /// Consume to obtain the underlying map.
    pub fn into_btree_map(self) -> BTreeMap<X, usize> {
        self.powers
    }

    /// Construct from a map of unique `(prime, power)` pairs.
    pub fn from_btree_map(map: BTreeMap<X, usize>) -> Self {
        Factored { powers: map }
    }

    /// Construct from an iterator of unique `(prime, power)` pairs.
    pub fn from_iter<I: IntoIterator<Item = (X, usize)>>(iter: I) -> Self {
        Factored::from_btree_map(iter.into_iter().collect())
    }

    // TODO: Reasonable (?) methods to implement
    // pub fn is_multiple_of(&self, other: &Self) -> bool
}

impl<X> One for Factored<X>
where
    X: Ord + Clone,
{
    /// Create a `Factored` representing `1`.
    fn one() -> Self {
        Self::from_btree_map(BTreeMap::new())
    }
}

impl<X> Default for Factored<X>
where
    X: Ord + Clone,
{
    /// Create a `Factored` representing `1`.
    fn default() -> Self {
        One::one()
    }
}

impl<X> Mul<Factored<X>> for Factored<X>
where
    X: Ord + Clone,
{
    type Output = Self;

    fn mul(mut self, other: Self) -> Self {
        self *= other;
        self
    }
}

impl<X> Div<Factored<X>> for Factored<X>
where
    X: Ord + Clone,
{
    type Output = Self;

    fn div(mut self, other: Self) -> Self {
        self /= other;
        self
    }
}

impl<X> MulAssign<Factored<X>> for Factored<X>
where
    X: Ord + Clone,
{
    fn mul_assign(&mut self, other: Self) {
        for (k, v) in other.powers.into_iter() {
            let current = self.get(&k);
            self.set(k.clone(), current + v);
        }
    }
}

impl<X> DivAssign<Factored<X>> for Factored<X>
where
    X: Ord + Clone,
{
    fn div_assign(&mut self, other: Self) {
        self.checked_div_assign(other).expect("divisor does not evenly divide into self!");
    }
}

impl<X> std::iter::Product for Factored<X>
where
    X: Ord + Clone,
{
    fn product<I: Iterator<Item=Factored<X>>>(iter: I) -> Self {
        iter.fold(Default::default(), |acc, x| acc * x)
    }
}

impl<X: Ord> IntoIterator for Factored<X>
{
    type Item = (X, usize);
    type IntoIter = IntoIter<X>;

    fn into_iter(self) -> Self::IntoIter { self.powers.into_iter() }
}

//------------------------------------

pub type Iter<'a, T> = ::std::collections::btree_map::Iter<'a, T, usize>;
pub type IntoIter<T> = ::std::collections::btree_map::IntoIter<T, usize>;
pub type Primes<'a, T> = ::std::collections::btree_map::Keys<'a, T, usize>;

#[inline]
fn clone2<A, B>((a, b): (&A, &B)) -> (A, B)
where
    A: Clone,
    B: Clone,
{
    (a.clone(), b.clone())
}
<|endoftext|>