<commit_before>// Copyright 2015 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.

extern crate num;
extern crate test;

use std::collections::hash_map::{HashMap,Hasher};
use std::collections::{Bitv,BitvSet};
use std::default::Default;
use std::num::{ToPrimitive,FromPrimitive}; // and regret it
use std::hash::Hash;
use std::ops::{Shr,Rem};
use std::rand::Rng;
use std::rand::weak_rng;
use std::rand::distributions::range::SampleRange;
use std::mem::swap;

use num::{Zero, One, Integer};

use factorize;
use factorization::Factorization;
use factorizer::Factorizer;
use util::{isqrt,gcd};

/// TODO
pub struct DixonFactorizer<T>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher>
{
	primes:       Vec<T>,
	extra_count:  usize,
	max_attempts: usize,
}

impl<T> DixonFactorizer<T>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher>
{
	pub fn new(primes: Vec<T>) -> Self
	{
		DixonFactorizer {
			primes:       primes,
			extra_count:  3,
			max_attempts: 100,
		}
	}
}

impl<T> Factorizer<T>
for DixonFactorizer<T>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Shr<usize, Output=T> + Hash<Hasher> + SampleRange,
{
	/// Produce a single factor of `x`.  TrialDivisionFactorizer is deterministic,
	///  and will always produce the smallest non-trivial factor of any composite number.
	///  Thus, the number it returns is also always prime.
	///
	/// The runtime scales linearly with the size of the smallest factor of `x`.
	fn get_factor(self: &Self, x: &T) -> T
	{
		// Step 1: Collect congruences of the form a^2 = b (mod x), where b < x
		//          and b is smooth (composed only of small primes).
		let a_min = isqrt(x.clone()); // XXX: ceil? (ensure a^2 > x)

		let a_count = self.primes.len() + self.extra_count;
		let mut a_values: Vec<T> = Vec::new();
		let mut b_factorizations: Vec<Factorization<T>> = Vec::new();

		for _ in (0us..a_count) {
			for _ in (0us..self.max_attempts) {

				// a random number such that a < x and a*a > x.
				let a = weak_rng().gen_range(a_min.clone(), x.clone());
				let b = a.clone() * a.clone() % x.clone();

				// there are cases where x may divide directly into a*a, in which
				//  case b = 0.  In this case, gcd(a,x) must be a nontrivial
				//  factor (easy proof), and we can bail with an early result.
				if b.is_zero() {
					let candidate = gcd(a.clone(), x.clone());

					// Just to be sure...
					assert!(candidate != One::one());
					assert!(candidate != x.clone());
					return candidate;
				}

				// Try to factorize b using only small primes
				let b_factorization = factorize_limited(b, &self.primes);

				if b_factorization.is_some() {
					a_values.push(a);
					b_factorizations.push(b_factorization.unwrap());
				}
			}
		}

		// Step 2: Find products of b's which are square.

		// Use a bit array to represent each b's factorization mod 2
		let mut bitmatrix = bit_matrix_from_factorizations(&b_factorizations, &self.primes);

		// Put in row echelon form
		bit_matrix_to_ref(&mut bitmatrix);

		// Each row full of zeros in the matrix represents a set of b values that multiply
		//  together to form a square.
		for matrix_row in bitmatrix.into_rows().into_iter() {

			if matrix_row.is_all_zero() {

				let mut a_prod: T = One::one();
				let mut b_prod_factors: Factorization<T> = Default::default();

				for index in matrix_row.into_index_set().iter() {
					a_prod = a_prod * a_values[index].clone();
					b_prod_factors = b_prod_factors * b_factorizations[index].clone();
				}

				// we now have a congruence of squares (mod x) between a_prod^2 and b_prod
				let b_prodsqrt_factors = b_prod_factors.sqrt().unwrap();
				let b_prodsqrt = b_prodsqrt_factors.product();

				// a - sqrt(b) has a high chance of sharing a nontrivial factor in common with x
				let candidate = gcd(a_prod - b_prodsqrt,  x.clone());

				if candidate != One::one() && candidate != x.clone() {
					return candidate;
				}
			}
		}
		// temporary solution: panic on failure to find factor (FIXME)
		panic!("No factor found! :(");
	}
}

// Utility function that only returns a factorization if it can be constructed
//  *exclusively* from the given primes.
fn factorize_limited<T>(x: T, primes: &Vec<T>) -> Option<Factorization<T>>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher> + SampleRange
{
	assert!(!x.is_zero());

	let mut f: Factorization<T> = Default::default();
	let mut c = x;
	for p in primes.iter() {

		let mut count = 0us;
		while c.is_multiple_of(p) {
			c = c / p.clone();
			count += 1;
		}

		f.set(p.clone(), count);
	}

	// Only report complete factorizations
	if c == One::one() {
		Some(f)
	} else {
		None
	}
}

#[test]
fn factorize_limited_test() {
	let primes = vec![2us, 5, 7];
	println!("{:?},{:?}",factorize_limited(1, &primes), Some(factorize(1us)));
	assert_eq!(factorize_limited(1, &primes), Some(factorize(1us)));
	assert_eq!(factorize_limited(2450, &primes), Some(factorize(2450us)));
	assert_eq!(factorize_limited(22, &primes), None);   // 11 not in prime list
	assert_eq!(factorize_limited(12, &primes), None);   // 3 not in prime list
}

//-------------------------------------------
// Private utility structs used in the "bit matrix to ref" algorithm, to separate
//  the underlying data representation from the general algorithm.
#[derive(Clone,Debug)]
struct DixonBitvec {
	elements: BitvSet, // represents the power of each prime modulo 2
	indices:  BitvSet, // indicates which rows have been xor'ed to make this row
}

#[derive(Clone,Debug)]
struct DixonBitmatrix {
	rows: Vec<DixonBitvec>,
}

impl DixonBitvec
{
	#[inline]
	fn is_all_zero(self: &Self) -> bool {
		self.elements.is_empty()
	}

	#[inline]
	fn into_index_set(self: Self) -> BitvSet {
		self.indices
	}

}

impl DixonBitmatrix
{
	// Matrix dimensions
	#[inline]
	fn nrows(self: &Self) -> usize { self.rows.len() }
	#[inline]
	fn ncols(self: &Self) -> usize { self.rows[0].elements.len() }

	// Index
	#[inline]
	fn get_elem(self: &Self, row: usize, col: usize) -> bool {
		self.rows[row].elements.contains(&col)
	}

	#[inline]
	fn swap_rows(self: &mut Self, i: usize, j: usize) {
		let temp = self.rows[i].clone();
		self.rows[i] = self.rows[j].clone();
		self.rows[j] = temp;
	}

	// Computes an XOR of rows src and dest, overwriting dest.
	#[inline]
	fn xor_update_row(self: &mut Self, src: usize, dest: usize) {
		let elems = self.rows[src].elements.clone();
		let inds  = self.rows[src].indices.clone();
		self.rows[dest].elements.symmetric_difference_with(&elems);
		self.rows[dest].indices.symmetric_difference_with(&inds);
	}

	#[inline]
	fn into_rows(self: Self) -> Vec<DixonBitvec> {
		self.rows
	}
}

// Produce matrix from initial input
fn bit_matrix_from_factorizations<T>(factorizations: &Vec<Factorization<T>>, primes: &Vec<T>) -> DixonBitmatrix
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher>
{
	let rows: Vec<DixonBitvec> = factorizations.iter().enumerate().map(|(row_index,fact)| {

		// set elements equal to powers in factorization, mod 2
		let elements: Bitv = primes.iter().map(|p| fact.get(p) % 2 == 1).collect();

		// indices initially contains just the index for this row
		let mut indices = BitvSet::new();
		indices.insert(row_index);

		// Construct the row
		DixonBitvec {
			elements: BitvSet::from_bitv(elements),
			indices:  indices,
		}
	}).collect();

	DixonBitmatrix { rows: rows }
}

// Manipulate bit matrix into row echelon form
fn bit_matrix_to_ref(matrix: &mut DixonBitmatrix) {

	let mut target_row = 0us;

	for col in (0us..matrix.ncols()) {

		// Look for a leading 1 in this column
		for source_row in (target_row..matrix.nrows()) {

			if matrix.get_elem(source_row, col) {

				// Move this row to its correct location (target_row)
				matrix.swap_rows(source_row, target_row);

				// Eliminate any remaining 1s below this one in the column by XORing
				for other_row in ((source_row+1)..matrix.nrows()) {
					if matrix.get_elem(other_row, col) {
						matrix.xor_update_row(target_row, other_row);
					}
				}

				target_row += 1; // done with this target_row
				break;           // also done with this column
			}
		}
		// (invariant: elements with row >= target_row,  col < leading_col are 0)
	}
}

