<commit_before>#[rustfmt::skip]

use rustc_span::symbol::{sym, Symbol};

use rustc_session::Session;

// Copied from https://github.com/rust-lang/rust/blob/e7f6ed14d5de2199d0e8a3c1e41f80e43885cb5c/src/librustc_codegen_llvm/llvm_util.rs#L139-L275

// WARNING: the features after applying `to_llvm_feature` must be known
// to LLVM or the feature detection code will walk past the end of the feature
// array, leading to crashes.

const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("aclass", Some(sym::arm_target_feature)),
    ("mclass", Some(sym::arm_target_feature)),
    ("rclass", Some(sym::arm_target_feature)),
    ("dsp", Some(sym::arm_target_feature)),
    ("neon", Some(sym::arm_target_feature)),
    ("crc", Some(sym::arm_target_feature)),
    ("crypto", Some(sym::arm_target_feature)),
    ("v5te", Some(sym::arm_target_feature)),
    ("v6", Some(sym::arm_target_feature)),
    ("v6k", Some(sym::arm_target_feature)),
    ("v6t2", Some(sym::arm_target_feature)),
    ("v7", Some(sym::arm_target_feature)),
    ("v8", Some(sym::arm_target_feature)),
    ("vfp2", Some(sym::arm_target_feature)),
    ("vfp3", Some(sym::arm_target_feature)),
    ("vfp4", Some(sym::arm_target_feature)),
    // This is needed for inline assembly, but shouldn't be stabilized as-is
    // since it should be enabled per-function using #[instruction_set], not
    // #[target_feature].
    ("thumb-mode", Some(sym::arm_target_feature)),
];

const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("fp", Some(sym::aarch64_target_feature)),
    ("neon", Some(sym::aarch64_target_feature)),
    ("sve", Some(sym::aarch64_target_feature)),
    ("crc", Some(sym::aarch64_target_feature)),
    ("crypto", Some(sym::aarch64_target_feature)),
    ("ras", Some(sym::aarch64_target_feature)),
    ("lse", Some(sym::aarch64_target_feature)),
    ("rdm", Some(sym::aarch64_target_feature)),
    ("fp16", Some(sym::aarch64_target_feature)),
    ("rcpc", Some(sym::aarch64_target_feature)),
    ("dotprod", Some(sym::aarch64_target_feature)),
    ("tme", Some(sym::aarch64_target_feature)),
    ("v8.1a", Some(sym::aarch64_target_feature)),
    ("v8.2a", Some(sym::aarch64_target_feature)),
    ("v8.3a", Some(sym::aarch64_target_feature)),
];

const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("adx", Some(sym::adx_target_feature)),
    ("aes", None),
    ("avx", None),
    ("avx2", None),
    ("avx512bw", Some(sym::avx512_target_feature)),
    ("avx512cd", Some(sym::avx512_target_feature)),
    ("avx512dq", Some(sym::avx512_target_feature)),
    ("avx512er", Some(sym::avx512_target_feature)),
    ("avx512f", Some(sym::avx512_target_feature)),
    ("avx512ifma", Some(sym::avx512_target_feature)),
    ("avx512pf", Some(sym::avx512_target_feature)),
    ("avx512vbmi", Some(sym::avx512_target_feature)),
    ("avx512vl", Some(sym::avx512_target_feature)),
    ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
    ("bmi1", None),
    ("bmi2", None),
    ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)),
    ("f16c", Some(sym::f16c_target_feature)),
    ("fma", None),
    ("fxsr", None),
    ("lzcnt", None),
    ("mmx", Some(sym::mmx_target_feature)),
    ("movbe", Some(sym::movbe_target_feature)),
    ("pclmulqdq", None),
    ("popcnt", None),
    ("rdrand", None),
    ("rdseed", None),
    ("rtm", Some(sym::rtm_target_feature)),
    ("sha", None),
    ("sse", None),
    ("sse2", None),
    ("sse3", None),
    ("sse4.1", None),
    ("sse4.2", None),
    ("sse4a", Some(sym::sse4a_target_feature)),
    ("ssse3", None),
    ("tbm", Some(sym::tbm_target_feature)),
    ("xsave", None),
    ("xsavec", None),
    ("xsaveopt", None),
    ("xsaves", None),
];

const HEXAGON_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("hvx", Some(sym::hexagon_target_feature)),
    ("hvx-length128b", Some(sym::hexagon_target_feature)),
];

const POWERPC_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("altivec", Some(sym::powerpc_target_feature)),
    ("power8-altivec", Some(sym::powerpc_target_feature)),
    ("power9-altivec", Some(sym::powerpc_target_feature)),
    ("power8-vector", Some(sym::powerpc_target_feature)),
    ("power9-vector", Some(sym::powerpc_target_feature)),
    ("vsx", Some(sym::powerpc_target_feature)),
];

const MIPS_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] =
    &[("fp64", Some(sym::mips_target_feature)), ("msa", Some(sym::mips_target_feature))];

const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("m", Some(sym::riscv_target_feature)),
    ("a", Some(sym::riscv_target_feature)),
    ("c", Some(sym::riscv_target_feature)),
    ("f", Some(sym::riscv_target_feature)),
    ("d", Some(sym::riscv_target_feature)),
    ("e", Some(sym::riscv_target_feature)),
];

const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("simd128", Some(sym::wasm_target_feature)),
    ("atomics", Some(sym::wasm_target_feature)),
    ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
];

/// When rustdoc is running, provide a list of all known features so that all their respective
/// primitives may be documented.
///
/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol>)> {
    std::iter::empty()
        .chain(ARM_ALLOWED_FEATURES.iter())
        .chain(AARCH64_ALLOWED_FEATURES.iter())
        .chain(X86_ALLOWED_FEATURES.iter())
        .chain(HEXAGON_ALLOWED_FEATURES.iter())
        .chain(POWERPC_ALLOWED_FEATURES.iter())
        .chain(MIPS_ALLOWED_FEATURES.iter())
        .chain(RISCV_ALLOWED_FEATURES.iter())
        .chain(WASM_ALLOWED_FEATURES.iter())
        .cloned()
}

pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Option<Symbol>)] {
    match &*sess.target.target.arch {
        "arm" => ARM_ALLOWED_FEATURES,
        "aarch64" => AARCH64_ALLOWED_FEATURES,
        "x86" | "x86_64" => X86_ALLOWED_FEATURES,
        "hexagon" => HEXAGON_ALLOWED_FEATURES,
        "mips" | "mips64" => MIPS_ALLOWED_FEATURES,
        "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
        "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
        "wasm32" => WASM_ALLOWED_FEATURES,
        _ => &[],
    }
}
<commit_msg>fmt: Skip whole module with bang<commit_after>#![rustfmt::skip]

use rustc_span::symbol::{sym, Symbol};

use rustc_session::Session;

// Copied from https://github.com/rust-lang/rust/blob/e7f6ed14d5de2199d0e8a3c1e41f80e43885cb5c/src/librustc_codegen_llvm/llvm_util.rs#L139-L275

// WARNING: the features after applying `to_llvm_feature` must be known
// to LLVM or the feature detection code will walk past the end of the feature
// array, leading to crashes.

const ARM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("aclass", Some(sym::arm_target_feature)),
    ("mclass", Some(sym::arm_target_feature)),
    ("rclass", Some(sym::arm_target_feature)),
    ("dsp", Some(sym::arm_target_feature)),
    ("neon", Some(sym::arm_target_feature)),
    ("crc", Some(sym::arm_target_feature)),
    ("crypto", Some(sym::arm_target_feature)),
    ("v5te", Some(sym::arm_target_feature)),
    ("v6", Some(sym::arm_target_feature)),
    ("v6k", Some(sym::arm_target_feature)),
    ("v6t2", Some(sym::arm_target_feature)),
    ("v7", Some(sym::arm_target_feature)),
    ("v8", Some(sym::arm_target_feature)),
    ("vfp2", Some(sym::arm_target_feature)),
    ("vfp3", Some(sym::arm_target_feature)),
    ("vfp4", Some(sym::arm_target_feature)),
    // This is needed for inline assembly, but shouldn't be stabilized as-is
    // since it should be enabled per-function using #[instruction_set], not
    // #[target_feature].
    ("thumb-mode", Some(sym::arm_target_feature)),
];

const AARCH64_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("fp", Some(sym::aarch64_target_feature)),
    ("neon", Some(sym::aarch64_target_feature)),
    ("sve", Some(sym::aarch64_target_feature)),
    ("crc", Some(sym::aarch64_target_feature)),
    ("crypto", Some(sym::aarch64_target_feature)),
    ("ras", Some(sym::aarch64_target_feature)),
    ("lse", Some(sym::aarch64_target_feature)),
    ("rdm", Some(sym::aarch64_target_feature)),
    ("fp16", Some(sym::aarch64_target_feature)),
    ("rcpc", Some(sym::aarch64_target_feature)),
    ("dotprod", Some(sym::aarch64_target_feature)),
    ("tme", Some(sym::aarch64_target_feature)),
    ("v8.1a", Some(sym::aarch64_target_feature)),
    ("v8.2a", Some(sym::aarch64_target_feature)),
    ("v8.3a", Some(sym::aarch64_target_feature)),
];

const X86_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("adx", Some(sym::adx_target_feature)),
    ("aes", None),
    ("avx", None),
    ("avx2", None),
    ("avx512bw", Some(sym::avx512_target_feature)),
    ("avx512cd", Some(sym::avx512_target_feature)),
    ("avx512dq", Some(sym::avx512_target_feature)),
    ("avx512er", Some(sym::avx512_target_feature)),
    ("avx512f", Some(sym::avx512_target_feature)),
    ("avx512ifma", Some(sym::avx512_target_feature)),
    ("avx512pf", Some(sym::avx512_target_feature)),
    ("avx512vbmi", Some(sym::avx512_target_feature)),
    ("avx512vl", Some(sym::avx512_target_feature)),
    ("avx512vpopcntdq", Some(sym::avx512_target_feature)),
    ("bmi1", None),
    ("bmi2", None),
    ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)),
    ("f16c", Some(sym::f16c_target_feature)),
    ("fma", None),
    ("fxsr", None),
    ("lzcnt", None),
    ("mmx", Some(sym::mmx_target_feature)),
    ("movbe", Some(sym::movbe_target_feature)),
    ("pclmulqdq", None),
    ("popcnt", None),
    ("rdrand", None),
    ("rdseed", None),
    ("rtm", Some(sym::rtm_target_feature)),
    ("sha", None),
    ("sse", None),
    ("sse2", None),
    ("sse3", None),
    ("sse4.1", None),
    ("sse4.2", None),
    ("sse4a", Some(sym::sse4a_target_feature)),
    ("ssse3", None),
    ("tbm", Some(sym::tbm_target_feature)),
    ("xsave", None),
    ("xsavec", None),
    ("xsaveopt", None),
    ("xsaves", None),
];