<commit_msg>tests and debugging Dixon<commit_after>// Copyright 2015 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.

extern crate num;
extern crate test;

use std::collections::hash_map::{HashMap,Hasher};
use std::collections::{Bitv,BitvSet};
use std::default::Default;
use std::num::{ToPrimitive,FromPrimitive}; // and regret it
use std::hash::Hash;
use std::ops::{Shr,Rem};
use std::rand::Rng;
use std::rand::weak_rng;
use std::rand::distributions::range::SampleRange;
use std::mem::swap;

use num::{Zero, One, Integer};

use factorize;
use factorization::Factorization;
use factorizer::Factorizer;
use util::{isqrt,gcd};

pub struct DixonFactorizer<T>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher>
{
	primes:       Vec<T>,
	extra_count:  usize,
	max_attempts: usize,
}

impl<T> DixonFactorizer<T>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher>
{
	pub fn new(primes: Vec<T>) -> Self
	{
		DixonFactorizer {
			primes:       primes,
			extra_count:  3,
			max_attempts: 100,
		}
	}
}

impl<T> Factorizer<T>
for DixonFactorizer<T>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Shr<usize, Output=T> + Hash<Hasher> + SampleRange,
{
	/// Produce a single factor of `x`.  TrialDivisionFactorizer is deterministic,
	///  and will always produce the smallest non-trivial factor of any composite number.
	///  Thus, the number it returns is also always prime.
	///
	/// The runtime scales linearly with the size of the smallest factor of `x`.
	fn get_factor(self: &Self, x: &T) -> T
	{
		// Step 1: Collect congruences of the form a^2 = b (mod x), where b < x
		//          and b is smooth (composed only of small primes).
		let a_min = isqrt(x.clone()); // XXX: ceil? (ensure a^2 > x)

		let a_count = self.primes.len() + self.extra_count;
		let mut a_values: Vec<T> = Vec::new();
		let mut b_factorizations: Vec<Factorization<T>> = Vec::new();

		'a: for _ in (0us..a_count) {
			for _ in (0us..self.max_attempts) {

				// a random number such that a < x and a*a > x.
				let a = weak_rng().gen_range(a_min.clone(), x.clone());
				let b = a.clone() * a.clone() % x.clone();

				// there are cases where x may divide directly into a*a, in which
				//  case b = 0.  In this case, gcd(a,x) must be a nontrivial
				//  factor (easy proof), and we can bail with an early result.
				if b.is_zero() {
					let candidate = gcd(a.clone(), x.clone());

					// Just to be sure...
					assert!(candidate != One::one());
					assert!(candidate != x.clone());
					return candidate;
				}

				// Try to factorize b using only small primes
				let b_factorization = factorize_limited(b, &self.primes);

				if b_factorization.is_some() {
					// Record it and reset the attempt counter
					a_values.push(a);
					b_factorizations.push(b_factorization.unwrap());
					continue 'a;
				}
			}
			panic!("Encountered max attempts to find an equivalence ({})", self.max_attempts);
		}

		assert_eq!(a_values.len(), a_count);
		assert_eq!(b_factorizations.len(), a_count);

		// Step 2: Find products of b's which are square.
		// NOTE: not currently a big fan of how this is accomplished. (using linear algebra, etc)
		//       This problem is isomorphic to a rather simple problem in combinatorial
		//       game theory (given a set of impartial games with known nimbers, find
		//       subsets with nimsum 0), and the solution here feels unintuitive and
		//       convoluted in comparison.
		//       (it also generates much fewer results... but perhaps many of the additional
		//        sums generated by the CGT solution are not useful here)

		// Use a bit array to represent each b's factorization mod 2
		let mut bitmatrix = bit_matrix_from_factorizations(&b_factorizations, &self.primes);

		// Put in row echelon form
		bit_matrix_to_ref(&mut bitmatrix);

		// Each row full of zeros in the matrix represents a set of b values that multiply
		//  together to form a square.
		for matrix_row in bitmatrix.into_rows().into_iter() {

			if matrix_row.is_all_zero() {

				let mut a_prod: T = One::one();
				let mut b_prod_factors: Factorization<T> = Default::default();

				for index in matrix_row.into_index_set().iter() {
					a_prod = a_prod * a_values[index].clone();
					b_prod_factors = b_prod_factors * b_factorizations[index].clone();
				}

				// we now have a congruence of squares (mod x) between a_prod^2 and b_prod
				let b_prodsqrt_factors = b_prod_factors.sqrt().unwrap();
				let b_prodsqrt = b_prodsqrt_factors.product();

				// a - sqrt(b) has a high chance of sharing a nontrivial factor in common with x
				let candidate = gcd(a_prod - b_prodsqrt,  x.clone());

				if candidate != One::one() && candidate != x.clone() {
					return candidate;
				}
			}
		}
		// temporary solution: panic on failure to find factor (FIXME)
		panic!("No factor found! :(");
	}
}

// Utility function that only returns a factorization if it can be constructed
//  *exclusively* from the given primes.
fn factorize_limited<T>(x: T, primes: &Vec<T>) -> Option<Factorization<T>>
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher> + SampleRange
{
	assert!(!x.is_zero());

	let mut f: Factorization<T> = Default::default();
	let mut c = x;
	for p in primes.iter() {

		let mut count = 0us;
		while c.is_multiple_of(p) {
			c = c / p.clone();
			count += 1;
		}

		f.set(p.clone(), count);
	}

	// Only report complete factorizations
	if c == One::one() {
		Some(f)
	} else {
		None
	}
}

#[test]
fn factorize_limited_test() {
	let primes = vec![2us, 5, 7];
	assert_eq!(factorize_limited(1, &primes), Some(factorize(1us)));
	assert_eq!(factorize_limited(2450, &primes), Some(factorize(2450us)));
	assert_eq!(factorize_limited(22, &primes), None);   // 11 not in prime list
	assert_eq!(factorize_limited(12, &primes), None);   // 3 not in prime list
}

//-------------------------------------------
// Private utility structs used in the "bit matrix to ref" algorithm, to separate
//  the underlying data representation from the general algorithm.
#[derive(Eq,PartialEq,Clone,Debug)]
struct DixonBitvec {
	elements: BitvSet, // represents the power of each prime modulo 2
	indices:  BitvSet, // indicates which rows have been xor'ed to make this row
}

#[derive(Eq,PartialEq,Clone,Debug)]
struct DixonBitmatrix {
	rows:  Vec<DixonBitvec>,
	width: usize,
}

impl DixonBitvec
{
	// Mostly for creating DixonBitvecs from literal vecs in tests
	#[inline]
	fn from_vecs(elems: Vec<usize>, ids: Vec<usize>) -> DixonBitvec {
		DixonBitvec {
			elements: elems.into_iter().collect(),
			indices:  ids.into_iter().collect(),
		}
	}

	#[inline]
	fn is_all_zero(self: &Self) -> bool {
		self.elements.is_empty()
	}

	#[inline]
	fn into_index_set(self: Self) -> BitvSet {
		self.indices
	}

}

impl DixonBitmatrix
{
	// Matrix dimensions
	#[inline]
	fn nrows(self: &Self) -> usize { self.rows.len() }
	#[inline]
	fn ncols(self: &Self) -> usize { self.width }

	// Index
	#[inline]
	fn get_elem(self: &Self, row: usize, col: usize) -> bool {
		self.rows[row].elements.contains(&col)
	}

	#[inline]
	fn swap_rows(self: &mut Self, i: usize, j: usize) {
		let temp = self.rows[i].clone();
		self.rows[i] = self.rows[j].clone();
		self.rows[j] = temp;
	}

	// Computes an XOR of rows src and dest, overwriting dest.
	#[inline]
	fn xor_update_row(self: &mut Self, src: usize, dest: usize) {
		let elems = self.rows[src].elements.clone();
		let inds  = self.rows[src].indices.clone();
		self.rows[dest].elements.symmetric_difference_with(&elems);
		self.rows[dest].indices.symmetric_difference_with(&inds);
	}

	#[inline]
	fn into_rows(self: Self) -> Vec<DixonBitvec> {
		self.rows
	}
}

// Produce matrix from initial input
fn bit_matrix_from_factorizations<T>(factorizations: &Vec<Factorization<T>>, primes: &Vec<T>) -> DixonBitmatrix
 where T: Eq + Clone + FromPrimitive + ToPrimitive + Zero + One + Integer + Hash<Hasher>
{
	let rows: Vec<DixonBitvec> = factorizations.iter().enumerate().map(|(row_index,fact)| {

		// set elements equal to powers in factorization, mod 2
		let elements: BitvSet = (0us..primes.len()).filter(|i| fact.get(&primes[*i]) % 2 == 1).collect();

		// indices initially contains just the index for this row
		let mut indices = BitvSet::new();
		indices.insert(row_index);

		// Construct the row
		DixonBitvec {
			elements: elements,
			indices:  indices,
		}
	}).collect();

	DixonBitmatrix {
		rows: rows,
		width: primes.len(),
	}
}