const HEXAGON_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("hvx", Some(sym::hexagon_target_feature)),
    ("hvx-length128b", Some(sym::hexagon_target_feature)),
];

const POWERPC_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("altivec", Some(sym::powerpc_target_feature)),
    ("power8-altivec", Some(sym::powerpc_target_feature)),
    ("power9-altivec", Some(sym::powerpc_target_feature)),
    ("power8-vector", Some(sym::powerpc_target_feature)),
    ("power9-vector", Some(sym::powerpc_target_feature)),
    ("vsx", Some(sym::powerpc_target_feature)),
];

const MIPS_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] =
    &[("fp64", Some(sym::mips_target_feature)), ("msa", Some(sym::mips_target_feature))];

const RISCV_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("m", Some(sym::riscv_target_feature)),
    ("a", Some(sym::riscv_target_feature)),
    ("c", Some(sym::riscv_target_feature)),
    ("f", Some(sym::riscv_target_feature)),
    ("d", Some(sym::riscv_target_feature)),
    ("e", Some(sym::riscv_target_feature)),
];

const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
    ("simd128", Some(sym::wasm_target_feature)),
    ("atomics", Some(sym::wasm_target_feature)),
    ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
];

/// When rustdoc is running, provide a list of all known features so that all their respective
/// primitives may be documented.
///
/// IMPORTANT: If you're adding another feature list above, make sure to add it to this iterator!
pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol>)> {
    std::iter::empty()
        .chain(ARM_ALLOWED_FEATURES.iter())
        .chain(AARCH64_ALLOWED_FEATURES.iter())
        .chain(X86_ALLOWED_FEATURES.iter())
        .chain(HEXAGON_ALLOWED_FEATURES.iter())
        .chain(POWERPC_ALLOWED_FEATURES.iter())
        .chain(MIPS_ALLOWED_FEATURES.iter())
        .chain(RISCV_ALLOWED_FEATURES.iter())
        .chain(WASM_ALLOWED_FEATURES.iter())
        .cloned()
}

pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Option<Symbol>)] {
    match &*sess.target.target.arch {
        "arm" => ARM_ALLOWED_FEATURES,
        "aarch64" => AARCH64_ALLOWED_FEATURES,
        "x86" | "x86_64" => X86_ALLOWED_FEATURES,
        "hexagon" => HEXAGON_ALLOWED_FEATURES,
        "mips" | "mips64" => MIPS_ALLOWED_FEATURES,
        "powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
        "riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
        "wasm32" => WASM_ALLOWED_FEATURES,
        _ => &[],
    }
}
<|endoftext|>


<commit_before>//! Implementations of `Trace` and associated traits.
//!
//! The `Trace` trait provides access to an ordered collection of `(key, val, time, diff)` tuples, but
//! there is substantial flexibility in implementations of this trait. Depending on characteristics of
//! the data, we may wish to represent the data in different ways. This module contains several of these
//! implementations, and combiners for merging the results of different traces.
//!
//! As examples of implementations,
//!
//! *  The `trie` module is meant to represent general update tuples, with no particular assumptions made
//!    about their contents. It organizes the data first by key, then by val, and then leaves the rest
//!    in an unordered pile.
//!
//! *  The `keys` module is meant for collections whose value type is `()`, which is to say there is no
//!    (key, val) structure on the records; all of them are just viewed as "keys".
//!
//! *  The `time` module is meant for collections with a single time value. This can remove repetition
//!    from the representation, at the cost of requiring more instances and run-time merging.
//!
//! *  The `base` module is meant for collections with a single time value equivalent to the least time.
//!    These collections must always accumulate to non-negative collections, and as such we can indicate
//!    the frequency of an element by its multiplicity. This removes both the time and weight from the
//!    representation, but is only appropriate for a subset (often substantial) of the data.
//!
//! Each of these representations is best suited for different data, but they can be combined to get the
//! benefits of each, as appropriate. There are several `Cursor` combiners, `CursorList` and `CursorPair`,
//! for homogenous and inhomogenous cursors, respectively.
//!
//! #Musings
//!
//! What is less clear is how to transfer updates between the representations at merge time in a tasteful
//! way. Perhaps we could put an ordering on the representations, each pair with a dominant representation,
//! and part of merging the latter filters updates into the former. Although back and forth might be
//! appealing, more thinking is required to negotiate all of these policies.
//!
//! One option would be to require the layer builder to handle these smarts. Merging is currently done by
//! the layer as part of custom code, but we could make it simply be "iterate through cursor, push results
//! into 'ordered builder'". Then the builder would be bright enough to emit a "batch" for the composite
//! trace, rather than just a batch of the type merged.

pub mod spine;

mod radix_batcher;
mod merge_batcher;

// pub use self::radix_batcher::RadixBatcher as Batcher;
pub use self::merge_batcher::MergeBatcher as Batcher;

pub mod ord;
pub mod hash;
<commit_msg>don't make merge_batcher default yet<commit_after>//! Implementations of `Trace` and associated traits.
//!
//! The `Trace` trait provides access to an ordered collection of `(key, val, time, diff)` tuples, but
//! there is substantial flexibility in implementations of this trait. Depending on characteristics of
//! the data, we may wish to represent the data in different ways. This module contains several of these
//! implementations, and combiners for merging the results of different traces.
//!
//! As examples of implementations,
//!
//! *  The `trie` module is meant to represent general update tuples, with no particular assumptions made
//!    about their contents. It organizes the data first by key, then by val, and then leaves the rest
//!    in an unordered pile.
//!
//! *  The `keys` module is meant for collections whose value type is `()`, which is to say there is no
//!    (key, val) structure on the records; all of them are just viewed as "keys".
//!
//! *  The `time` module is meant for collections with a single time value. This can remove repetition
//!    from the representation, at the cost of requiring more instances and run-time merging.
//!
//! *  The `base` module is meant for collections with a single time value equivalent to the least time.
//!    These collections must always accumulate to non-negative collections, and as such we can indicate
//!    the frequency of an element by its multiplicity. This removes both the time and weight from the
//!    representation, but is only appropriate for a subset (often substantial) of the data.
//!
//! Each of these representations is best suited for different data, but they can be combined to get the
//! benefits of each, as appropriate. There are several `Cursor` combiners, `CursorList` and `CursorPair`,
//! for homogenous and inhomogenous cursors, respectively.
//!
//! #Musings
//!
//! What is less clear is how to transfer updates between the representations at merge time in a tasteful
//! way. Perhaps we could put an ordering on the representations, each pair with a dominant representation,
//! and part of merging the latter filters updates into the former. Although back and forth might be
//! appealing, more thinking is required to negotiate all of these policies.
//!
//! One option would be to require the layer builder to handle these smarts. Merging is currently done by
//! the layer as part of custom code, but we could make it simply be "iterate through cursor, push results
//! into 'ordered builder'". Then the builder would be bright enough to emit a "batch" for the composite
//! trace, rather than just a batch of the type merged.

pub mod spine;

mod radix_batcher;
mod merge_batcher;

pub use self::radix_batcher::RadixBatcher as Batcher;
// pub use self::merge_batcher::MergeBatcher as Batcher;

pub mod ord;
pub mod hash;
<|endoftext|>


<commit_before>#[feature(managed_boxes)];
/**
 * Snippets from the Dave Herman's presentation (2013-01-06)
 * http://www.infoq.com/presentations/Rust
 *
 * Dave Herman talks about Mozilla Rust and some of the features that make it safe, concurrent, and fast.
 *
 * 13. Dereferencing pointers
 * http://static.rust-lang.org/doc/master/tutorial.html#dereferencing-pointers
 */
struct Point {
	x: f64,
	y: f64
}

struct Rectangle (Point, Point);

impl Rectangle {
	fn area(&self) -> f64 {
		match *self {
			Rectangle(top_left, bottom_right) => (bottom_right.x - top_left.x) * (top_left.y - bottom_right.y)
		}
	}
}

fn print_point(p: &Point) {
	match *p {
		Point {x, y} => println!("({:f}, {:f})", x, y)
	}
}

fn main() {
	/*
	 * Snippets from the Dave Herman's presentation (2013-01-06)
	 * http://www.infoq.com/presentations/Rust
	 *
	 * Dave Herman talks about Mozilla Rust and some of the features that make it safe, concurrent, and fast.
	 */
	// Borrowed pointer to T
	// &T, in C++ : T&
	let p = Point{x:1.1, y:1.2};
	print_point(&p);
	// Managed pointer to T
	// @T, in C++ : shared_ptr<T>
	let p2 = @Point{x:2.1, y:2.2};
	print_point(p2);
	// Owned pointer to T
	// ~T, in C++ : unique_ptr<T>
	let p3 = ~Point{x:3.1, y:3.2};
	print_point(p3);
	// Unsafe pointer to T
	// *T
	/*
	let p4; // uninitialized
	print_point(p4); // error

	let p5 = ~Point {x:5.1, y:5.2};
	box.topLeft = move p5; // deinitialized
	print_point(p); // error
	*/

	/*
	 * 13. Dereferencing pointers
	 * http://static.rust-lang.org/doc/master/tutorial.html#dereferencing-pointers
	 */
	let managed = @10;
	let owned = ~20;
	let borrowed = &30;

	let sum = *managed + *owned + *borrowed;
	println!("{} + {} + {} = {}", *managed, *owned, *borrowed, sum);

	/*
	 * Dereferenced mutable pointers may appear on the left hand side of assignments.
	 * Such an assignment modifies the value that the pointer points to.
	 */
	let managed = @mut 10;
	let mut owned = ~20;

	let mut value = 30;
	let borrowed = &mut value;

	*managed = *owned + 10;
	*owned = *borrowed + 100;
	*borrowed = *managed + 1000;
	let sum = *managed + *owned + *borrowed;
	println!("{} + {} + {} = {}", *managed, *owned, *borrowed, sum);

	/*
	 * Pointers have high operator precedence, but lower precedence than the dot
	 * operator used for field and method access. This precedence order can
	 * sometimes make code awkward and parenthesis-filled.
	 *
	 * To combat this ugliness the dot operator applies automatic pointer
	 * dereferencing to the receiver (the value on the left-hand side of the dot),
	 * so in most cases, explicitly dereferencing the receiver is not necessary.
	 */
	let bottom = @Point { x: 10.0, y: 120.0 };
	let top = ~Point { x: bottom.x + 100.0, y: bottom.y - 100.0 };
	let rect = &Rectangle(*top, *bottom);
	let area = rect.area();
	println!("Area of rectangle {:?}: {:f}", rect, area);
}
<commit_msg>Remove example with '= @mut'<commit_after>#[feature(managed_boxes)];
/**
 * Snippets from the Dave Herman's presentation (2013-01-06)
 * http://www.infoq.com/presentations/Rust
 *
 * Dave Herman talks about Mozilla Rust and some of the features that make it safe, concurrent, and fast.
 *
 * 13. Dereferencing pointers
 * http://static.rust-lang.org/doc/master/tutorial.html#dereferencing-pointers
 */