// Manipulate bit matrix into row echelon form
fn bit_matrix_to_ref(matrix: &mut DixonBitmatrix)
{
	let mut target_row = 0us;

	for col in (0us..matrix.ncols()) {

		// Look for a leading 1 in this column
		for source_row in (target_row..matrix.nrows()) {
			if matrix.get_elem(source_row, col) {

				// Move this row to its correct location (target_row)
				matrix.swap_rows(source_row, target_row);

				// Eliminate any remaining 1s below this one in the column by XORing
				for other_row in ((source_row+1)..matrix.nrows()) {
					if matrix.get_elem(other_row, col) {
						matrix.xor_update_row(target_row, other_row);
					}
				}

				target_row += 1; // done with this target_row
				break;           // also done with this column
			}
		}
		// (invariant: elements with row >= target_row,  col < leading_col are 0)
	}
}

fn gen_test_matrix() -> DixonBitmatrix {
	// Test a specific matrix
	// [1, 0, 0, 0] {0}       [1, 0, 0, 0] {0}
	// [1, 1, 1, 0] {1}  ref  [0, 1, 1, 0] {0,1}
	// [1, 1, 1, 0] {2} ----> [0, 0, 1, 1] {1,3}
	// [1, 1, 0, 1] {3}       [0, 0, 0, 0] {1,2} \ interchangeable
	// [1, 0, 0, 0] {4}       [0, 0, 0, 0] {0,4} /      rows
	DixonBitmatrix { rows: vec![
		DixonBitvec::from_vecs(vec![0],     vec![0]),
		DixonBitvec::from_vecs(vec![0,1,2], vec![1]),
		DixonBitvec::from_vecs(vec![0,1,2], vec![2]),
		DixonBitvec::from_vecs(vec![0,1,3], vec![3]),
		DixonBitvec::from_vecs(vec![0],     vec![4]),
	], width: 4}
}

#[test]
fn test_row_swap() {
	let original   = gen_test_matrix();
	let mut actual = original.clone();

	actual.swap_rows(1,1);
	assert_eq!(actual, original);

	actual.swap_rows(1,3);
	let expected = DixonBitmatrix { rows: vec![
		DixonBitvec::from_vecs(vec![0],     vec![0]),
		DixonBitvec::from_vecs(vec![0,1,3], vec![3]), // changed
		DixonBitvec::from_vecs(vec![0,1,2], vec![2]),
		DixonBitvec::from_vecs(vec![0,1,2], vec![1]), // changed
		DixonBitvec::from_vecs(vec![0],     vec![4]),
	], width: 4};
	assert_eq!(actual, expected);
}

#[test]
fn test_row_xor() {
	let original   = gen_test_matrix();
	let mut actual = original.clone();

	actual.xor_update_row(1,3);
	let expected = DixonBitmatrix { rows: vec![
		DixonBitvec::from_vecs(vec![0],     vec![0]),
		DixonBitvec::from_vecs(vec![0,1,2], vec![1]),
		DixonBitvec::from_vecs(vec![0,1,2], vec![2]),
		DixonBitvec::from_vecs(vec![2,3],   vec![1,3]), // changed
		DixonBitvec::from_vecs(vec![0],     vec![4]),
	], width: 4};
	assert_eq!(actual, expected);

	actual.xor_update_row(1,3);
	assert_eq!(actual, original);
}

#[test]
fn test_bit_marix_to_ref() {
	let mut actual = gen_test_matrix();

	bit_matrix_to_ref(&mut actual);

	let expected = DixonBitmatrix { rows: vec![
		DixonBitvec::from_vecs(vec![0],   vec![0]),
		DixonBitvec::from_vecs(vec![1,2], vec![0,1]),
		DixonBitvec::from_vecs(vec![2,3], vec![1,3]),
		DixonBitvec::from_vecs(vec![],    vec![1,2]),
		DixonBitvec::from_vecs(vec![],    vec![0,4]),
	], width: 4};

	// This test is a bit strict as there can be many valid REF forms.
	// It's mostly to double check that the algorithm is doing what I think it's
	//  doing (i.e. no silly typos)
	assert_eq!(actual, expected);
}
<|endoftext|>


<commit_before>use std::collections::{HashSet, VecDeque};
use std::ops::{Index, IndexMut};

use super::{BoundingVolume, Transformable, Triangle, TriangleStorage, AABB};
use math::Transform;
use math::{Point3, Vector3};
use ray::Ray;

#[derive(Debug, Clone, Copy)]
struct NodeId(usize);

impl NodeId {
    const fn none() -> Self {
        NodeId(usize::MAX)
    }
}

impl From<usize> for NodeId {
    fn from(id: usize) -> Self {
        Self(id)
    }
}

#[derive(Debug)]
struct Node<M, T> {
    parent: Option<NodeId>,
    metadata: M,
    data: T,
}

impl<M: Default, T> Node<M, T> {
    fn new(data: T, parent: Option<NodeId>) -> Self {
        Self {
            data,
            parent,
            metadata: M::default(),
        }
    }
}

#[derive(Debug)]
struct Arena<M, T> {
    nodes: Vec<Node<M, T>>,
}

impl<M: Default, T> Arena<M, T> {
    fn new() -> Self {
        Self {
            nodes: Vec::default(),
        }
    }

    fn new_node(&mut self, data: T) -> NodeId {
        self.new_node_with_parent(data, None)
    }

    fn new_node_with_parent(&mut self, data: T, parent_id: Option<NodeId>) -> NodeId {
        let next_index = self.nodes.len();

        let node = Node::new(data, parent_id);

        self.nodes.push(node);

        NodeId::from(next_index)
    }

    fn clear(&mut self) {
        self.nodes.clear();
    }

    fn num_nodes(&self) -> usize {
        self.nodes.len()
    }
}

impl<M, T> Index<NodeId> for Arena<M, T> {
    type Output = Node<M, T>;

    fn index(&self, id: NodeId) -> &Self::Output {
        &self.nodes[id.0]
    }
}

impl<M, T> IndexMut<NodeId> for Arena<M, T> {
    fn index_mut(&mut self, id: NodeId) -> &mut Self::Output {
        &mut self.nodes[id.0]
    }
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct TriangleId(usize);

impl TriangleId {
    fn value(&self) -> usize {
        self.0
    }
}

impl From<usize> for TriangleId {
    fn from(id: usize) -> Self {
        Self(id)
    }
}

pub struct IntersectionIterator<'a, I> {
    ids: I,
    triangles: &'a [Triangle],
}

impl<'a, I> IntersectionIterator<'a, I> {
    fn new(ids: I, triangles: &'a [Triangle]) -> Self {
        Self { ids, triangles }
    }
}

impl<'a, I> Iterator for IntersectionIterator<'a, I>
where
    I: Iterator<Item = TriangleId>,
{
    type Item = &'a Triangle;

    fn next(&mut self) -> Option<Self::Item> {
        let item = self
            .ids
            .next()
            .and_then(|triangle_id| self.triangles.get(triangle_id.value()));

        item
    }
}

#[derive(Debug)]
struct Metadata {
    children: [NodeId; 8],
    bounding_box: AABB,
    is_leaf: bool,
    is_empty: bool,
}

impl Default for Metadata {
    fn default() -> Self {
        Self {
            children: [NodeId::none(); 8],
            bounding_box: AABB::empty(),
            is_leaf: false,
            is_empty: false,
        }
    }
}

const MAX_DEPTH: usize = 6;
const MIN_SIZE: f32 = 0.0005;
const MIN_TRIANGLES_PER_NODE: usize = 1;

#[derive(Debug)]
pub struct Octree {
    triangles: Vec<Triangle>,
    arena: Arena<Metadata, HashSet<TriangleId>>,
    root: NodeId,
}