struct Point {
	x: f64,
	y: f64
}

struct Rectangle (Point, Point);

impl Rectangle {
	fn area(&self) -> f64 {
		match *self {
			Rectangle(top_left, bottom_right) => (bottom_right.x - top_left.x) * (top_left.y - bottom_right.y)
		}
	}
}

fn print_point(p: &Point) {
	match *p {
		Point {x, y} => println!("({:f}, {:f})", x, y)
	}
}

fn main() {
	/*
	 * Snippets from the Dave Herman's presentation (2013-01-06)
	 * http://www.infoq.com/presentations/Rust
	 *
	 * Dave Herman talks about Mozilla Rust and some of the features that make it safe, concurrent, and fast.
	 */
	// Borrowed pointer to T
	// &T, in C++ : T&
	let p = Point{x:1.1, y:1.2};
	print_point(&p);
	// Managed pointer to T
	// @T, in C++ : shared_ptr<T>
	let p2 = @Point{x:2.1, y:2.2};
	print_point(p2);
	// Owned pointer to T
	// ~T, in C++ : unique_ptr<T>
	let p3 = ~Point{x:3.1, y:3.2};
	print_point(p3);
	// Unsafe pointer to T
	// *T
	/*
	let p4; // uninitialized
	print_point(p4); // error

	let p5 = ~Point {x:5.1, y:5.2};
	box.topLeft = move p5; // deinitialized
	print_point(p); // error
	*/

	/*
	 * 13. Dereferencing pointers
	 * http://static.rust-lang.org/doc/master/tutorial.html#dereferencing-pointers
	 */
	let managed = @10;
	let owned = ~20;
	let borrowed = &30;

	let sum = *managed + *owned + *borrowed;
	println!("{} + {} + {} = {}", *managed, *owned, *borrowed, sum);

	/*
	 * Dereferenced mutable pointers may appear on the left hand side of assignments.
	 * Such an assignment modifies the value that the pointer points to.
	 */
	let managed = @10;
	let mut owned = ~20;

	let mut value = 30;
	let borrowed = &mut value;

	*owned = *borrowed + 100;
	*borrowed = *managed + 1000;
	let sum = *managed + *owned + *borrowed;
	println!("{} + {} + {} = {}", *managed, *owned, *borrowed, sum);

	/*
	 * Pointers have high operator precedence, but lower precedence than the dot
	 * operator used for field and method access. This precedence order can
	 * sometimes make code awkward and parenthesis-filled.
	 *
	 * To combat this ugliness the dot operator applies automatic pointer
	 * dereferencing to the receiver (the value on the left-hand side of the dot),
	 * so in most cases, explicitly dereferencing the receiver is not necessary.
	 */
	let bottom = @Point { x: 10.0, y: 120.0 };
	let top = ~Point { x: bottom.x + 100.0, y: bottom.y - 100.0 };
	let rect = &Rectangle(*top, *bottom);
	let area = rect.area();
	println!("Area of rectangle {:?}: {:f}", rect, area);
}
<|endoftext|>


<commit_before>#[crate_id(name="tee", vers="1.0.0", author="Aleksander Bielawski")];
#[license="MIT"];

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Aleksander Bielawski <pabzdzdzwiagief@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern mod extra;

use std::io::{stdin, stdout, Append, File, Truncate, Write};
use std::io::{io_error, result, EndOfFile};
use std::io::signal::{Interrupt, Listener};
use std::io::util::{copy, MultiWriter};
use std::os::{args, set_exit_status};
use extra::getopts::groups::{getopts, optflag, usage};

static NAME: &'static str = "tee";
static VERSION: &'static str = "1.0.0";

fn main() {
    match options(args()).and_then(exec) {
        Err(message) => {
            warn(message);
            set_exit_status(1)
        },
        Ok(status) => set_exit_status(status)
    }
}

struct Options {
    program: ~str,
    append: bool,
    ignore_interrupts: bool,
    print_and_exit: Option<~str>,
    files: ~[Path]
}

fn options(args: &[~str]) -> Result<Options, ~str> {
    let opts = ~[
        optflag("a", "append", "append to the given FILEs, do not overwrite"),
        optflag("i", "ignore-interrupts", "ignore interrupt signals"),
        optflag("", "help", "display this help and exit"),
        optflag("", "version", "output version information and exit")];
    getopts(args.tail(), opts).map_err(|e| e.to_err_msg()).and_then(|m| {
        let version = format!("{} {}", NAME, VERSION);
        let program = args[0].clone();
        let arguments = "[OPTION]... [FILE]...";
        let brief = "Copy standard input to each FILE, and also to standard " +
                    "output.";
        let comment = "If a FILE is -, copy again to standard output.";
        let help = format!("{}\n\nUsage:\n  {} {}\n\n{}\n{}",
                           version, program, arguments, usage(brief, opts),
                           comment);
        let names = m.free + ~[~"-"];
        let to_print = if m.opt_present("help") { Some(help) }
                       else if m.opt_present("version") { Some(version) }
                       else { None };
        Ok(Options {
            program: program,
            append: m.opt_present("append"),
            ignore_interrupts: m.opt_present("ignore-interrupts"),
            print_and_exit: to_print,
            files: names.map(|name| Path::new(name.clone()))
        })
    })
}

fn exec(options: Options) -> Result<int, ~str> {
    match options.print_and_exit {
        Some(text) => {
            println(text);
            Ok(0)
        },
        None => tee(options)
    }
}

fn tee(options: Options) -> Result<int, ~str> {
    let mut handler = Listener::new();
    if options.ignore_interrupts {
        handler.register(Interrupt);
    }
    result(|| io_error::cond.trap(|e| {
        if e.kind != EndOfFile {
            io_error::cond.raise(e);
        }
    }).inside(|| {
        let writers = options.files.map(|path| open(path, options.append));
        let output = &mut MultiWriter::new(writers);
        let input = &mut stdin();
        copy(input, output);
        output.flush();
        0
    })).map_err(|err| err.desc.to_owned())
}

fn open(path: &Path, append: bool) -> ~Writer {
    if *path == Path::new("-") {
        ~stdout() as ~Writer
    } else {
        let mode = if append { Append } else { Truncate };
        ~File::open_mode(path, mode, Write) as ~Writer
    }
}

fn warn(message: &str) {
    error!("{}: {}", args()[0], message);
}
<commit_msg>Make tee keep going on errors<commit_after>#[crate_id(name="tee", vers="1.0.0", author="Aleksander Bielawski")];
#[license="MIT"];

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Aleksander Bielawski <pabzdzdzwiagief@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern mod extra;

use std::io::{stdin, stdout, Append, File, Truncate, Write};
use std::io::{io_error, EndOfFile};
use std::io::signal::{Interrupt, Listener};
use std::io::util::{copy, NullWriter, MultiWriter};
use std::os::{args, set_exit_status};
use extra::getopts::groups::{getopts, optflag, usage};

static NAME: &'static str = "tee";
static VERSION: &'static str = "1.0.0";

fn main() {
    match options(args()).and_then(exec) {
        Ok(_) => set_exit_status(0),
        Err(_) => set_exit_status(1)
    }
}

struct Options {
    program: ~str,
    append: bool,
    ignore_interrupts: bool,
    print_and_exit: Option<~str>,
    files: ~[Path]
}

fn options(args: &[~str]) -> Result<Options, ()> {
    let opts = ~[
        optflag("a", "append", "append to the given FILEs, do not overwrite"),
        optflag("i", "ignore-interrupts", "ignore interrupt signals"),
        optflag("", "help", "display this help and exit"),
        optflag("", "version", "output version information and exit")];
    getopts(args.tail(), opts).map_err(|e| e.to_err_msg()).and_then(|m| {
        let version = format!("{} {}", NAME, VERSION);
        let program = args[0].clone();
        let arguments = "[OPTION]... [FILE]...";
        let brief = "Copy standard input to each FILE, and also to standard " +
                    "output.";
        let comment = "If a FILE is -, copy again to standard output.";
        let help = format!("{}\n\nUsage:\n  {} {}\n\n{}\n{}",
                           version, program, arguments, usage(brief, opts),
                           comment);
        let names = m.free + ~[~"-"];
        let to_print = if m.opt_present("help") { Some(help) }
                       else if m.opt_present("version") { Some(version) }
                       else { None };
        Ok(Options {
            program: program,
            append: m.opt_present("append"),
            ignore_interrupts: m.opt_present("ignore-interrupts"),
            print_and_exit: to_print,
            files: names.map(|name| Path::new(name.clone()))
        })
    }).map_err(|message| warn(message))
}

fn exec(options: Options) -> Result<(), ()> {
    match options.print_and_exit {
        Some(text) => Ok(println(text)),
        None => tee(options)
    }
}

fn tee(options: Options) -> Result<(), ()> {
    let mut handler = Listener::new();
    if options.ignore_interrupts {
        handler.register(Interrupt);
    }
    let mut ok = true;
    io_error::cond.trap(|_| ok = false).inside(|| {
        let writers = options.files.map(|path| open(path, options.append));
        let output = &mut MultiWriter::new(writers);
        let input = &mut NamedReader { inner: ~stdin() as ~Reader };
        copy(input, output);
        output.flush();
    });
    if ok { Ok(()) } else { Err(()) }
}

fn open(path: &Path, append: bool) -> ~Writer {
    let inner = with_path(path, || if *path == Path::new("-") {
        ~stdout() as ~Writer
    } else {
        let mode = if append { Append } else { Truncate };
        match File::open_mode(path, mode, Write) {
            Some(file) => ~file as ~Writer,
            None => ~NullWriter as ~Writer
        }
    });
    ~NamedWriter { inner: inner, path: ~path.clone() } as ~Writer
}