impl Octree {
    fn rebuild(&mut self) {
        self.arena.clear();

        let root_id = self
            .arena
            .new_node((0..self.triangles.len()).map(TriangleId::from).collect());

        let mut iterator = self.triangles.iter();
        self.root = root_id;
        self.arena[root_id].metadata.bounding_box = AABB::from_triangles(&mut iterator);
        self.build(root_id, 1);

        dbg!(self.arena.num_nodes());
        dbg!(&self.arena[self.root].metadata);
        dbg!(&self.arena[root_id].metadata.bounding_box);

        let all_triangle_ids: HashSet<TriangleId> =
            (0..self.triangles.len()).map(TriangleId::from).collect();

        let mut triangle_ids_in_nodes: HashSet<TriangleId> = HashSet::default();
        let mut to_visit: VecDeque<NodeId> = VecDeque::new();
        let mut num_nodes = 1;
        let mut num_triangles = self.arena[self.root].data.len();
        to_visit.push_back(self.root);

        while let Some(id) = to_visit.pop_back() {
            let child_node = &self.arena[id];
            num_triangles += child_node.data.len();

            if !child_node.metadata.is_leaf {
                for octant_id in child_node.metadata.children.iter().cloned() {
                    to_visit.push_back(octant_id);
                }
            }

            for triangle_id in child_node.data.iter().cloned() {
                triangle_ids_in_nodes.insert(triangle_id);
            }

            num_nodes += 1;
        }

        dbg!(num_triangles / num_nodes);

        assert!(triangle_ids_in_nodes == all_triangle_ids, "Found orphans");
    }

    fn build(&mut self, node_id: NodeId, depth: usize) {
        let (mut child_nodes, mut child_bounding_volumes) = {
            let node = &mut self.arena[node_id];
            let bounding_box = &node.metadata.bounding_box;

            // Exit condition triangles per node
            if node.data.len() <= MIN_TRIANGLES_PER_NODE {
                node.metadata.is_leaf = true;
                node.metadata.is_empty = node.data.is_empty();
                return;
            }

            let dimensions = bounding_box.dimensions();

            // Exit condition smallest node
            if dimensions.x <= MIN_SIZE && dimensions.y <= MIN_SIZE && dimensions.z <= MIN_SIZE {
                node.metadata.is_leaf = true;
                return;
            }

            // Exit condition max depth
            if depth >= MAX_DEPTH {
                node.metadata.is_leaf = true;
                return;
            }

            let child_bounding_volumes = Self::build_octants_for(bounding_box, dimensions);
            let mut to_delete: HashSet<TriangleId> = HashSet::default();
            let mut child_nodes: VecDeque<HashSet<TriangleId>> = VecDeque::with_capacity(8);
            for _ in 0..8 {
                child_nodes.push_back(HashSet::default());
            }

            for triangle_id in &node.data {
                for i in 0..8 {
                    let triangle = &self.triangles[triangle_id.value()];

                    if child_bounding_volumes[i].intersects_triangle(&triangle) {
                        to_delete.insert(*triangle_id);
                        child_nodes[i].insert(*triangle_id);
                        // TODO: Think about this break, is it enough if a triangle is in a single
                        // node or should it be in all that it intersects with?
                        // break;
                    }
                }
            }

            node.data = node.data.difference(&to_delete).cloned().collect();
            assert!(node.data.len() == 0);
            // println!(
            //     "Triangles left in parent({}): {}",
            //     node_id.0,
            //     node.data.len()
            // );
            (child_nodes, child_bounding_volumes)
        };

        for i in 0..8 {
            let id = self
                .arena
                .new_node_with_parent(child_nodes.pop_front().unwrap(), Some(node_id));
            self.arena[id].metadata.bounding_box = child_bounding_volumes.pop_front().unwrap();

            self.arena[node_id].metadata.children[i] = id;
        }

        for i in 0..8 {
            self.build(self.arena[node_id].metadata.children[i], depth + 1);
        }
    }

    fn build_octants_for(bounding_box: &AABB, dimensions: Vector3) -> VecDeque<AABB> {
        let half = (dimensions * 0.5).as_point();
        let center = (bounding_box.min() + half.as_vector()).as_point();

        let (min, max) = (bounding_box.min(), bounding_box.max());
        let mut child_bounding_volumes = VecDeque::with_capacity(8);
        // Left
        child_bounding_volumes.push_back(AABB::new(min, center));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(min.x, min.y, center.z),
            Point3::new(center.x, center.y, max.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(min.x, center.y, min.z),
            Point3::new(center.x, max.y, center.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(min.x, center.y, center.z),
            Point3::new(center.x, max.y, max.z),
        ));
        // Right
        child_bounding_volumes.push_back(AABB::new(center, max));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(center.x, center.y, min.z),
            Point3::new(max.x, max.y, center.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(center.x, min.y, center.z),
            Point3::new(max.x, center.y, max.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(center.x, min.y, min.z),
            Point3::new(max.x, center.y, center.z),
        ));

        child_bounding_volumes
    }
}

impl Transformable for Octree {
    fn transform(&mut self, transform: &Transform) {
        for triangle in self.all_mut() {
            triangle.transform(&transform);
        }

        self.rebuild();
    }
}

impl<'a> TriangleStorage<'a> for Octree {
    type Iterator = std::slice::Iter<'a, Triangle>;
    type IteratorMut = std::slice::IterMut<'a, Triangle>;
    type IntersectionIterator =
        IntersectionIterator<'a, std::collections::hash_set::IntoIter<TriangleId>>;

    fn new(triangles: Vec<Triangle>) -> Self {
        let mut arena = Arena::new();
        let root_id = arena.new_node((0..triangles.len()).map(TriangleId::from).collect());

        let mut tree = Self {
            triangles,
            arena,
            root: root_id,
        };

        tree.rebuild();
        // panic!();

        tree
    }

    fn intersect(&'a self, ray: Ray, _cull: bool) -> Self::IntersectionIterator {
        let mut node_ids: VecDeque<NodeId> = VecDeque::new();
        node_ids.push_front(self.root);
        let mut triangles_to_test = HashSet::new();

        while let Some(id) = node_ids.pop_back() {
            let child_node = &self.arena[id];

            if child_node.metadata.bounding_box.intersect(ray) {
                if !child_node.metadata.is_leaf && !child_node.metadata.is_empty {
                    for octant_id in child_node.metadata.children.iter().cloned() {
                        node_ids.push_back(octant_id);
                    }
                }

                for triangle_id in child_node.data.iter().cloned() {
                    triangles_to_test.insert(triangle_id);
                }
            }
        }

        IntersectionIterator::new(triangles_to_test.into_iter(), &self.triangles)
    }

    fn all(&'a self) -> Self::Iterator {
        self.triangles.iter()
    }

    fn all_mut(&'a mut self) -> Self::IteratorMut {
        self.triangles.iter_mut()
    }
}
<commit_msg>Remove unneeded parent reference in octree node<commit_after>use std::collections::{HashSet, VecDeque};
use std::ops::{Index, IndexMut};

use super::{BoundingVolume, Transformable, Triangle, TriangleStorage, AABB};
use math::Transform;
use math::{Point3, Vector3};
use ray::Ray;

#[derive(Debug, Clone, Copy)]
struct NodeId(usize);

impl NodeId {
    const fn none() -> Self {
        NodeId(usize::MAX)
    }
}

impl From<usize> for NodeId {
    fn from(id: usize) -> Self {
        Self(id)
    }
}

#[derive(Debug)]
struct Node<M, T> {
    metadata: M,
    data: T,
}

impl<M: Default, T> Node<M, T> {
    fn new(data: T) -> Self {
        Self {
            data,
            metadata: M::default(),
        }
    }
}

#[derive(Debug)]
struct Arena<M, T> {
    nodes: Vec<Node<M, T>>,
}

impl<M: Default, T> Arena<M, T> {
    fn new() -> Self {
        Self {
            nodes: Vec::default(),
        }
    }

    fn new_node(&mut self, data: T) -> NodeId {
        let next_index = self.nodes.len();

        let node = Node::new(data);

        self.nodes.push(node);

        NodeId::from(next_index)
    }

    fn clear(&mut self) {
        self.nodes.clear();
    }

    fn num_nodes(&self) -> usize {
        self.nodes.len()
    }
}

impl<M, T> Index<NodeId> for Arena<M, T> {
    type Output = Node<M, T>;

    fn index(&self, id: NodeId) -> &Self::Output {
        &self.nodes[id.0]
    }
}

impl<M, T> IndexMut<NodeId> for Arena<M, T> {
    fn index_mut(&mut self, id: NodeId) -> &mut Self::Output {
        &mut self.nodes[id.0]
    }
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct TriangleId(usize);

impl TriangleId {
    fn value(&self) -> usize {
        self.0
    }
}

impl From<usize> for TriangleId {
    fn from(id: usize) -> Self {
        Self(id)
    }
}

pub struct IntersectionIterator<'a, I> {
    ids: I,
    triangles: &'a [Triangle],
}

impl<'a, I> IntersectionIterator<'a, I> {
    fn new(ids: I, triangles: &'a [Triangle]) -> Self {
        Self { ids, triangles }
    }
}