struct NamedWriter {
    priv inner: ~Writer,
    priv path: ~Path
}

impl Writer for NamedWriter {
    fn write(&mut self, buf: &[u8]) {
        with_path(self.path, || io_error::cond.trap(|e| {
            self.inner = ~NullWriter as ~Writer;
            io_error::cond.raise(e);
        }).inside(|| self.inner.write(buf)))
    }

    fn flush(&mut self) {
        with_path(self.path, || io_error::cond.trap(|e| {
            self.inner = ~NullWriter as ~Writer;
            io_error::cond.raise(e);
        }).inside(|| self.inner.flush()))
    }
}

struct NamedReader {
    priv inner: ~Reader
}

impl Reader for NamedReader {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
        with_path(&Path::new("stdin"), || io_error::cond.trap(|e| {
            if e.kind != EndOfFile {
                io_error::cond.raise(e)
            }
        }).inside(|| self.inner.read(buf)))

    }

    fn eof(&mut self) -> bool {
        self.inner.eof()
    }
}

fn with_path<T>(path: &Path, cb: || -> T) -> T {
    io_error::cond.trap(|e| {
        warn(format!("{}: {}", path.display(), e.desc));
        io_error::cond.raise(e);
    }).inside(cb)
}

fn warn(message: &str) {
    error!("{}: {}", args()[0], message);
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "cargo-clippy", allow(clone_on_ref_ptr))]
#![cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]

extern crate cairo;
extern crate cairo_sys;
extern crate cssparser;
extern crate float_cmp;
extern crate glib;
extern crate glib_sys;
extern crate itertools;
extern crate libc;
extern crate nalgebra;
extern crate owning_ref;
extern crate pango;
extern crate pango_cairo_sys;
extern crate pango_sys;
extern crate pangocairo;
extern crate regex;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate downcast_rs;

pub use attributes::rsvg_attribute_from_name;

pub use color::{rsvg_css_parse_color, ColorKind, ColorSpec};

pub use drawing_ctx::{
    rsvg_drawing_ctx_add_node_and_ancestors_to_stack,
    rsvg_drawing_ctx_draw_node_from_stack,
    rsvg_drawing_ctx_free,
    rsvg_drawing_ctx_get_ink_rect,
    rsvg_drawing_ctx_new,
};

pub use load::{rsvg_load_new_node, rsvg_load_set_node_atts};

pub use node::{
    rsvg_node_add_child,
    rsvg_node_children_iter_begin,
    rsvg_node_children_iter_end,
    rsvg_node_children_iter_next,
    rsvg_node_find_last_chars_child,
    rsvg_node_get_parent,
    rsvg_node_get_type,
    rsvg_node_is_same,
    rsvg_node_ref,
    rsvg_node_register_in_defs,
    rsvg_node_set_attribute_parse_error,
    rsvg_node_unref,
    rsvg_root_node_cascade,
};

pub use parsers::rsvg_css_parse_number_optional_number;

pub use property_bag::{
    rsvg_property_bag_free,
    rsvg_property_bag_iter_begin,
    rsvg_property_bag_iter_end,
    rsvg_property_bag_iter_next,
    rsvg_property_bag_new,
};

pub use state::{
    rsvg_state_free,
    rsvg_state_new,
    rsvg_state_parse_style_pair,
};

pub use structure::{rsvg_node_svg_apply_atts, rsvg_node_svg_get_size};

pub use text::{rsvg_node_chars_append, rsvg_node_chars_new};

#[macro_use]
mod coord_units;

#[macro_use]
mod float_eq_cairo;

#[macro_use]
mod property_macros;

mod aspect_ratio;
mod attributes;
mod bbox;
mod clip_path;
mod color;
mod cond;
mod defs;
mod drawing_ctx;
mod error;
pub mod filters;
mod gradient;
mod handle;
mod image;
mod iri;
mod length;
mod link;
mod load;
mod marker;
mod mask;
mod node;
mod paint_server;
mod parsers;
mod path_builder;
mod path_parser;
mod pattern;
mod property_bag;
mod rect;
mod shapes;
mod space;
mod srgb;
mod state;
mod stop;
mod structure;
pub mod surface_utils;
mod text;
mod transform;
mod unitinterval;
mod util;
mod viewbox;
mod viewport;
<commit_msg>rustfmt<commit_after>#![cfg_attr(feature = "cargo-clippy", allow(clone_on_ref_ptr))]
#![cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]

extern crate cairo;
extern crate cairo_sys;
extern crate cssparser;
extern crate float_cmp;
extern crate glib;
extern crate glib_sys;
extern crate itertools;
extern crate libc;
extern crate nalgebra;
extern crate owning_ref;
extern crate pango;
extern crate pango_cairo_sys;
extern crate pango_sys;
extern crate pangocairo;
extern crate regex;

#[macro_use]
extern crate lazy_static;

#[macro_use]
extern crate downcast_rs;

pub use attributes::rsvg_attribute_from_name;

pub use color::{rsvg_css_parse_color, ColorKind, ColorSpec};

pub use drawing_ctx::{
    rsvg_drawing_ctx_add_node_and_ancestors_to_stack,
    rsvg_drawing_ctx_draw_node_from_stack,
    rsvg_drawing_ctx_free,
    rsvg_drawing_ctx_get_ink_rect,
    rsvg_drawing_ctx_new,
};

pub use load::{rsvg_load_new_node, rsvg_load_set_node_atts};

pub use node::{
    rsvg_node_add_child,
    rsvg_node_children_iter_begin,
    rsvg_node_children_iter_end,
    rsvg_node_children_iter_next,
    rsvg_node_find_last_chars_child,
    rsvg_node_get_parent,
    rsvg_node_get_type,
    rsvg_node_is_same,
    rsvg_node_ref,
    rsvg_node_register_in_defs,
    rsvg_node_set_attribute_parse_error,
    rsvg_node_unref,
    rsvg_root_node_cascade,
};

pub use parsers::rsvg_css_parse_number_optional_number;

pub use property_bag::{
    rsvg_property_bag_free,
    rsvg_property_bag_iter_begin,
    rsvg_property_bag_iter_end,
    rsvg_property_bag_iter_next,
    rsvg_property_bag_new,
};

pub use state::{rsvg_state_free, rsvg_state_new, rsvg_state_parse_style_pair};

pub use structure::{rsvg_node_svg_apply_atts, rsvg_node_svg_get_size};

pub use text::{rsvg_node_chars_append, rsvg_node_chars_new};

#[macro_use]
mod coord_units;

#[macro_use]
mod float_eq_cairo;

#[macro_use]
mod property_macros;

mod aspect_ratio;
mod attributes;
mod bbox;
mod clip_path;
mod color;
mod cond;
mod defs;
mod drawing_ctx;
mod error;
pub mod filters;
mod gradient;
mod handle;
mod image;
mod iri;
mod length;
mod link;
mod load;
mod marker;
mod mask;
mod node;
mod paint_server;
mod parsers;
mod path_builder;
mod path_parser;
mod pattern;
mod property_bag;
mod rect;
mod shapes;
mod space;
mod srgb;
mod state;
mod stop;
mod structure;
pub mod surface_utils;
mod text;
mod transform;
mod unitinterval;
mod util;
mod viewbox;
mod viewport;
<|endoftext|>


<commit_before>use super::super::lsm::btree::Ordering;
use super::super::lsm::service::*;
use crate::index::EntryKey;
use crate::ram::types::Id;
use crate::{
    index::ranged::{
        client::RangedQueryClient,
        trees::{max_entry_key, min_entry_key},
    },
};
use bifrost::rpc::RPCError;
use std::sync::Arc;
use std::time::Duration;

pub struct ClientCursor {
    pub ids: Vec<Id>,
    next: Option<EntryKey>,
    query_client: Arc<RangedQueryClient>,
    ordering: Ordering,
    tree_key: EntryKey,
    pub pos: usize,
    buffer_size: u16,
}

impl ClientCursor {
    pub async fn new(
        ordering: Ordering,
        block: ServBlock,
        tree_key: EntryKey,
        query_client: Arc<RangedQueryClient>,
        buffer_size: u16,
    ) -> Result<Self, RPCError> {
        trace!(
            "Client cursor created with buffer next {:?}, tree key {:?}, block keys {:?}",
            block.next,
            tree_key,
            block.buffer
        );
        let next = block.next;
        let ids = block.buffer;
        Ok(Self {
            ids,
            query_client,
            tree_key,
            ordering,
            next,
            buffer_size,
            pos: 0,
        })
    }

    pub async fn next(&mut self) -> Result<Option<Id>, RPCError> {
        let mut res = None;
        if self.pos < self.ids.len() {
            res = Some(self.ids[self.pos]);
            self.pos += 1;
            if self.pos < self.ids.len() {
                return Ok(res);
            }
        }
        let current_key = if self.pos == 0 { None } else { self.ids.get(self.pos - 1) };
        let next_key = if let Some(key) = &self.next {
            // Have next, use it
            key
        } else {
            // Key does not in the tree, and next key is unknown.
            // Should refill by next tree and return the previous key
            self.refill_by_next_tree().await?;
            return Ok(res);
        };
        debug!("Buffer all used, refilling using key {:?}, current id {:?}, next id {:?}", next_key, current_key, next_key.id());
        let next_cursor = RangedQueryClient::seek(
            &self.query_client,
            next_key,
            self.ordering,
            self.buffer_size,
        )
        .await?;
        if let Some(cursor) = next_cursor {
            *self = cursor;
        } else {
            self.ids = vec![];
        }
        return Ok(res);
    }

    pub fn current(&self) -> Option<&Id> {
        match self.ids.get(self.pos) {
            Some(id ) => Some(id),
            _ => None,
        }
    }