impl<'a, I> Iterator for IntersectionIterator<'a, I>
where
    I: Iterator<Item = TriangleId>,
{
    type Item = &'a Triangle;

    fn next(&mut self) -> Option<Self::Item> {
        let item = self
            .ids
            .next()
            .and_then(|triangle_id| self.triangles.get(triangle_id.value()));

        item
    }
}

#[derive(Debug)]
struct Metadata {
    children: [NodeId; 8],
    bounding_box: AABB,
    is_leaf: bool,
    is_empty: bool,
}

impl Default for Metadata {
    fn default() -> Self {
        Self {
            children: [NodeId::none(); 8],
            bounding_box: AABB::empty(),
            is_leaf: false,
            is_empty: false,
        }
    }
}

const MAX_DEPTH: usize = 6;
const MIN_SIZE: f32 = 0.0005;
const MIN_TRIANGLES_PER_NODE: usize = 1;

#[derive(Debug)]
pub struct Octree {
    triangles: Vec<Triangle>,
    arena: Arena<Metadata, HashSet<TriangleId>>,
    root: NodeId,
}

impl Octree {
    fn rebuild(&mut self) {
        self.arena.clear();

        let root_id = self
            .arena
            .new_node((0..self.triangles.len()).map(TriangleId::from).collect());

        let mut iterator = self.triangles.iter();
        self.root = root_id;
        self.arena[root_id].metadata.bounding_box = AABB::from_triangles(&mut iterator);
        self.build(root_id, 1);

        dbg!(self.arena.num_nodes());
        dbg!(&self.arena[self.root].metadata);
        dbg!(&self.arena[root_id].metadata.bounding_box);

        let all_triangle_ids: HashSet<TriangleId> =
            (0..self.triangles.len()).map(TriangleId::from).collect();

        let mut triangle_ids_in_nodes: HashSet<TriangleId> = HashSet::default();
        let mut to_visit: VecDeque<NodeId> = VecDeque::new();
        let mut num_nodes = 1;
        let mut num_triangles = self.arena[self.root].data.len();
        to_visit.push_back(self.root);

        while let Some(id) = to_visit.pop_back() {
            let child_node = &self.arena[id];
            num_triangles += child_node.data.len();

            if !child_node.metadata.is_leaf {
                for octant_id in child_node.metadata.children.iter().cloned() {
                    to_visit.push_back(octant_id);
                }
            }

            for triangle_id in child_node.data.iter().cloned() {
                triangle_ids_in_nodes.insert(triangle_id);
            }

            num_nodes += 1;
        }

        dbg!(num_triangles / num_nodes);

        assert!(triangle_ids_in_nodes == all_triangle_ids, "Found orphans");
    }

    fn build(&mut self, node_id: NodeId, depth: usize) {
        let (mut child_nodes, mut child_bounding_volumes) = {
            let node = &mut self.arena[node_id];
            let bounding_box = &node.metadata.bounding_box;

            // Exit condition triangles per node
            if node.data.len() <= MIN_TRIANGLES_PER_NODE {
                node.metadata.is_leaf = true;
                node.metadata.is_empty = node.data.is_empty();
                return;
            }

            let dimensions = bounding_box.dimensions();

            // Exit condition smallest node
            if dimensions.x <= MIN_SIZE && dimensions.y <= MIN_SIZE && dimensions.z <= MIN_SIZE {
                node.metadata.is_leaf = true;
                return;
            }

            // Exit condition max depth
            if depth >= MAX_DEPTH {
                node.metadata.is_leaf = true;
                return;
            }

            let child_bounding_volumes = Self::build_octants_for(bounding_box, dimensions);
            let mut to_delete: HashSet<TriangleId> = HashSet::default();
            let mut child_nodes: VecDeque<HashSet<TriangleId>> = VecDeque::with_capacity(8);
            for _ in 0..8 {
                child_nodes.push_back(HashSet::default());
            }

            for triangle_id in &node.data {
                for i in 0..8 {
                    let triangle = &self.triangles[triangle_id.value()];

                    if child_bounding_volumes[i].intersects_triangle(&triangle) {
                        to_delete.insert(*triangle_id);
                        child_nodes[i].insert(*triangle_id);
                        // TODO: Think about this break, is it enough if a triangle is in a single
                        // node or should it be in all that it intersects with?
                        // break;
                    }
                }
            }

            node.data = node.data.difference(&to_delete).cloned().collect();
            assert!(node.data.len() == 0);
            // println!(
            //     "Triangles left in parent({}): {}",
            //     node_id.0,
            //     node.data.len()
            // );
            (child_nodes, child_bounding_volumes)
        };

        for i in 0..8 {
            let id = self.arena.new_node(child_nodes.pop_front().unwrap());
            self.arena[id].metadata.bounding_box = child_bounding_volumes.pop_front().unwrap();

            self.arena[node_id].metadata.children[i] = id;
        }

        for i in 0..8 {
            self.build(self.arena[node_id].metadata.children[i], depth + 1);
        }
    }

    fn build_octants_for(bounding_box: &AABB, dimensions: Vector3) -> VecDeque<AABB> {
        let half = (dimensions * 0.5).as_point();
        let center = (bounding_box.min() + half.as_vector()).as_point();

        let (min, max) = (bounding_box.min(), bounding_box.max());
        let mut child_bounding_volumes = VecDeque::with_capacity(8);
        // Left
        child_bounding_volumes.push_back(AABB::new(min, center));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(min.x, min.y, center.z),
            Point3::new(center.x, center.y, max.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(min.x, center.y, min.z),
            Point3::new(center.x, max.y, center.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(min.x, center.y, center.z),
            Point3::new(center.x, max.y, max.z),
        ));
        // Right
        child_bounding_volumes.push_back(AABB::new(center, max));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(center.x, center.y, min.z),
            Point3::new(max.x, max.y, center.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(center.x, min.y, center.z),
            Point3::new(max.x, center.y, max.z),
        ));
        child_bounding_volumes.push_back(AABB::new(
            Point3::new(center.x, min.y, min.z),
            Point3::new(max.x, center.y, center.z),
        ));

        child_bounding_volumes
    }
}

impl Transformable for Octree {
    fn transform(&mut self, transform: &Transform) {
        for triangle in self.all_mut() {
            triangle.transform(&transform);
        }

        self.rebuild();
    }
}

impl<'a> TriangleStorage<'a> for Octree {
    type Iterator = std::slice::Iter<'a, Triangle>;
    type IteratorMut = std::slice::IterMut<'a, Triangle>;
    type IntersectionIterator =
        IntersectionIterator<'a, std::collections::hash_set::IntoIter<TriangleId>>;

    fn new(triangles: Vec<Triangle>) -> Self {
        let mut arena = Arena::new();
        let root_id = arena.new_node((0..triangles.len()).map(TriangleId::from).collect());

        let mut tree = Self {
            triangles,
            arena,
            root: root_id,
        };

        tree.rebuild();

        tree
    }

    fn intersect(&'a self, ray: Ray, _cull: bool) -> Self::IntersectionIterator {
        let mut node_ids: VecDeque<NodeId> = VecDeque::new();
        node_ids.push_front(self.root);
        let mut triangles_to_test = HashSet::new();

        while let Some(id) = node_ids.pop_back() {
            let child_node = &self.arena[id];

            if child_node.metadata.bounding_box.intersect(ray) {
                if !child_node.metadata.is_leaf {
                    for octant_id in child_node.metadata.children.iter().cloned() {
                        node_ids.push_back(octant_id);
                    }
                }

                for triangle_id in child_node.data.iter().cloned() {
                    triangles_to_test.insert(triangle_id);
                }
            }
        }

        IntersectionIterator::new(triangles_to_test.into_iter(), &self.triangles)
    }

    fn all(&'a self) -> Self::Iterator {
        self.triangles.iter()
    }

    fn all_mut(&'a mut self) -> Self::IteratorMut {
        self.triangles.iter_mut()
    }
}
<|endoftext|>


<commit_before>use std::error::{self, Error};
use std::fmt;
use std::any;
use rustc_serialize::json;

pub trait ValicoError: error::Error + fmt::Debug + Send + any::Any + json::ToJson {
    fn get_code(&self) -> &str;
    fn get_path(&self) -> &str;
    fn get_title(&self) -> &str;
    fn get_detail(&self) -> Option<&str> { None }
}

pub type ValicoErrors = Vec<Box<ValicoError>>;

mopafy!(ValicoError);

macro_rules! impl_basic_err {
    ($err:ty, $code:expr) => {
        impl ::std::error::Error for $err {
            fn description(&self) -> &str {
                $code
            }
        }

        impl ::std::fmt::Display for $err {
            fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                self.description().fmt(formatter)
            }
        }
    }
}

macro_rules! impl_err {
    ($err:ty, $code:expr, $title:expr) => {
        impl_basic_err!($err, $code);

        impl $crate::common::error::ValicoError for $err {
            fn get_code(&self) -> &str { $code }
            fn get_title(&self) -> &str { $title }
            fn get_path(&self) -> &str { self.path.as_slice() }
        }
    };

    ($err:ty, $code:expr, $title:expr, +detail) => {
        impl_basic_err!($err, $code);

        impl $crate::common::error::ValicoError for $err {
            fn get_code(&self) -> &str { $code }
            fn get_title(&self) -> &str { $title }
            fn get_path(&self) -> &str { self.path.as_slice() }
            fn get_detail(&self) -> Option<&str> { Some(self.detail.as_slice()) }
        }
    };

    ($err:ty, $code:expr, $title:expr, +opt_detail) => {
        impl_basic_err!($err, $code);

        impl $crate::common::error::ValicoError for $err {
            fn get_code(&self) -> &str { $code }
            fn get_title(&self) -> &str { $title }
            fn get_path(&self) -> &str { self.path.as_slice() }
            fn get_detail(&self) -> Option<&str> { self.detail.as_ref().map(|s| s.as_slice()) }
        }
    }
}

macro_rules! impl_to_json{
    ($err:ty) => {
        impl json::ToJson for $err {
            fn to_json(&self) -> json::Json {
                let mut map = ::std::collections::BTreeMap::new();
                map.insert("code".to_string(), self.get_code().to_json());
                map.insert("title".to_string(), self.get_title().to_json());
                map.insert("path".to_string(), self.get_path().to_json());
                match self.get_detail() {
                    Some(ref detail) => { map.insert("detail".to_string(), detail.to_json()); },
                    None => ()
                }
                json::Json::Object(map)
            }
        }
    };
    ($err:ty, $($sp:expr),+) => {
        impl json::ToJson for $err {
            fn to_json(&self) -> json::Json {
                let mut map = ::std::collections::BTreeMap::new();
                map.insert("code".to_string(), self.get_code().to_json());
                map.insert("title".to_string(), self.get_title().to_json());
                map.insert("path".to_string(), self.get_path().to_json());
                match self.get_detail() {
                    Some(ref detail) => { map.insert("detail".to_string(), detail.to_json()); },
                    None => ()
                }
                $({
                    let closure = $sp;
                    closure(self, &mut map);
                })+
                json::Json::Object(map)
            }
        }
    }
}<commit_msg>feat(common): impl ToJson for Box<ValicoError><commit_after>use std::error::{self, Error};
use std::fmt;
use std::any;
use rustc_serialize::json;

pub trait ValicoError: error::Error + fmt::Debug + Send + any::Any + json::ToJson {
    fn get_code(&self) -> &str;
    fn get_path(&self) -> &str;
    fn get_title(&self) -> &str;
    fn get_detail(&self) -> Option<&str> { None }
}

impl json::ToJson for Box<ValicoError> {
    fn to_json(&self) -> json::Json {
        (**self).to_json()
    }
}

pub type ValicoErrors = Vec<Box<ValicoError>>;

mopafy!(ValicoError);

macro_rules! impl_basic_err {
    ($err:ty, $code:expr) => {
        impl ::std::error::Error for $err {
            fn description(&self) -> &str {
                $code
            }
        }

        impl ::std::fmt::Display for $err {
            fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                self.description().fmt(formatter)
            }
        }
    }
}

macro_rules! impl_err {
    ($err:ty, $code:expr, $title:expr) => {
        impl_basic_err!($err, $code);

        impl $crate::common::error::ValicoError for $err {
            fn get_code(&self) -> &str { $code }
            fn get_title(&self) -> &str { $title }
            fn get_path(&self) -> &str { self.path.as_slice() }
        }
    };

    ($err:ty, $code:expr, $title:expr, +detail) => {
        impl_basic_err!($err, $code);

        impl $crate::common::error::ValicoError for $err {
            fn get_code(&self) -> &str { $code }
            fn get_title(&self) -> &str { $title }
            fn get_path(&self) -> &str { self.path.as_slice() }
            fn get_detail(&self) -> Option<&str> { Some(self.detail.as_slice()) }
        }
    };

    ($err:ty, $code:expr, $title:expr, +opt_detail) => {
        impl_basic_err!($err, $code);

        impl $crate::common::error::ValicoError for $err {
            fn get_code(&self) -> &str { $code }
            fn get_title(&self) -> &str { $title }
            fn get_path(&self) -> &str { self.path.as_slice() }
            fn get_detail(&self) -> Option<&str> { self.detail.as_ref().map(|s| s.as_slice()) }
        }
    }
}

macro_rules! impl_to_json{
    ($err:ty) => {
        impl json::ToJson for $err {
            fn to_json(&self) -> json::Json {
                let mut map = ::std::collections::BTreeMap::new();
                map.insert("code".to_string(), self.get_code().to_json());
                map.insert("title".to_string(), self.get_title().to_json());
                map.insert("path".to_string(), self.get_path().to_json());
                match self.get_detail() {
                    Some(ref detail) => { map.insert("detail".to_string(), detail.to_json()); },
                    None => ()
                }
                json::Json::Object(map)
            }
        }
    };
    ($err:ty, $($sp:expr),+) => {
        impl json::ToJson for $err {
            fn to_json(&self) -> json::Json {
                let mut map = ::std::collections::BTreeMap::new();
                map.insert("code".to_string(), self.get_code().to_json());
                map.insert("title".to_string(), self.get_title().to_json());
                map.insert("path".to_string(), self.get_path().to_json());
                match self.get_detail() {
                    Some(ref detail) => { map.insert("detail".to_string(), detail.to_json()); },
                    None => ()
                }
                $({
                    let closure = $sp;
                    closure(self, &mut map);
                })+
                json::Json::Object(map)
            }
        }
    }
}<|endoftext|>