    async fn refill_by_next_tree(&mut self) -> Result<(), RPCError> {
        debug!(
            "Refill by next tree, key {:?}, ordering {:?}",
            self.tree_key, self.ordering
        );
        loop {
            if let Some((tree_key, tree)) = self
                .query_client
                .next_tree(&self.tree_key, self.ordering)
                .await
                .unwrap()
            {
                debug!(
                    "Next tree for {:?} returns {:?}, lower key {:?}, ordering {:?}",
                    self.tree_key, tree, tree_key, self.ordering
                );
                let tree_client =
                    locate_tree_server_from_conshash(&tree.id, &self.query_client.conshash).await?;
                let seek_key = match self.ordering {
                    Ordering::Forward => min_entry_key(),
                    Ordering::Backward => max_entry_key(),
                };
                let seek_res = tree_client
                    .seek(
                        tree.id,
                        seek_key,
                        self.ordering,
                        self.buffer_size,
                        tree.epoch,
                    )
                    .await?;
                match seek_res {
                    OpResult::Successful(block) => {
                        if block.buffer.is_empty() {
                            // Clear, this will ensure the cursor returns 0
                            debug!("Tree refill seek returns empty block");
                            self.ids.clear();
                        } else {
                            debug!(
                                "Tree refill seek returns block sized {}",
                                block.buffer.len()
                            );
                            *self = Self::new(
                                self.ordering,
                                block,
                                tree_key,
                                self.query_client.clone(),
                                self.buffer_size,
                            )
                            .await?;
                        }
                        return Ok(());
                    }
                    OpResult::Migrating => {
                        tokio::time::sleep(Duration::from_millis(500)).await;
                    }
                    OpResult::OutOfBound | OpResult::NotFound => unreachable!(),
                    OpResult::EpochMissMatch(expect, actual) => {
                        debug!(
                            "Epoch mismatch on refill, expected {}, actual {}",
                            expect, actual
                        );
                    }
                }
            } else {
                debug!(
                    "Next tree for {:?} does not return anything. ordering {:?}",
                    self.tree_key, self.ordering
                );
                return Ok(());
            }
        }
    }
}
<commit_msg>adjust log level<commit_after>use super::super::lsm::btree::Ordering;
use super::super::lsm::service::*;
use crate::index::EntryKey;
use crate::ram::types::Id;
use crate::{
    index::ranged::{
        client::RangedQueryClient,
        trees::{max_entry_key, min_entry_key},
    },
};
use bifrost::rpc::RPCError;
use std::sync::Arc;
use std::time::Duration;

pub struct ClientCursor {
    pub ids: Vec<Id>,
    next: Option<EntryKey>,
    query_client: Arc<RangedQueryClient>,
    ordering: Ordering,
    tree_key: EntryKey,
    pub pos: usize,
    buffer_size: u16,
}

impl ClientCursor {
    pub async fn new(
        ordering: Ordering,
        block: ServBlock,
        tree_key: EntryKey,
        query_client: Arc<RangedQueryClient>,
        buffer_size: u16,
    ) -> Result<Self, RPCError> {
        trace!(
            "Client cursor created with buffer next {:?}, tree key {:?}, block keys {:?}",
            block.next,
            tree_key,
            block.buffer
        );
        let next = block.next;
        let ids = block.buffer;
        Ok(Self {
            ids,
            query_client,
            tree_key,
            ordering,
            next,
            buffer_size,
            pos: 0,
        })
    }

    pub async fn next(&mut self) -> Result<Option<Id>, RPCError> {
        let mut res = None;
        if self.pos < self.ids.len() {
            res = Some(self.ids[self.pos]);
            self.pos += 1;
            if self.pos < self.ids.len() {
                return Ok(res);
            }
        }
        let current_key = if self.pos == 0 { None } else { self.ids.get(self.pos - 1) };
        let next_key = if let Some(key) = &self.next {
            // Have next, use it
            key
        } else {
            // Key does not in the tree, and next key is unknown.
            // Should refill by next tree and return the previous key
            self.refill_by_next_tree().await?;
            return Ok(res);
        };
        trace!("Buffer all used, refilling using key {:?}, current id {:?}, next id {:?}", next_key, current_key, next_key.id());
        let next_cursor = RangedQueryClient::seek(
            &self.query_client,
            next_key,
            self.ordering,
            self.buffer_size,
        )
        .await?;
        if let Some(cursor) = next_cursor {
            *self = cursor;
        } else {
            self.ids = vec![];
        }
        return Ok(res);
    }

    pub fn current(&self) -> Option<&Id> {
        match self.ids.get(self.pos) {
            Some(id ) => Some(id),
            _ => None,
        }
    }

    async fn refill_by_next_tree(&mut self) -> Result<(), RPCError> {
        debug!(
            "Refill by next tree, key {:?}, ordering {:?}",
            self.tree_key, self.ordering
        );
        loop {
            if let Some((tree_key, tree)) = self
                .query_client
                .next_tree(&self.tree_key, self.ordering)
                .await
                .unwrap()
            {
                debug!(
                    "Next tree for {:?} returns {:?}, lower key {:?}, ordering {:?}",
                    self.tree_key, tree, tree_key, self.ordering
                );
                let tree_client =
                    locate_tree_server_from_conshash(&tree.id, &self.query_client.conshash).await?;
                let seek_key = match self.ordering {
                    Ordering::Forward => min_entry_key(),
                    Ordering::Backward => max_entry_key(),
                };
                let seek_res = tree_client
                    .seek(
                        tree.id,
                        seek_key,
                        self.ordering,
                        self.buffer_size,
                        tree.epoch,
                    )
                    .await?;
                match seek_res {
                    OpResult::Successful(block) => {
                        if block.buffer.is_empty() {
                            // Clear, this will ensure the cursor returns 0
                            debug!("Tree refill seek returns empty block");
                            self.ids.clear();
                        } else {
                            debug!(
                                "Tree refill seek returns block sized {}",
                                block.buffer.len()
                            );
                            *self = Self::new(
                                self.ordering,
                                block,
                                tree_key,
                                self.query_client.clone(),
                                self.buffer_size,
                            )
                            .await?;
                        }
                        return Ok(());
                    }
                    OpResult::Migrating => {
                        tokio::time::sleep(Duration::from_millis(500)).await;
                    }
                    OpResult::OutOfBound | OpResult::NotFound => unreachable!(),
                    OpResult::EpochMissMatch(expect, actual) => {
                        debug!(
                            "Epoch mismatch on refill, expected {}, actual {}",
                            expect, actual
                        );
                    }
                }
            } else {
                debug!(
                    "Next tree for {:?} does not return anything. ordering {:?}",
                    self.tree_key, self.ordering
                );
                return Ok(());
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::slice;

/// Slice from `vec[vec.len()..vec.capacity()]`
pub unsafe fn remaining_capacity_as_slice_mut<A>(vec: &mut Vec<A>) -> &mut [A] {
    slice::from_raw_parts_mut(
        vec.as_mut_slice().as_mut_ptr().offset(vec.len() as isize),
        vec.capacity() - vec.len(),
    )
}

pub unsafe fn remove_lifetime_mut<A: ?Sized>(a: &mut A) -> &'static mut A {
    mem::transmute(a)
}

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

    #[test]
    fn test_remaining_capacity_as_slice_mut() {
        let mut v = Vec::with_capacity(5);
        v.push(10);
        v.push(11);
        v.push(12);
        unsafe {
            {
                let s = remaining_capacity_as_slice_mut(&mut v);
                assert_eq!(2, s.len());
                s[0] = 13;
                s[1] = 14;
            }
            v.set_len(5);
        }
        assert_eq!(vec![10, 11, 12, 13, 14], v);
    }
}
<commit_msg>Simplify internal function a bit<commit_after>use std::mem;

/// Slice from `vec[vec.len()..vec.capacity()]`
pub unsafe fn remaining_capacity_as_slice_mut<A>(vec: &mut Vec<A>) -> &mut [A] {
    let range = vec.len()..vec.capacity();
    vec.get_unchecked_mut(range)
}

pub unsafe fn remove_lifetime_mut<A: ?Sized>(a: &mut A) -> &'static mut A {
    mem::transmute(a)
}

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

    #[test]
    fn test_remaining_capacity_as_slice_mut() {
        let mut v = Vec::with_capacity(5);
        v.push(10);
        v.push(11);
        v.push(12);
        unsafe {
            {
                let s = remaining_capacity_as_slice_mut(&mut v);
                assert_eq!(2, s.len());
                s[0] = 13;
                s[1] = 14;
            }
            v.set_len(5);
        }
        assert_eq!(vec![10, 11, 12, 13, 14], v);
    }
}
<|endoftext|>


<commit_before>
use meta_tools::*;
use quote::{ quote, ToTokens, TokenStreamExt };
use syn::parse::*;
use syn::spanned::Spanned;
use proc_macro_tools::*;
use std::collections::HashMap;
use iter_tools::{ /* Itertools, */ process_results };
use convert_case::{Case, Casing};

pub type Result< T > = std::result::Result< T, syn::Error >;

///
/// Descriptor of a function with a body, body of which is not parsed.
///

pub struct FnQuick
{
  pub attrs : Vec< syn::Attribute >,
  pub vis : syn::Visibility,
  pub sig : syn::Signature,
  pub block : Option< proc_macro2::TokenStream >,
}

impl quote::ToTokens for FnQuick
{
  fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
  {

    for attr in self.attrs.iter()
    {
      attr.to_tokens( tokens );
    }

    self.sig.to_tokens( tokens );

    match &self.block
    {
      Some( block ) => tokens.append( proc_macro2::Group::new( proc_macro2::Delimiter::Brace, block.to_token_stream() ) ),
      None => tokens.append( proc_macro2::Punct::new( ';', proc_macro2::Spacing::Alone ) ),
    }

  }
}

///
/// Descriptor of element of options.
///

pub enum Element
{
  Fn( FnQuick ),
  #[ allow( dead_code ) ]
  Signature( FnQuick ),
  Field( syn::Field ),
}