<commit_before>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type HashFn<K> = pure fn~(K) -> uint;
type EqFn<K> = pure fn~(K, K) -> bool;

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    type Bucket<K,V> = {hash: uint, key: K, value: V};
    enum LinearMap<K,V> {
        LinearMap_({
            hashfn: pure fn~(x: &K) -> uint,
            eqfn: pure fn~(x: &K, y: &K) -> bool,
            resize_at: uint,
            size: uint,
            buckets: ~[option<Bucket<K,V>>]})
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn linear_map<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> LinearMap<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> LinearMap<K,V> {

        LinearMap_({
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| none)})
    }

    priv impl<K, V> LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(&const self,
                          h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(&const self,
                            idx: uint,
                            len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n);
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(&const self,
                                hash: uint,
                                op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(&const self,
                               buckets: &[option<Bucket<K,V>>],
                               k: &K) -> SearchResult {
            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(&const self,
                                         buckets: &[option<Bucket<K,V>>],
                                         hash: uint,
                                         k: &K) -> SearchResult {
            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                  some(bkt) => if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                    return FoundEntry(i);
                  },
                  none => return FoundHole(i)
                }
            };
            return TableFull;
        }

        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand(&mut self) {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| none);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = none;
                bucket <-> old_buckets[i];
                if bucket.is_some() {
                    self.insert_bucket(bucket);
                }
            }
        }

        fn insert_bucket(&mut self, +bucket: option<Bucket<K,V>>) {
            let {hash, key, value} <- option::unwrap(bucket);
            let _ = self.insert_internal(hash, key, value);
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
              TableFull => {fail ~"Internal logic error";}
              FoundHole(idx) => {
                debug!("insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                self.size += 1;
                return true;
              }
              FoundEntry(idx) => {
                debug!("insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                return false;
              }
            }
        }

        fn search(&self,
                  hash: uint,
                  op: fn(x: &option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K,V> LinearMap<K,V> {
        fn insert(&mut self, +k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(&k);
            self.insert_internal(hash, k, v)
        }

        fn remove(&mut self, k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
              TableFull | FoundHole(_) => {
                return false;
              }
              FoundEntry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = none;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = none;
                bucket <-> self.buckets[idx];
                self.insert_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear(&mut self) {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = none;
            }
            self.size = 0;
        }

        pure fn len(&const self) -> uint {
            self.size
        }

        pure fn is_empty(&const self) -> bool {
            self.len() == 0
        }

        fn contains_key(&const self,
                        k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(_) => {true}
              TableFull | FoundHole(_) => {false}
            }
        }

        /*
        FIXME(#3148)--region inference fails to capture needed deps

        fn find_ref(&self, k: &K) -> option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(ref bkt) => some(&bkt.value)
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }
        */

        fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }

        fn each_key_ref(&self, blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }

        fn each_value_ref(&self, blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K,V: copy> LinearMap<K,V> {
        fn find(&const self, k: &K) -> option<V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(bkt) => {some(copy bkt.value)}
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }

        fn get(&const self, k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!("No entry found for key: %?", k);
            }
            option::unwrap(value)
        }

    }

    impl<K: copy, V: copy> LinearMap<K,V> {
        fn each(&self, blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: copy, V> LinearMap<K,V> {
        fn each_key(&self, blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K, V: copy> LinearMap<K,V> {
        fn each_value(&self, blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    import linear::{LinearMap, linear_map};

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return linear_map(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        for uint::range(0, 32) |i| {
            assert (&mut m).insert(i, i*2);
        }
        let mut observed = 0;
        for (&m).each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }
}
<commit_msg>Remove one last match check, in send_map<commit_after>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type HashFn<K> = pure fn~(K) -> uint;
type EqFn<K> = pure fn~(K, K) -> bool;

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    type Bucket<K,V> = {hash: uint, key: K, value: V};
    enum LinearMap<K,V> {
        LinearMap_({
            hashfn: pure fn~(x: &K) -> uint,
            eqfn: pure fn~(x: &K, y: &K) -> bool,
            resize_at: uint,
            size: uint,
            buckets: ~[option<Bucket<K,V>>]})
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn linear_map<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> LinearMap<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> LinearMap<K,V> {

        LinearMap_({
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| none)})
    }

    priv impl<K, V> LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(&const self,
                          h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(&const self,
                            idx: uint,
                            len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!("next_bucket(%?, %?) = %?", idx, len_buckets, n);
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(&const self,
                                hash: uint,
                                op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(&const self,
                               buckets: &[option<Bucket<K,V>>],
                               k: &K) -> SearchResult {
            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(&const self,
                                         buckets: &[option<Bucket<K,V>>],
                                         hash: uint,
                                         k: &K) -> SearchResult {
            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                  some(bkt) => if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                    return FoundEntry(i);
                  },
                  none => return FoundHole(i)
                }
            };
            return TableFull;
        }

        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand(&mut self) {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| none);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = none;
                bucket <-> old_buckets[i];
                if bucket.is_some() {
                    self.insert_bucket(bucket);
                }
            }
        }

        fn insert_bucket(&mut self, +bucket: option<Bucket<K,V>>) {
            let {hash, key, value} <- option::unwrap(bucket);
            let _ = self.insert_internal(hash, key, value);
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(&mut self, hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
              TableFull => {fail ~"Internal logic error";}
              FoundHole(idx) => {
                debug!("insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                self.size += 1;
                return true;
              }
              FoundEntry(idx) => {
                debug!("insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash);
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                return false;
              }
            }
        }

        fn search(&self,
                  hash: uint,
                  op: fn(x: &option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K,V> LinearMap<K,V> {
        fn insert(&mut self, +k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(&k);
            self.insert_internal(hash, k, v)
        }

        fn remove(&mut self, k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
              TableFull | FoundHole(_) => {
                return false;
              }
              FoundEntry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = none;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = none;
                bucket <-> self.buckets[idx];
                self.insert_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear(&mut self) {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = none;
            }
            self.size = 0;
        }

        pure fn len(&const self) -> uint {
            self.size
        }

        pure fn is_empty(&const self) -> bool {
            self.len() == 0
        }

        fn contains_key(&const self,
                        k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(_) => {true}
              TableFull | FoundHole(_) => {false}
            }
        }

        /*
        FIXME(#3148)--region inference fails to capture needed deps

        fn find_ref(&self, k: &K) -> option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(ref bkt) => some(&bkt.value)
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }
        */

        fn each_ref(&self, blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }

        fn each_key_ref(&self, blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }

        fn each_value_ref(&self, blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K,V: copy> LinearMap<K,V> {
        fn find(&const self, k: &K) -> option<V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                // FIXME (#3148): Once we rewrite found_entry, this
                // failure case won't be necessary
                match self.buckets[idx] {
                    some(bkt) => {some(copy bkt.value)}
                    none => fail ~"LinearMap::find: internal logic error"
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }

        fn get(&const self, k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!("No entry found for key: %?", k);
            }
            option::unwrap(value)
        }

    }

    impl<K: copy, V: copy> LinearMap<K,V> {
        fn each(&self, blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: copy, V> LinearMap<K,V> {
        fn each_key(&self, blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K, V: copy> LinearMap<K,V> {
        fn each_value(&self, blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    import linear::{LinearMap, linear_map};

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return linear_map(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        for uint::range(0, 32) |i| {
            assert (&mut m).insert(i, i*2);
        }
        let mut observed = 0;
        for (&m).each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }
}
<|endoftext|>


<commit_before>/*!

The `ToBytes` and `IterBytes` traits

*/

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use io::Writer;

pub type Cb = fn(buf: &[const u8]) -> bool;

/**
 * A trait to implement in order to make a type hashable;
 * This works in combination with the trait `Hash::Hash`, and
 * may in the future be merged with that trait or otherwise
 * modified when default methods and trait inheritence are
 * completed.
 */
pub trait IterBytes {
    /**
     * Call the provided callback `f` one or more times with
     * byte-slices that should be used when computing a hash
     * value or otherwise "flattening" the structure into
     * a sequence of bytes. The `lsb0` parameter conveys
     * whether the caller is asking for little-endian bytes
     * (`true`) or big-endian (`false`); this should only be
     * relevant in implementations that represent a single
     * multi-byte datum such as a 32 bit integer or 64 bit
     * floating-point value. It can be safely ignored for
     * larger structured types as they are usually processed
     * left-to-right in declaration order, regardless of
     * underlying memory endianness.
     */
    pure fn iter_bytes(lsb0: bool, f: Cb);
}

impl bool: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        f([
            self as u8
        ]);
    }
}

impl u8: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        f([
            self
        ]);
    }
}

impl u16: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        if lsb0 {
            f([
                self as u8,
                (self >> 8) as u8
            ]);
        } else {
            f([
                (self >> 8) as u8,
                self as u8
            ]);
        }
    }
}

impl u32: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        if lsb0 {
            f([
                self as u8,
                (self >> 8) as u8,
                (self >> 16) as u8,
                (self >> 24) as u8,
            ]);
        } else {
            f([
                (self >> 24) as u8,
                (self >> 16) as u8,
                (self >> 8) as u8,
                self as u8
            ]);
        }
    }
}

impl u64: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        if lsb0 {
            f([
                self as u8,
                (self >> 8) as u8,
                (self >> 16) as u8,
                (self >> 24) as u8,
                (self >> 32) as u8,
                (self >> 40) as u8,
                (self >> 48) as u8,
                (self >> 56) as u8
            ]);
        } else {
            f([
                (self >> 56) as u8,
                (self >> 48) as u8,
                (self >> 40) as u8,
                (self >> 32) as u8,
                (self >> 24) as u8,
                (self >> 16) as u8,
                (self >> 8) as u8,
                self as u8
            ]);
        }
    }
}

impl i8: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u8).iter_bytes(lsb0, f)
    }
}

impl i16: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u16).iter_bytes(lsb0, f)
    }
}

impl i32: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u32).iter_bytes(lsb0, f)
    }
}

impl i64: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u64).iter_bytes(lsb0, f)
    }
}

impl char: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "32")]
impl uint: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "64")]
impl uint: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u64).iter_bytes(lsb0, f)
    }
}

impl int: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as uint).iter_bytes(lsb0, f)
    }
}

impl<A: IterBytes> &[A]: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        for self.each |elt| {
            do elt.iter_bytes(lsb0) |bytes| {
                f(bytes)
            }
        }
    }
}

impl<A: IterBytes, B: IterBytes> (A,B): IterBytes {
  #[inline(always)]
  pure fn iter_bytes(lsb0: bool, f: Cb) {
    match self {
      (ref a, ref b) => {
        a.iter_bytes(lsb0, f);
        b.iter_bytes(lsb0, f);
      }
    }
  }
}

impl<A: IterBytes, B: IterBytes, C: IterBytes> (A,B,C): IterBytes {
  #[inline(always)]
  pure fn iter_bytes(lsb0: bool, f: Cb) {
    match self {
      (ref a, ref b, ref c) => {
        a.iter_bytes(lsb0, f);
        b.iter_bytes(lsb0, f);
        c.iter_bytes(lsb0, f);
      }
    }
  }
}

// Move this to vec, probably.
pure fn borrow<A>(a: &x/[A]) -> &x/[A] {
    a
}

impl<A: IterBytes> ~[A]: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        borrow(self).iter_bytes(lsb0, f)
    }
}

impl<A: IterBytes> @[A]: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        borrow(self).iter_bytes(lsb0, f)
    }
}