impl Parse for Element
{
  fn parse( input : ParseStream< '_ > ) -> Result< Self >
  {

    let attrs : Vec< syn::Attribute > = input.call( syn::Attribute::parse_outer )?;
    let vis : syn::Visibility = input.parse()?;

    let lookahead1 = input.lookahead1();
    if lookahead1.peek( syn::Token!{ fn } )
    {
      let sig : syn::Signature = input.parse()?;

      let lookahead2 = input.lookahead1();
      if lookahead2.peek( syn::token::Brace )
      {
        let input2;
        let _brace_token : syn::token::Brace = syn::braced!( input2 in input );
        let block : proc_macro2::TokenStream = input2.parse()?;
        let fn_desc = FnQuick
        {
          attrs,
          vis,
          sig,
          block : Some( block ),
        };
        return Ok( Element::Fn( fn_desc ) );
      }
      else
      {
        let fn_desc = FnQuick
        {
          attrs,
          vis,
          sig,
          block : None,
        };
        return Ok( Element::Fn( fn_desc ) );
      }
    }
    else
    {
      input.call( syn::Field::parse_named ).map( | mut e |
      {
        e.vis = vis;
        e.attrs = attrs;
        Element::Field( e )
      })
    }
  }
}

///
/// Descriptor of attribute options.
///

#[allow( dead_code )]
struct OptionsDescriptor
{
  attrs : Vec< syn::Attribute >,
  vis : syn::Visibility,
  ident : syn::Ident,
  generics: syn::Generics,
  brace_token : syn::token::Brace,
  methods_map : HashMap< String, FnQuick >,
  signatures_map : HashMap< String, FnQuick >,
  fields_map : HashMap< String, syn::Field >,
}

impl Parse for OptionsDescriptor
{
  fn parse( input : ParseStream< '_ > ) -> Result< Self >
  {
    let input2;
    let vis = input.parse()?;
    let ident = input.parse()?;
    let generics = input.parse()?;
    let brace_token = syn::braced!( input2 in input );
    let mut attrs = input2.call( syn::Attribute::parse_inner )?;
    let elements : syn::punctuated::Punctuated< Element, syn::Token!{ ; } > = input2.parse_terminated( Element::parse )?;
    let mut methods_map = hmap!{};
    let mut signatures_map = hmap!{};
    let mut fields_map = hmap!{};

    for attr in attrs.iter_mut()
    {
      attr.style = syn::AttrStyle::Outer;
    }

    for element in elements.into_iter()
    {
      match element
      {
        Element::Fn( f ) =>
        {
          methods_map.insert( f.sig.ident.to_string(), f );
        },
        Element::Signature( f ) =>
        {
          signatures_map.insert( f.sig.ident.to_string(), f );
        },
        Element::Field( f ) =>
        {
          let key = f.ident.as_ref().ok_or_else( || syn_err!( &f.clone(), "Field does not have name: {}", quote!{ #f } ) )?.to_string();
          fields_map.insert( key, f );
        },
      }
    }

    let result = OptionsDescriptor
    {
      vis,
      ident,
      generics,
      brace_token,
      attrs,
      methods_map,
      signatures_map,
      fields_map,
    };
    Ok( result )
  }
}

///
/// Getter descriptor.
///

#[ derive( Debug ) ]
pub struct AccessorDescriptor
{
  attr : proc_macro2::TokenStream,
  signature : proc_macro2::TokenStream,
  body : proc_macro2::TokenStream,
}

//

impl quote::ToTokens for AccessorDescriptor
{
  fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
  {
    self.attr.to_tokens( tokens );
    self.signature.to_tokens( tokens );
    self.body.to_tokens( tokens );
  }
}

///
/// Generate a getter for a field.
///

fn getter_gen( name : &str, field : &syn::Field ) -> Result< AccessorDescriptor >
{

  let name_ident = syn::Ident::new( &name, field.span() );
  let ty = &field.ty;

  // tree_print!( ty );

  let ty_is_ref = matches!( ty, syn::Type::Reference( _ ) );

  let ty2 = if ty_is_ref
  {
    ty.to_token_stream()
  }
  else
  {
    quote!{ & #ty }
  };

  let attr = quote!
  {
    #[ inline ]
  };

  let signature = quote!
  {
    fn #name_ident( &self ) -> #ty2
  };

  let body = quote!
  {
    {
      &self.#name_ident
    }
  };

  let result = AccessorDescriptor
  {
    attr,
    signature,
    body,
  };

  Ok( result )
}

///
/// Generate a mutter for a field.
///

fn mutter_gen( name : &str, field : &syn::Field ) -> Result< AccessorDescriptor >
{

  let name_ident = syn::Ident::new( &name, field.span() );
  let name_mut_ident = syn::Ident::new( &format!( "{}_mut", name ), field.span() );
  let ty = &field.ty;

  // tree_print!( ty );

  let ty2 = quote!{ &mut #ty };

  let attr = quote!
  {
    #[ inline ]
  };

  let signature = quote!
  {
    fn #name_mut_ident( &mut self ) -> #ty2
  };

  let body = quote!
  {
    {
      &mut self.#name_ident
    }
  };

  let result = AccessorDescriptor
  {
    attr,
    signature,
    body,
  };

  Ok( result )
}

///
///
///

fn perform_gen( options_descriptor : &OptionsDescriptor ) -> ( proc_macro2::TokenStream, proc_macro2::TokenStream )
{

  let mut perform = quote!{};
  let mut attr_perform = quote!{};
  if let Some( perform_fn ) = options_descriptor.methods_map.get( "perform" )
  {
    let sig = &perform_fn.sig;
    attr_perform = quote!{ #[ perform( #sig ) ] };
    perform = quote!
    {
      #[ allow( unused_attributes ) ]
      #[ inline ]
      #perform_fn
    }
  }

  ( perform, attr_perform )
}

///
/// Options macro handler.
///

pub fn options( _attr : proc_macro::TokenStream, item : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream >
{

  let options_descriptor = match syn::parse::< OptionsDescriptor >( item )
  {
    Ok( syntax_tree ) => syntax_tree,
    Err( err ) => return Err( err ),
  };

  let name_ident = &options_descriptor.ident;
  let name_options_adapter_str = String::from( name_ident.to_string() ).from_case( Case::Snake ).to_case( Case::UpperCamel );
  let name_options_adapter_str = format!( "{}OptionsAdapter", name_options_adapter_str );
  let name_options_adapter_ident = syn::Ident::new( &name_options_adapter_str, name_ident.span() );
  let generics = &options_descriptor.generics;
  let attrs = &options_descriptor.attrs;

  let mut fields_define = Vec::< &syn::Field >::new();
  for ( _name, field ) in options_descriptor.fields_map.iter()
  {
    fields_define.push( field );
  }

  let ( perform, attr_perform ) = perform_gen( &options_descriptor );

  let getters = options_descriptor.fields_map.iter().map( | ( key, field ) | getter_gen( key, field ) );
  let getters : Vec< _ > = process_results( getters, | iter | iter.collect() )?;
  let getters_signatures : Vec< _ > = getters.iter().map( | e | e.signature.clone() ).collect();

  let mutters = options_descriptor.fields_map.iter().map( | ( key, field ) | mutter_gen( key, field ) );
  let mutters : Vec< _ > = process_results( mutters, | iter | iter.collect() )?;
  let mutters_signatures : Vec< _ > = mutters.iter().map( | e | e.signature.clone() ).collect();

  let result = quote!
  {

    pub mod #name_ident
    {

      // #[cfg( feature = "in_wtools" )]
      // use ::wtools::options::*;
      // #[cfg( not( feature = "in_wtools" ) )]
      use super::Former;

      #( #attrs )*
      #[ derive( Former, PartialEq, Debug ) ]
      #attr_perform
      pub struct Options #generics
      {
        #( #fields_define, )*
      }

      pub trait OptionsAdapter #generics
      {
        #( #getters_signatures ; )*
        #( #mutters_signatures ; )*
        #perform
      }

      impl #generics OptionsAdapter #generics for Options #generics
      {
        #( #getters )*
        #( #mutters )*
      }

      #[ inline ]
      pub fn former #generics() -> OptionsFormer #generics
      {
        Options::#generics::former()
      }

      /// Namespace of the module to include with `use module::*`.
      pub mod prelude
      {
        pub use super::OptionsAdapter as #name_options_adapter_ident;
      }

    }

    #[ inline ]
    pub fn #name_ident #generics () -> #name_ident::OptionsFormer #generics
    {
      #name_ident::former::#generics()
    }

  };

  Ok( result )
}
<commit_msg>cleaning modules and publishing<commit_after>
use meta_tools::*;
use proc_macro_tools::quote::{ ToTokens, TokenStreamExt };
use proc_macro_tools::syn::parse::*;
use proc_macro_tools::syn::spanned::Spanned;
use proc_macro_tools::*;
use std::collections::HashMap;
use iter_tools::{ /* Itertools, */ process_results };
use convert_case::{Case, Casing};

pub type Result< T > = std::result::Result< T, syn::Error >;

///
/// Descriptor of a function with a body, body of which is not parsed.
///

pub struct FnQuick
{
  pub attrs : Vec< syn::Attribute >,
  pub vis : syn::Visibility,
  pub sig : syn::Signature,
  pub block : Option< proc_macro2::TokenStream >,
}

impl quote::ToTokens for FnQuick
{
  fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
  {

    for attr in self.attrs.iter()
    {
      attr.to_tokens( tokens );
    }

    self.sig.to_tokens( tokens );

    match &self.block
    {
      Some( block ) => tokens.append( proc_macro2::Group::new( proc_macro2::Delimiter::Brace, block.to_token_stream() ) ),
      None => tokens.append( proc_macro2::Punct::new( ';', proc_macro2::Spacing::Alone ) ),
    }

  }
}

///
/// Descriptor of element of options.
///

pub enum Element
{
  Fn( FnQuick ),
  #[ allow( dead_code ) ]
  Signature( FnQuick ),
  Field( syn::Field ),
}

impl Parse for Element
{
  fn parse( input : ParseStream< '_ > ) -> Result< Self >
  {

    let attrs : Vec< syn::Attribute > = input.call( syn::Attribute::parse_outer )?;
    let vis : syn::Visibility = input.parse()?;

    let lookahead1 = input.lookahead1();
    if lookahead1.peek( syn::Token!{ fn } )
    {
      let sig : syn::Signature = input.parse()?;

      let lookahead2 = input.lookahead1();
      if lookahead2.peek( syn::token::Brace )
      {
        let input2;
        let _brace_token : syn::token::Brace = syn::braced!( input2 in input );
        let block : proc_macro2::TokenStream = input2.parse()?;
        let fn_desc = FnQuick
        {
          attrs,
          vis,
          sig,
          block : Some( block ),
        };
        return Ok( Element::Fn( fn_desc ) );
      }
      else
      {
        let fn_desc = FnQuick
        {
          attrs,
          vis,
          sig,
          block : None,
        };
        return Ok( Element::Fn( fn_desc ) );
      }
    }
    else
    {
      input.call( syn::Field::parse_named ).map( | mut e |
      {
        e.vis = vis;
        e.attrs = attrs;
        Element::Field( e )
      })
    }
  }
}

///
/// Descriptor of attribute options.
///

#[allow( dead_code )]
struct OptionsDescriptor
{
  attrs : Vec< syn::Attribute >,
  vis : syn::Visibility,
  ident : syn::Ident,
  generics: syn::Generics,
  brace_token : syn::token::Brace,
  methods_map : HashMap< String, FnQuick >,
  signatures_map : HashMap< String, FnQuick >,
  fields_map : HashMap< String, syn::Field >,
}

impl Parse for OptionsDescriptor
{
  fn parse( input : ParseStream< '_ > ) -> Result< Self >
  {
    let input2;
    let vis = input.parse()?;
    let ident = input.parse()?;
    let generics = input.parse()?;
    let brace_token = syn::braced!( input2 in input );
    let mut attrs = input2.call( syn::Attribute::parse_inner )?;
    let elements : syn::punctuated::Punctuated< Element, syn::Token!{ ; } > = input2.parse_terminated( Element::parse )?;
    let mut methods_map = hmap!{};
    let mut signatures_map = hmap!{};
    let mut fields_map = hmap!{};

    for attr in attrs.iter_mut()
    {
      attr.style = syn::AttrStyle::Outer;
    }

    for element in elements.into_iter()
    {
      match element
      {
        Element::Fn( f ) =>
        {
          methods_map.insert( f.sig.ident.to_string(), f );
        },
        Element::Signature( f ) =>
        {
          signatures_map.insert( f.sig.ident.to_string(), f );
        },
        Element::Field( f ) =>
        {
          let key = f.ident.as_ref().ok_or_else( || syn_err!( &f.clone(), "Field does not have name: {}", qt!{ #f } ) )?.to_string();
          fields_map.insert( key, f );
        },
      }
    }

    let result = OptionsDescriptor
    {
      vis,
      ident,
      generics,
      brace_token,
      attrs,
      methods_map,
      signatures_map,
      fields_map,
    };
    Ok( result )
  }
}

///
/// Getter descriptor.
///

#[ derive( Debug ) ]
pub struct AccessorDescriptor
{
  attr : proc_macro2::TokenStream,
  signature : proc_macro2::TokenStream,
  body : proc_macro2::TokenStream,
}

//

impl quote::ToTokens for AccessorDescriptor
{
  fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
  {
    self.attr.to_tokens( tokens );
    self.signature.to_tokens( tokens );
    self.body.to_tokens( tokens );
  }
}

///
/// Generate a getter for a field.
///

fn getter_gen( name : &str, field : &syn::Field ) -> Result< AccessorDescriptor >
{

  let name_ident = syn::Ident::new( &name, field.span() );
  let ty = &field.ty;

  // tree_print!( ty );

  let ty_is_ref = matches!( ty, syn::Type::Reference( _ ) );

  let ty2 = if ty_is_ref
  {
    ty.to_token_stream()
  }
  else
  {
    qt!{ & #ty }
  };

  let attr = qt!
  {
    #[ inline ]
  };

  let signature = qt!
  {
    fn #name_ident( &self ) -> #ty2
  };

  let body = qt!
  {
    {
      &self.#name_ident
    }
  };

  let result = AccessorDescriptor
  {
    attr,
    signature,
    body,
  };

  Ok( result )
}

///
/// Generate a mutter for a field.
///

fn mutter_gen( name : &str, field : &syn::Field ) -> Result< AccessorDescriptor >
{

  let name_ident = syn::Ident::new( &name, field.span() );
  let name_mut_ident = syn::Ident::new( &format!( "{}_mut", name ), field.span() );
  let ty = &field.ty;

  // tree_print!( ty );

  let ty2 = qt!{ &mut #ty };

  let attr = qt!
  {
    #[ inline ]
  };

  let signature = qt!
  {
    fn #name_mut_ident( &mut self ) -> #ty2
  };

  let body = qt!
  {
    {
      &mut self.#name_ident
    }
  };

  let result = AccessorDescriptor
  {
    attr,
    signature,
    body,
  };

  Ok( result )
}

///
///
///

fn perform_gen( options_descriptor : &OptionsDescriptor ) -> ( proc_macro2::TokenStream, proc_macro2::TokenStream )
{

  let mut perform = qt!{};
  let mut attr_perform = qt!{};
  if let Some( perform_fn ) = options_descriptor.methods_map.get( "perform" )
  {
    let sig = &perform_fn.sig;
    attr_perform = qt!{ #[ perform( #sig ) ] };
    perform = qt!
    {
      #[ allow( unused_attributes ) ]
      #[ inline ]
      #perform_fn
    }
  }

  ( perform, attr_perform )
}

///
/// Options macro handler.
///

pub fn options( _attr : proc_macro::TokenStream, item : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream >
{

  let options_descriptor = match syn::parse::< OptionsDescriptor >( item )
  {
    Ok( syntax_tree ) => syntax_tree,
    Err( err ) => return Err( err ),
  };

  let name_ident = &options_descriptor.ident;
  let name_options_adapter_str = String::from( name_ident.to_string() ).from_case( Case::Snake ).to_case( Case::UpperCamel );
  let name_options_adapter_str = format!( "{}OptionsAdapter", name_options_adapter_str );
  let name_options_adapter_ident = syn::Ident::new( &name_options_adapter_str, name_ident.span() );
  let generics = &options_descriptor.generics;
  let attrs = &options_descriptor.attrs;

  let mut fields_define = Vec::< &syn::Field >::new();
  for ( _name, field ) in options_descriptor.fields_map.iter()
  {
    fields_define.push( field );
  }

  let ( perform, attr_perform ) = perform_gen( &options_descriptor );

  let getters = options_descriptor.fields_map.iter().map( | ( key, field ) | getter_gen( key, field ) );
  let getters : Vec< _ > = process_results( getters, | iter | iter.collect() )?;
  let getters_signatures : Vec< _ > = getters.iter().map( | e | e.signature.clone() ).collect();

  let mutters = options_descriptor.fields_map.iter().map( | ( key, field ) | mutter_gen( key, field ) );
  let mutters : Vec< _ > = process_results( mutters, | iter | iter.collect() )?;
  let mutters_signatures : Vec< _ > = mutters.iter().map( | e | e.signature.clone() ).collect();

  let result = qt!
  {

    pub mod #name_ident
    {

      // #[cfg( feature = "in_wtools" )]
      // use ::wtools::options::*;
      // #[cfg( not( feature = "in_wtools" ) )]
      use super::Former;

      #( #attrs )*
      #[ derive( Former, PartialEq, Debug ) ]
      #attr_perform
      pub struct Options #generics
      {
        #( #fields_define, )*
      }

      pub trait OptionsAdapter #generics
      {
        #( #getters_signatures ; )*
        #( #mutters_signatures ; )*
        #perform
      }

      impl #generics OptionsAdapter #generics for Options #generics
      {
        #( #getters )*
        #( #mutters )*
      }

      #[ inline ]
      pub fn former #generics() -> OptionsFormer #generics
      {
        Options::#generics::former()
      }

      /// Namespace of the module to include with `use module::*`.
      pub mod prelude
      {
        pub use super::OptionsAdapter as #name_options_adapter_ident;
      }

    }

    #[ inline ]
    pub fn #name_ident #generics () -> #name_ident::OptionsFormer #generics
    {
      #name_ident::former::#generics()
    }

  };

  Ok( result )
}
<|endoftext|>


<commit_before>use crate::QCoreApplication;
use cpp_utils::CppBox;
use std::os::raw::{c_char, c_int};
use std::process;

/// A struct providing valid `argc` and `argv` values for Qt application
/// objects.
///
/// Constructors of `qt_core::core_application::CoreApplication`,
/// `qt_gui::gui_application::GuiApplication` and `qt_widgets::application::Application`
/// require `argc` and `argv` values that are available in C++'s `main` function but
/// not available in Rust. More importantly, `argc` and `argv` must be valid for the entire
/// life of the application. This struct stores list of arguments in a format compatible with
/// `argc` and `argv`, and can be used to initialize Qt application objects.
/// `CoreApplicationArgs` must live longer than the application object.
///
/// `CoreApplication::create_and_exit` convenience function
/// and similar functions in the other application types
/// can be used instead of `CoreApplicationArgs`.
struct QCoreApplicationArgs {
    _values: Vec<Vec<u8>>,
    argc: Box<c_int>,
    argv: Vec<*mut c_char>,
}

impl QCoreApplicationArgs {
    /// Creates an object containing `args`.
    fn new(mut args: Vec<Vec<u8>>) -> QCoreApplicationArgs {
        for arg in &mut args {
            if !arg.ends_with(&[0]) {
                arg.push(0);
            }
        }
        QCoreApplicationArgs {
            argc: Box::new(args.len() as c_int),
            argv: args
                .iter_mut()
                .map(|x| x.as_mut_ptr() as *mut c_char)
                .collect(),
            _values: args,
        }
    }

    /// Returns `(argc, argv)` values in the form accepted by the application objects'
    /// constructors.
    fn get(&mut self) -> (*mut c_int, *mut *mut c_char) {
        let argc = self.argc.as_mut();
        let argv = self.argv.as_mut_ptr();
        (argc, argv)
    }

    #[cfg(unix)]
    /// Creates an object representing real arguments of the application.
    /// On Windows, this function uses empty argument list for performance reasons because
    /// Qt doesn't use `argc` and `argv` on Windows at all.
    fn from_real() -> QCoreApplicationArgs {
        use std::os::unix::ffi::OsStringExt;

        let args = std::env::args_os().map(|arg| arg.into_vec()).collect();
        QCoreApplicationArgs::new(args)
    }
    #[cfg(windows)]
    /// Creates an object representing real arguments of the application.
    /// On Windows, this function uses empty argument list for performance reasons because
    /// Qt doesn't use `argc` and `argv` on Windows at all.
    fn from_real() -> QCoreApplicationArgs {
        // Qt doesn't use argc and argv on Windows anyway
        // TODO: check this
        QCoreApplicationArgs::empty()
    }
}

impl QCoreApplication {
    pub fn new() -> CppBox<Self> {
        let mut args = QCoreApplicationArgs::from_real();
        let (argc, argv) = args.get();
        unsafe {
            QCoreApplication::new_2a(
                ::cpp_utils::Ref::from_raw(argc).unwrap(),
                ::cpp_utils::Ptr::from_raw(argv),
            )
        }
    }

    /// A convenience function for performing proper initialization and de-initialization of
    /// a Qt application.
    ///
    /// This function creates `CoreApplication` with valid `argc` and `argv`, calls the passed
    /// closure `f(app)` with the application object and exist the process with the exit code
    /// returned by the closure. The closure should perform the initialization of the application
    /// and either return immediately or call `CoreApplication::exec()` and return its return value:
    /// ```no_run
    /// use moqt_core::QCoreApplication;
    ///
    /// fn main() {
    ///     QCoreApplication::create_and_exit(|app| {
    ///         unsafe {
    ///             // initialization goes here
    ///             QCoreApplication::exec()
    ///         }
    ///     })
    /// }
    /// ```
    pub fn create_and_exit<F: FnOnce(::cpp_utils::Ptr<QCoreApplication>) -> i32>(f: F) -> ! {
        let exit_code = {
            unsafe {
                let mut app = QCoreApplication::new();
                f(app.as_mut_ptr())
            }
        }; // drop `app` and `args`
        process::exit(exit_code)
    }
}
<commit_msg>fix windows build<commit_after>use crate::QCoreApplication;
use cpp_utils::CppBox;
use std::os::raw::{c_char, c_int};
use std::process;

/// A struct providing valid `argc` and `argv` values for Qt application
/// objects.
///
/// Constructors of `qt_core::core_application::CoreApplication`,
/// `qt_gui::gui_application::GuiApplication` and `qt_widgets::application::Application`
/// require `argc` and `argv` values that are available in C++'s `main` function but
/// not available in Rust. More importantly, `argc` and `argv` must be valid for the entire
/// life of the application. This struct stores list of arguments in a format compatible with
/// `argc` and `argv`, and can be used to initialize Qt application objects.
/// `CoreApplicationArgs` must live longer than the application object.
///
/// `CoreApplication::create_and_exit` convenience function
/// and similar functions in the other application types
/// can be used instead of `CoreApplicationArgs`.
struct QCoreApplicationArgs {
    _values: Vec<Vec<u8>>,
    argc: Box<c_int>,
    argv: Vec<*mut c_char>,
}

impl QCoreApplicationArgs {
    /// Creates an object containing `args`.
    fn new(mut args: Vec<Vec<u8>>) -> QCoreApplicationArgs {
        for arg in &mut args {
            if !arg.ends_with(&[0]) {
                arg.push(0);
            }
        }
        QCoreApplicationArgs {
            argc: Box::new(args.len() as c_int),
            argv: args
                .iter_mut()
                .map(|x| x.as_mut_ptr() as *mut c_char)
                .collect(),
            _values: args,
        }
    }

    /// Returns `(argc, argv)` values in the form accepted by the application objects'
    /// constructors.
    fn get(&mut self) -> (*mut c_int, *mut *mut c_char) {
        let argc = self.argc.as_mut();
        let argv = self.argv.as_mut_ptr();
        (argc, argv)
    }

    #[cfg(unix)]
    /// Creates an object representing real arguments of the application.
    /// On Windows, this function uses empty argument list for performance reasons because
    /// Qt doesn't use `argc` and `argv` on Windows at all.
    fn from_real() -> QCoreApplicationArgs {
        use std::os::unix::ffi::OsStringExt;

        let args = std::env::args_os().map(|arg| arg.into_vec()).collect();
        QCoreApplicationArgs::new(args)
    }
    #[cfg(windows)]
    /// Creates an object representing real arguments of the application.
    /// On Windows, this function uses empty argument list for performance reasons because
    /// Qt doesn't use `argc` and `argv` on Windows at all.
    fn from_real() -> QCoreApplicationArgs {
        // Qt doesn't use argc and argv on Windows anyway
        // TODO: check this
        QCoreApplicationArgs::new(Vec::new())
    }
}

impl QCoreApplication {
    pub fn new() -> CppBox<Self> {
        let mut args = QCoreApplicationArgs::from_real();
        let (argc, argv) = args.get();
        unsafe {
            QCoreApplication::new_2a(
                ::cpp_utils::Ref::from_raw(argc).unwrap(),
                ::cpp_utils::Ptr::from_raw(argv),
            )
        }
    }

    /// A convenience function for performing proper initialization and de-initialization of
    /// a Qt application.
    ///
    /// This function creates `CoreApplication` with valid `argc` and `argv`, calls the passed
    /// closure `f(app)` with the application object and exist the process with the exit code
    /// returned by the closure. The closure should perform the initialization of the application
    /// and either return immediately or call `CoreApplication::exec()` and return its return value:
    /// ```no_run
    /// use moqt_core::QCoreApplication;
    ///
    /// fn main() {
    ///     QCoreApplication::create_and_exit(|app| {
    ///         unsafe {
    ///             // initialization goes here
    ///             QCoreApplication::exec()
    ///         }
    ///     })
    /// }
    /// ```
    pub fn create_and_exit<F: FnOnce(::cpp_utils::Ptr<QCoreApplication>) -> i32>(f: F) -> ! {
        let exit_code = {
            unsafe {
                let mut app = QCoreApplication::new();
                f(app.as_mut_ptr())
            }
        }; // drop `app` and `args`
        process::exit(exit_code)
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLFormElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLFormElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::{HTMLCollection, Static};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLFormElement {
    pub htmlelement: HTMLElement
}

impl HTMLFormElementDerived for EventTarget {
    fn is_htmlformelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLFormElementTypeId))
    }
}

impl HTMLFormElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFormElement {
        HTMLFormElement {
            htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFormElement> {
        let element = HTMLFormElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLFormElementBinding::Wrap)
    }
}

pub trait HTMLFormElementMethods {
    fn AcceptCharset(&self) -> DOMString;
    fn SetAcceptCharset(&mut self, _accept_charset: DOMString) -> ErrorResult;
    fn Action(&self) -> DOMString;
    fn SetAction(&mut self, _action: DOMString) -> ErrorResult;
    fn Autocomplete(&self) -> DOMString;
    fn SetAutocomplete(&mut self, _autocomplete: DOMString) -> ErrorResult;
    fn Enctype(&self) -> DOMString;
    fn SetEnctype(&mut self, _enctype: DOMString) -> ErrorResult;
    fn Encoding(&self) -> DOMString;
    fn SetEncoding(&mut self, _encoding: DOMString) -> ErrorResult;
    fn Method(&self) -> DOMString;
    fn SetMethod(&mut self, _method: DOMString) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&mut self, _name: DOMString) -> ErrorResult;
    fn NoValidate(&self) -> bool;
    fn SetNoValidate(&mut self, _no_validate: bool) -> ErrorResult;
    fn Target(&self) -> DOMString;
    fn SetTarget(&mut self, _target: DOMString) -> ErrorResult;
    fn Elements(&self) -> Temporary<HTMLCollection>;
    fn Length(&self) -> i32;
    fn Submit(&self) -> ErrorResult;
    fn Reset(&self);
    fn CheckValidity(&self) -> bool;
    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Temporary<Element>;
}

impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> {
    fn AcceptCharset(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAcceptCharset(&mut self, _accept_charset: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Action(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAction(&mut self, _action: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Autocomplete(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAutocomplete(&mut self, _autocomplete: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Enctype(&self) -> DOMString {
        "".to_owned()
    }

    fn SetEnctype(&mut self, _enctype: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Encoding(&self) -> DOMString {
        "".to_owned()
    }

    fn SetEncoding(&mut self, _encoding: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Method(&self) -> DOMString {
        "".to_owned()
    }

    fn SetMethod(&mut self, _method: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&mut self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn NoValidate(&self) -> bool {
        false
    }

    fn SetNoValidate(&mut self, _no_validate: bool) -> ErrorResult {
        Ok(())
    }

    fn Target(&self) -> DOMString {
        "".to_owned()
    }

    fn SetTarget(&mut self, _target: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Elements(&self) -> Temporary<HTMLCollection> {
        // FIXME: https://github.com/mozilla/servo/issues/1844
        let window = window_from_node(self).root();
        HTMLCollection::new(&*window, Static(vec!()))
    }

    fn Length(&self) -> i32 {
        0
    }

    fn Submit(&self) -> ErrorResult {
        Ok(())
    }

    fn Reset(&self) {
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Temporary<Element> {
        fail!("Not implemented.")
    }
}
<commit_msg>Remove needless '&mut self' from HTMLFormElementMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLFormElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLFormElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLFormElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlcollection::{HTMLCollection, Static};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLFormElement {
    pub htmlelement: HTMLElement
}

impl HTMLFormElementDerived for EventTarget {
    fn is_htmlformelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLFormElementTypeId))
    }
}

impl HTMLFormElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLFormElement {
        HTMLFormElement {
            htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLFormElement> {
        let element = HTMLFormElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLFormElementBinding::Wrap)
    }
}

pub trait HTMLFormElementMethods {
    fn AcceptCharset(&self) -> DOMString;
    fn SetAcceptCharset(&self, _accept_charset: DOMString) -> ErrorResult;
    fn Action(&self) -> DOMString;
    fn SetAction(&self, _action: DOMString) -> ErrorResult;
    fn Autocomplete(&self) -> DOMString;
    fn SetAutocomplete(&self, _autocomplete: DOMString) -> ErrorResult;
    fn Enctype(&self) -> DOMString;
    fn SetEnctype(&self, _enctype: DOMString) -> ErrorResult;
    fn Encoding(&self) -> DOMString;
    fn SetEncoding(&self, _encoding: DOMString) -> ErrorResult;
    fn Method(&self) -> DOMString;
    fn SetMethod(&self, _method: DOMString) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&self, _name: DOMString) -> ErrorResult;
    fn NoValidate(&self) -> bool;
    fn SetNoValidate(&self, _no_validate: bool) -> ErrorResult;
    fn Target(&self) -> DOMString;
    fn SetTarget(&self, _target: DOMString) -> ErrorResult;
    fn Elements(&self) -> Temporary<HTMLCollection>;
    fn Length(&self) -> i32;
    fn Submit(&self) -> ErrorResult;
    fn Reset(&self);
    fn CheckValidity(&self) -> bool;
    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Temporary<Element>;
}

impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> {
    fn AcceptCharset(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAcceptCharset(&self, _accept_charset: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Action(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAction(&self, _action: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Autocomplete(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAutocomplete(&self, _autocomplete: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Enctype(&self) -> DOMString {
        "".to_owned()
    }

    fn SetEnctype(&self, _enctype: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Encoding(&self) -> DOMString {
        "".to_owned()
    }

    fn SetEncoding(&self, _encoding: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Method(&self) -> DOMString {
        "".to_owned()
    }

    fn SetMethod(&self, _method: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn NoValidate(&self) -> bool {
        false
    }

    fn SetNoValidate(&self, _no_validate: bool) -> ErrorResult {
        Ok(())
    }

    fn Target(&self) -> DOMString {
        "".to_owned()
    }

    fn SetTarget(&self, _target: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Elements(&self) -> Temporary<HTMLCollection> {
        // FIXME: https://github.com/mozilla/servo/issues/1844
        let window = window_from_node(self).root();
        HTMLCollection::new(&*window, Static(vec!()))
    }

    fn Length(&self) -> i32 {
        0
    }

    fn Submit(&self) -> ErrorResult {
        Ok(())
    }

    fn Reset(&self) {
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Temporary<Element> {
        fail!("Not implemented.")
    }
}
<|endoftext|>