pub pure fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
                                            lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_3<A: IterBytes,
                B: IterBytes,
                C: IterBytes>(a: &A, b: &B, c: &C,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_4<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_5<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes,
                E: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D, e: &E,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_6<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes,
                E: IterBytes,
                F: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D, e: &E, f: &F,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_7<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes,
                E: IterBytes,
                F: IterBytes,
                G: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D, e: &E, f: &F,
                              g: &G,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    g.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

impl &str: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        do str::byte_slice(self) |bytes| {
            f(bytes);
        }
    }
}

impl ~str: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        do str::byte_slice(self) |bytes| {
            f(bytes);
        }
    }
}

impl @str: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        do str::byte_slice(self) |bytes| {
            f(bytes);
        }
    }
}

impl<A: IterBytes> Option<A>: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        match self {
          Some(ref a) => iter_bytes_2(&0u8, a, lsb0, f),
          None => 1u8.iter_bytes(lsb0, f)
        }
    }
}

impl<A: IterBytes> &A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (*self).iter_bytes(lsb0, f);
    }
}

impl<A: IterBytes> @A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (*self).iter_bytes(lsb0, f);
    }
}

impl<A: IterBytes> ~A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (*self).iter_bytes(lsb0, f);
    }
}

// NB: raw-pointer IterBytes does _not_ dereference
// to the target; it just gives you the pointer-bytes.
impl<A> *const A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as uint).iter_bytes(lsb0, f);
    }
}

trait ToBytes {
    fn to_bytes(lsb0: bool) -> ~[u8];
}

impl<A: IterBytes> A: ToBytes {
    fn to_bytes(lsb0: bool) -> ~[u8] {
        do io::with_bytes_writer |wr| {
            for self.iter_bytes(lsb0) |bytes| {
                wr.write(bytes)
            }
        }
    }
}
<commit_msg>call out to iter_bytes_{2,3} in IterBytes instances for pairs, triples<commit_after>/*!

The `ToBytes` and `IterBytes` traits

*/

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use io::Writer;

pub type Cb = fn(buf: &[const u8]) -> bool;

/**
 * A trait to implement in order to make a type hashable;
 * This works in combination with the trait `Hash::Hash`, and
 * may in the future be merged with that trait or otherwise
 * modified when default methods and trait inheritence are
 * completed.
 */
pub trait IterBytes {
    /**
     * Call the provided callback `f` one or more times with
     * byte-slices that should be used when computing a hash
     * value or otherwise "flattening" the structure into
     * a sequence of bytes. The `lsb0` parameter conveys
     * whether the caller is asking for little-endian bytes
     * (`true`) or big-endian (`false`); this should only be
     * relevant in implementations that represent a single
     * multi-byte datum such as a 32 bit integer or 64 bit
     * floating-point value. It can be safely ignored for
     * larger structured types as they are usually processed
     * left-to-right in declaration order, regardless of
     * underlying memory endianness.
     */
    pure fn iter_bytes(lsb0: bool, f: Cb);
}

impl bool: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        f([
            self as u8
        ]);
    }
}

impl u8: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        f([
            self
        ]);
    }
}

impl u16: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        if lsb0 {
            f([
                self as u8,
                (self >> 8) as u8
            ]);
        } else {
            f([
                (self >> 8) as u8,
                self as u8
            ]);
        }
    }
}

impl u32: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        if lsb0 {
            f([
                self as u8,
                (self >> 8) as u8,
                (self >> 16) as u8,
                (self >> 24) as u8,
            ]);
        } else {
            f([
                (self >> 24) as u8,
                (self >> 16) as u8,
                (self >> 8) as u8,
                self as u8
            ]);
        }
    }
}

impl u64: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        if lsb0 {
            f([
                self as u8,
                (self >> 8) as u8,
                (self >> 16) as u8,
                (self >> 24) as u8,
                (self >> 32) as u8,
                (self >> 40) as u8,
                (self >> 48) as u8,
                (self >> 56) as u8
            ]);
        } else {
            f([
                (self >> 56) as u8,
                (self >> 48) as u8,
                (self >> 40) as u8,
                (self >> 32) as u8,
                (self >> 24) as u8,
                (self >> 16) as u8,
                (self >> 8) as u8,
                self as u8
            ]);
        }
    }
}

impl i8: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u8).iter_bytes(lsb0, f)
    }
}

impl i16: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u16).iter_bytes(lsb0, f)
    }
}

impl i32: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u32).iter_bytes(lsb0, f)
    }
}

impl i64: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u64).iter_bytes(lsb0, f)
    }
}

impl char: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "32")]
impl uint: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "64")]
impl uint: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as u64).iter_bytes(lsb0, f)
    }
}

impl int: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as uint).iter_bytes(lsb0, f)
    }
}

impl<A: IterBytes> &[A]: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        for self.each |elt| {
            do elt.iter_bytes(lsb0) |bytes| {
                f(bytes)
            }
        }
    }
}

impl<A: IterBytes, B: IterBytes> (A,B): IterBytes {
  #[inline(always)]
  pure fn iter_bytes(lsb0: bool, f: Cb) {
    match self {
      (ref a, ref b) => {
        iter_bytes_2(a, b, lsb0, f);
      }
    }
  }
}

impl<A: IterBytes, B: IterBytes, C: IterBytes> (A,B,C): IterBytes {
  #[inline(always)]
  pure fn iter_bytes(lsb0: bool, f: Cb) {
    match self {
      (ref a, ref b, ref c) => {
        iter_bytes_3(a, b, c, lsb0, f);
      }
    }
  }
}

// Move this to vec, probably.
pure fn borrow<A>(a: &x/[A]) -> &x/[A] {
    a
}

impl<A: IterBytes> ~[A]: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        borrow(self).iter_bytes(lsb0, f)
    }
}

impl<A: IterBytes> @[A]: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        borrow(self).iter_bytes(lsb0, f)
    }
}

pub pure fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
                                            lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_3<A: IterBytes,
                B: IterBytes,
                C: IterBytes>(a: &A, b: &B, c: &C,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_4<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_5<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes,
                E: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D, e: &E,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_6<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes,
                E: IterBytes,
                F: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D, e: &E, f: &F,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

pub pure fn iter_bytes_7<A: IterBytes,
                B: IterBytes,
                C: IterBytes,
                D: IterBytes,
                E: IterBytes,
                F: IterBytes,
                G: IterBytes>(a: &A, b: &B, c: &C,
                              d: &D, e: &E, f: &F,
                              g: &G,
                              lsb0: bool, z: Cb) {
    let mut flag = true;
    a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
    if !flag { return; }
    g.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
}

impl &str: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        do str::byte_slice(self) |bytes| {
            f(bytes);
        }
    }
}

impl ~str: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        do str::byte_slice(self) |bytes| {
            f(bytes);
        }
    }
}

impl @str: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(_lsb0: bool, f: Cb) {
        do str::byte_slice(self) |bytes| {
            f(bytes);
        }
    }
}

impl<A: IterBytes> Option<A>: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        match self {
          Some(ref a) => iter_bytes_2(&0u8, a, lsb0, f),
          None => 1u8.iter_bytes(lsb0, f)
        }
    }
}

impl<A: IterBytes> &A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (*self).iter_bytes(lsb0, f);
    }
}

impl<A: IterBytes> @A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (*self).iter_bytes(lsb0, f);
    }
}

impl<A: IterBytes> ~A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (*self).iter_bytes(lsb0, f);
    }
}

// NB: raw-pointer IterBytes does _not_ dereference
// to the target; it just gives you the pointer-bytes.
impl<A> *const A: IterBytes {
    #[inline(always)]
    pure fn iter_bytes(lsb0: bool, f: Cb) {
        (self as uint).iter_bytes(lsb0, f);
    }
}

trait ToBytes {
    fn to_bytes(lsb0: bool) -> ~[u8];
}

impl<A: IterBytes> A: ToBytes {
    fn to_bytes(lsb0: bool) -> ~[u8] {
        do io::with_bytes_writer |wr| {
            for self.iter_bytes(lsb0) |bytes| {
                wr.write(bytes)
            }
        }
    }
}
<|endoftext|>


<commit_before>import bar::baz;
import foo::zed;
mod foo {
    mod zed {
        fn baz() { #debug("baz"); }
    }
}
mod bar {
    import zed::baz;
    export baz;
    mod foo {
        mod zed { }
    }
}
fn main(args: [str]) { baz(); }
<commit_msg>test: Swap the order of two imports in import7 to eliminate another cycle<commit_after>import foo::zed;
import bar::baz;
mod foo {
    mod zed {
        fn baz() { #debug("baz"); }
    }
}
mod bar {
    import zed::baz;
    export baz;
    mod foo {
        mod zed { }
    }
}
fn main(args: [str]) { baz(); }
<|endoftext|>