<commit_before>
//! A serialization framework supporting the following features:
//!
//! - Arbitrary types can implement the `Encodable` and `Decodable` traits
//!   to support serialization
//! - Serialization can be "context-aware", that is, `Encodables` and
//!   `Decodables` can specify what kind of context they need to be serialized
//!   or deserialized. For example, certain values may always need to be
//!   interned at runtime. Such a value would implement `Decodable` with a
//!   context from which the needed interner is reachable.
//! - The framework supports "objects", that is, types can implement the
//!   `EncodableObject` and `DecodableObject` traits, which will make their
//!   actual data only be emitted once within some encoded dataset. Other
//!   `Encodables` only store a reference to where the objects data is located.
//! - `Encodables` do not need to know there encoded size beforehand and can
//!   indeed be of variable size. This allows for space-efficient encodings
//!   like using the LEB128 format for integers.
//! - Encoding and decoding generally does not need to do dynamic memory
//!   allocation.
//! - The API is designed in a way that should allow for easily auto-generating
//!   serialization and deserialization code.
//! - Completely safe implementation (no `unsafe` used).

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Vacant, Occupied};

//=-----------------------------------------------------------------------------
// ENCODING
//=-----------------------------------------------------------------------------

#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Address(u64);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectTableIndex(u32);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectUid(u64);

/// Something that can be encoded given a certain context ECX.
pub trait Encodable<ECX> {
    fn encode<'ecx, 'encodable>(&'encodable self,
                                session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

/// Values implementing this trait will only be emitted once during an
/// EncodingSession. Other values referencing them only store an address where
/// actual object can be found within the encoded data.
pub trait EncodableObject<ECX> : Encodable<ECX> {
    fn object_uid(&self) -> ObjectUid;

    fn encode_contents<'encodable, 'ecx>(&'encodable self,
                                         session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

pub trait Encoder {
    fn position(&self) -> Address;
    fn finalize(self: Box<Self>, four_cc: [u8; 4], object_table_address: Address);

    fn emit_u32(&mut self, value: u32);
    fn emit_u64(&mut self, value: u64);
    // TODO: Add emit_* methods of other primitive and composite types
}

pub struct EncodingContext<'ctx, ECX: 'ctx> {
    encoder: &'ctx mut Encoder,
    object_table_indices: &'ctx mut HashMap<ObjectUid, ObjectTableIndex>,
    object_table: &'ctx mut Vec<Address>,
    delayed_writes: &'ctx mut Vec<(&'ctx EncodableObject<ECX>, ObjectTableIndex)>,
    pub extra: &'ctx mut ECX
}

impl<'sess, ECX: 'sess> EncodingContext<'sess, ECX> {

    pub fn encoder(&mut self) -> &mut Encoder {
        &mut *self.encoder
    }

    pub fn encode_object<'object, O>(&mut self, object: &'object O)
        where O: EncodableObject<ECX>,
              'object: 'sess
    {
        let object_uid = EncodableObject::object_uid(object);
        let (object_table_index, is_new) = self.get_object_table_index(object_uid);

        self.encoder().emit_u32(object_table_index.0);

        if is_new {
            self.enqueue_object_encoding(object_table_index,
                                         object as &'sess EncodableObject<ECX>);
        }
    }

    fn get_object_table_index(&mut self, object_uid: ObjectUid) -> (ObjectTableIndex, bool) {
        match self.object_table_indices.entry(object_uid) {
            Occupied(occupied) => (*occupied.get(), false),
            Vacant(vacant) => {
                // TODO: make this a safe conversion
                let index = ObjectTableIndex(self.object_table.len() as u32);
                vacant.insert(index);
                self.object_table.push(Address(u64::max_value()));
                (index, true)
            }
        }
    }

    fn write_enqueued_objects(&mut self) {
        loop {
            // encoding objects might add more to this queue, so we can't do
            // this in a for loop
            let item = self.delayed_writes.pop();

            match item {
                Some((object, object_table_index)) => {
                    let position = self.encoder.position();
                    object.encode_contents(self);
                    // Now that we know the address, write it to the table
                    self.object_table[object_table_index.0 as usize] = position;
                },
                None => break,
            }
        }
    }

    fn enqueue_object_encoding(&mut self,
                               object_table_index: ObjectTableIndex,
                               encodable: &'sess EncodableObject<ECX>) {
        self.delayed_writes.push((encodable, object_table_index));
    }
}

pub struct EncodingSession<ECX> {
    encoder: Box<Encoder>,
    object_table_indices: HashMap<ObjectUid, ObjectTableIndex>,
    object_table: Vec<Address>,
    pub context: ECX
}

impl<ECX> EncodingSession<ECX> {

    pub fn new<E: Encoder+'static>(encoder: E, ecx: ECX) -> EncodingSession<ECX> {
        EncodingSession {
            encoder: Box::new(encoder),
            object_table_indices: HashMap::new(),
            object_table: Vec::new(),
            context: ecx
        }
    }

    pub fn encode<T: Encodable<ECX>>(&mut self, encodable: &T) -> Address {
        let mut delayed_writes = Vec::new();

        let address = self.encoder.position();

        let mut context = EncodingContext {
            encoder: &mut *self.encoder,
            object_table_indices: &mut self.object_table_indices,
            object_table: &mut self.object_table,
            delayed_writes: &mut delayed_writes,
            extra: &mut self.context,
        };

        encodable.encode(&mut context);
        context.write_enqueued_objects();

        address
    }

    pub fn finalize(mut self, four_cc: [u8; 4]) {
        let object_table_address = self.encoder.position();

        for object_table_entry in self.object_table {
            self.encoder.emit_u64(object_table_entry.0);
        }

        self.encoder.finalize(four_cc, object_table_address);
    }
}

//=-----------------------------------------------------------------------------
// DECODING
//=-----------------------------------------------------------------------------
// TODO: The decoding API is still in flux.

pub trait Decodable<DCX> {
    fn decode(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait DecodableObject<DCX> : Decodable<DCX> {
    fn decode_contents(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait Decoder {
    fn set_position(&mut self, position: Address);
    fn position(&self) -> Address;
    fn read_u32(&mut self) -> u32;
    fn read_u64(&mut self) -> u64;
}

pub struct DecodingContext<'ctx, DCX> {
    decoder: &'ctx mut Decoder,
    object_table: Vec<Address>,
    pub extra: DCX,
}

impl<'ctx, DCX> DecodingContext<'ctx, DCX> {

    pub fn decoder(&mut self) -> &mut Decoder {
        self.decoder
    }

    pub fn decode_object<T:DecodableObject<DCX>>(&mut self) -> T {
        let object_table_index = self.decoder.read_u32();

        let address = self.object_table[object_table_index as usize];

        let current_position = self.decoder.position();
        self.decoder.set_position(address);

        let object = DecodableObject::decode_contents(self);

        self.decoder.set_position(current_position);

        object
    }
}

pub struct DecodingSession<'ctx, DCX> {
    context: DecodingContext<'ctx, DCX>
}

impl<'ctx, DCX> DecodingSession<'ctx, DCX> {

    pub fn decode<T: Decodable<DCX>>(&mut self) -> T {
        Decodable::decode(&mut self.context)
    }
}

//=-----------------------------------------------------------------------------
// TEST
//=-----------------------------------------------------------------------------

struct Ast {
    id: u64
}

impl<ECX> Encodable<ECX> for u64 {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        ecx.encoder().emit_u64(*self)
    }
}

impl<DCX> Decodable<DCX> for u64 {
    fn decode(context: &mut DecodingContext<DCX>) -> u64 {
        context.decoder().read_u64()
    }
}

impl<ECX> Encodable<ECX> for Ast {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        Encodable::encode(&self.id, ecx)
    }
}

impl<DCX> Decodable<DCX> for Ast {
    fn decode(context: &mut DecodingContext<DCX>) -> Ast {
        Ast { id: Decodable::decode(context) }
    }
}

impl<T: Encodable<ECX>, ECX> Encodable<ECX> for Option<T> {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        match *self {
            None => {
                ecx.encoder().emit_u32(0)
            }
            Some(ref value) => {
                ecx.encoder.emit_u32(1);
                Encodable::encode(value, ecx)
            }
        }
    }
}

impl<T: Decodable<DCX>, DCX> Decodable<DCX> for Option<T> {
    fn decode(context: &mut DecodingContext<DCX>) -> Option<T> {
        let disr = context.decoder().read_u32();
        if disr == 0 {
            None
        }
        else {
            Some(Decodable::decode(context))
        }
    }
}

struct Ty<'tcx> {
    id: u64,
    ast: Ast,
    sub_ty: Option<&'tcx Ty<'tcx>>
}

trait TyRestoreContext<'tcx> {
    fn create_interned(&self, id: u64, ast: Ast, sub_ty: Option<&'tcx Ty<'tcx>>) -> &'tcx Ty<'tcx>;
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for &'tcx Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> &'tcx Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        context.extra.create_interned(id, ast, sub_ty)
    }
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        Ty {
            id: id,
            ast: ast,
            sub_ty: sub_ty
        }
    }
}
<commit_msg>Add export table stub<commit_after>
//! A serialization framework supporting the following features:
//!
//! - Arbitrary types can implement the `Encodable` and `Decodable` traits
//!   to support serialization
//! - Serialization can be "context-aware", that is, `Encodables` and
//!   `Decodables` can specify what kind of context they need to be serialized
//!   or deserialized. For example, certain values may always need to be
//!   interned at runtime. Such a value would implement `Decodable` with a
//!   context from which the needed interner is reachable.
//! - The framework supports "objects", that is, types can implement the
//!   `EncodableObject` and `DecodableObject` traits, which will make their
//!   actual data only be emitted once within some encoded dataset. Other
//!   `Encodables` only store a reference to where the objects data is located.
//! - `Encodables` do not need to know there encoded size beforehand and can
//!   indeed be of variable size. This allows for space-efficient encodings
//!   like using the LEB128 format for integers.
//! - Encoding and decoding generally does not need to do dynamic memory
//!   allocation.
//! - The API is designed in a way that should allow for easily auto-generating
//!   serialization and deserialization code.
//! - Completely safe implementation (no `unsafe` used).

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Vacant, Occupied};

//=-----------------------------------------------------------------------------
// ENCODING
//=-----------------------------------------------------------------------------

#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Address(u64);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectTableIndex(u32);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct ObjectUid(u64);

/// Something that can be encoded given a certain context ECX.
pub trait Encodable<ECX> {
    fn encode<'ecx, 'encodable>(&'encodable self,
                                session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

/// Values implementing this trait will only be emitted once during an
/// EncodingSession. Other values referencing them only store an address where
/// actual object can be found within the encoded data.
pub trait EncodableObject<ECX> : Encodable<ECX> {
    fn object_uid(&self) -> ObjectUid;

    fn encode_contents<'encodable, 'ecx>(&'encodable self,
                                         session: &mut EncodingContext<'ecx, ECX>)
        where 'encodable: 'ecx;
}

pub trait Encoder {
    fn position(&self) -> Address;
    fn finalize(self: Box<Self>, four_cc: [u8; 4], object_table_address: Address);

    fn emit_u32(&mut self, value: u32);
    fn emit_u64(&mut self, value: u64);
    // TODO: Add emit_* methods of other primitive and composite types
}

pub struct EncodingContext<'ctx, ECX: 'ctx> {
    encoder: &'ctx mut Encoder,
    object_table_indices: &'ctx mut HashMap<ObjectUid, ObjectTableIndex>,
    object_table: &'ctx mut Vec<Address>,
    delayed_writes: &'ctx mut Vec<(&'ctx EncodableObject<ECX>, ObjectTableIndex)>,
    pub extra: &'ctx mut ECX
}

impl<'sess, ECX: 'sess> EncodingContext<'sess, ECX> {

    pub fn encoder(&mut self) -> &mut Encoder {
        &mut *self.encoder
    }

    pub fn encode_object<'object, O>(&mut self, object: &'object O)
        where O: EncodableObject<ECX>,
              'object: 'sess
    {
        let object_uid = EncodableObject::object_uid(object);
        let (object_table_index, is_new) = self.get_object_table_index(object_uid);

        self.encoder().emit_u32(object_table_index.0);

        if is_new {
            self.enqueue_object_encoding(object_table_index,
                                         object as &'sess EncodableObject<ECX>);
        }
    }

    fn get_object_table_index(&mut self, object_uid: ObjectUid) -> (ObjectTableIndex, bool) {
        match self.object_table_indices.entry(object_uid) {
            Occupied(occupied) => (*occupied.get(), false),
            Vacant(vacant) => {
                // TODO: make this a safe conversion
                let index = ObjectTableIndex(self.object_table.len() as u32);
                vacant.insert(index);
                self.object_table.push(Address(u64::max_value()));
                (index, true)
            }
        }
    }

    fn write_enqueued_objects(&mut self) {
        loop {
            // encoding objects might add more to this queue, so we can't do
            // this in a for loop
            let item = self.delayed_writes.pop();

            match item {
                Some((object, object_table_index)) => {
                    let position = self.encoder.position();
                    object.encode_contents(self);
                    // Now that we know the address, write it to the table
                    self.object_table[object_table_index.0 as usize] = position;
                },
                None => break,
            }
        }
    }

    fn enqueue_object_encoding(&mut self,
                               object_table_index: ObjectTableIndex,
                               encodable: &'sess EncodableObject<ECX>) {
        self.delayed_writes.push((encodable, object_table_index));
    }
}

pub struct EncodingSession<ECX> {
    encoder: Box<Encoder>,
    object_table_indices: HashMap<ObjectUid, ObjectTableIndex>,
    object_table: Vec<Address>,
    pub context: ECX
}

impl<ECX> EncodingSession<ECX> {

    pub fn new<E: Encoder+'static>(encoder: E, ecx: ECX) -> EncodingSession<ECX> {
        EncodingSession {
            encoder: Box::new(encoder),
            object_table_indices: HashMap::new(),
            object_table: Vec::new(),
            context: ecx
        }
    }

    pub fn encode<T: Encodable<ECX>>(&mut self, encodable: &T) -> Address {
        let mut delayed_writes = Vec::new();

        let address = self.encoder.position();

        let mut context = EncodingContext {
            encoder: &mut *self.encoder,
            object_table_indices: &mut self.object_table_indices,
            object_table: &mut self.object_table,
            delayed_writes: &mut delayed_writes,
            extra: &mut self.context,
        };

        encodable.encode(&mut context);
        context.write_enqueued_objects();

        address
    }

    pub fn add_to_export_table(name: &[u8], address: Address) {
        // TODO
    }

    pub fn finalize(mut self, four_cc: [u8; 4]) {
        let object_table_address = self.encoder.position();

        for object_table_entry in self.object_table {
            self.encoder.emit_u64(object_table_entry.0);
        }

        // TODO: emit export table

        self.encoder.finalize(four_cc, object_table_address);
    }
}

//=-----------------------------------------------------------------------------
// DECODING
//=-----------------------------------------------------------------------------
// TODO: The decoding API is still in flux.

pub trait Decodable<DCX> {
    fn decode(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait DecodableObject<DCX> : Decodable<DCX> {
    fn decode_contents(context: &mut DecodingContext<DCX>) -> Self;
}

pub trait Decoder {
    fn set_position(&mut self, position: Address);
    fn position(&self) -> Address;
    fn read_u32(&mut self) -> u32;
    fn read_u64(&mut self) -> u64;
}

pub struct DecodingContext<'ctx, DCX> {
    decoder: &'ctx mut Decoder,
    object_table: Vec<Address>,
    pub extra: DCX,
}

impl<'ctx, DCX> DecodingContext<'ctx, DCX> {

    pub fn decoder(&mut self) -> &mut Decoder {
        self.decoder
    }

    pub fn decode_object<T:DecodableObject<DCX>>(&mut self) -> T {
        let object_table_index = self.decoder.read_u32();

        let address = self.object_table[object_table_index as usize];

        let current_position = self.decoder.position();
        self.decoder.set_position(address);

        let object = DecodableObject::decode_contents(self);

        self.decoder.set_position(current_position);

        object
    }
}

pub struct DecodingSession<'ctx, DCX> {
    context: DecodingContext<'ctx, DCX>
}

impl<'ctx, DCX> DecodingSession<'ctx, DCX> {

    pub fn decode<T: Decodable<DCX>>(&mut self) -> T {
        Decodable::decode(&mut self.context)
    }
}

//=-----------------------------------------------------------------------------
// TEST
//=-----------------------------------------------------------------------------

struct Ast {
    id: u64
}

impl<ECX> Encodable<ECX> for u64 {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        ecx.encoder().emit_u64(*self)
    }
}

impl<DCX> Decodable<DCX> for u64 {
    fn decode(context: &mut DecodingContext<DCX>) -> u64 {
        context.decoder().read_u64()
    }
}

impl<ECX> Encodable<ECX> for Ast {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        Encodable::encode(&self.id, ecx)
    }
}

impl<DCX> Decodable<DCX> for Ast {
    fn decode(context: &mut DecodingContext<DCX>) -> Ast {
        Ast { id: Decodable::decode(context) }
    }
}

impl<T: Encodable<ECX>, ECX> Encodable<ECX> for Option<T> {
    fn encode<'ecx, 'a: 'ecx>(&'a self, ecx: &mut EncodingContext<'ecx, ECX>) {
        match *self {
            None => {
                ecx.encoder().emit_u32(0)
            }
            Some(ref value) => {
                ecx.encoder.emit_u32(1);
                Encodable::encode(value, ecx)
            }
        }
    }
}

impl<T: Decodable<DCX>, DCX> Decodable<DCX> for Option<T> {
    fn decode(context: &mut DecodingContext<DCX>) -> Option<T> {
        let disr = context.decoder().read_u32();
        if disr == 0 {
            None
        }
        else {
            Some(Decodable::decode(context))
        }
    }
}

struct Ty<'tcx> {
    id: u64,
    ast: Ast,
    sub_ty: Option<&'tcx Ty<'tcx>>
}

trait TyRestoreContext<'tcx> {
    fn create_interned(&self, id: u64, ast: Ast, sub_ty: Option<&'tcx Ty<'tcx>>) -> &'tcx Ty<'tcx>;
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for &'tcx Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> &'tcx Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        context.extra.create_interned(id, ast, sub_ty)
    }
}

impl<'tcx, DCX: TyRestoreContext<'tcx>> Decodable<DCX> for Ty<'tcx> {
    fn decode(context: &mut DecodingContext<DCX>) -> Ty<'tcx> {
        let id = Decodable::decode(context);
        let ast = Decodable::decode(context);
        let sub_ty = Decodable::decode(context);

        Ty {
            id: id,
            ast: ast,
            sub_ty: sub_ty
        }
    }
}
<|endoftext|>


<commit_before>/*!

*/

//!
//!
//!`MetaFactory` can be used to construct value creation chains from
//! closures or other sources that produce values.
//!
//! Let's look at really small example first:
//!
//! ```
//! use metafactory::{ metafactory, argless_as_factory, AsFactoryExt };
//!
//! fn main() {
//!     let meta_sum = metafactory(
//!         |a: int, b: int| a + b
//!     );
//!
//!     let sum_factory = meta_sum.new(vec![
//!         argless_as_factory(5i),
//!         argless_as_factory(6i),
//!     ]).ok().unwrap();
//!
//!     let getter = sum_factory.as_factory_of::<int>().unwrap();
//!
//!     assert_eq!(getter.take(), 11);
//! }
//! ```
//!
//! What is going on? Well, first we use `metafactory` generic function to
//! convert arbitrary closure to `MetaFactory` object `meta_sum`.
//!
//! It has a method `new`, which is used above to return a real
//! concrete factory `sum_factory`. As argument, it takes other factories.
//! The method `argless_as_factory()` returns factories for clonable values
//! `5i` and `6i`.
//!
//! So, metafactories can be created from different sources: clonable
//! objects or closures. In this case `5i` is a clonable object.
//!
//! Returned `sum_factory` has a `Box<Any>` type, and can be downcasted to
//! a `Factory` of appropriate type with `as_factory_of` method.
//!
//! Then you can call `take()` on this factory `getter` to invoke your closure
//! and return a new value.
//!
//! Note a lot of `unwrap` calls. All the potential argument or type
//! mismatches produce correct errors that can be dealt with.
//!
//! Now, the example above might seem a bit involved, but consider what it
//! allows us to do: provided argument counts and types match, we can
//! connect any chain of factories together, at runtime.
//!
//! Let's expand example to add a new factory that uses `sum_factory` as an
//! argument, and creates our own struct:
//!
//! ```
//! use metafactory::{ metafactory, argless_as_factory, AsFactoryExt };
//!
//! /// Our own struct.
//! struct Foo {
//!     value: int,
//! }
//!
//! fn main() {
//!     // initialization
//!
//!     let meta_sum = metafactory(
//!         |a: int, b: int| a + b
//!     );
//!
//!     let meta_foo = metafactory(
//!         |sum: int| Foo { value: sum }
//!     );
//!
//!     // plugging in
//!
//!     let foo_factory = meta_foo.new(vec![
//!         meta_sum.new(vec![
//!             argless_as_factory(5i),
//!             argless_as_factory(6i),
//!         ]).ok().unwrap()
//!     ]).ok().unwrap();
//!
//!     // using
//!
//!     let getter = foo_factory.as_factory_of::<Foo>().unwrap();
//!
//!     assert_eq!(getter.take().value, 11);
//! }
//! ```
//!
//! So, the intention of this library is to have a mechanism to separate 3
//! things: creating the values, plugging-in the factories
//! values, and using them.
//!
//! Created metafactories can also be used to inspect closure argument types.
//! It is also possible to clone the created factory: in such case, all
//! the call tree is also cloned internally. This makes it possible to
//! pass a copy of a factory to a task.
//!
//! Factories intentionally do not produce any kind of singletons or
//! references, only new values. You can also look at them as configurable
//! stream of values.
//!
//! If this library looks a bit lower-level, it is because it is intended as
//! such: more convenient wrappers like dependency injection or plugin
//! architecture can be implemented on top of this.
//!
//! Finally, a more complete example of available functionality:
//!
//! ```
//! use metafactory::{ metafactory, AsFactoryExt };
//!
//! fn main() {
//!     // build argument-factory from cloneable source.
//!     let meta_arg1 = metafactory(5i);
//!
//!     // build argument-factory from lambda.
//!     let meta_arg2 = metafactory(|| 14i32);
//!
//!     // build a factory that uses other factories create added numbers.
//!     let meta_adder = metafactory(|a1: int, a2: i32| a1 + a2 as int);
//!
//!     // it knows the cloneable source returns int
//!     assert!(meta_arg1.get_type().is::<int>());
//!     // it knows the lambda source returns i32
//!     assert!(meta_arg2.get_type().is::<i32>());
//!     // it knows the lambda with 2 args returns int
//!     assert!(meta_adder.get_type().is::<int>());
//!
//!     // create a factory for adder, pass other 2 factories as arguments
//!     let boxany = meta_adder.new(vec![
//!         meta_arg1.new(Vec::new()).ok().unwrap(),
//!         meta_arg2.new(Vec::new()).ok().unwrap(),
//!     ]).ok().unwrap();
//!
//!     // conveniently downcast factory to callable instance
//!     let factory = boxany.as_factory_of::<int>().unwrap();
//!
//!     // value should be the sum.
//!     assert_eq!(19, factory.take());
//!
//!     // factory can be cloned
//!     let factory2 = factory.clone();
//!
//!     // both clones invoke the same construction path and return the same value
//!     assert_eq!(factory.take(), factory2.take());
//! }
//! ```

#![feature(macro_rules)]
#![feature(unboxed_closures)]

extern crate typedef;

use std::any::{ Any, AnyRefExt };
use std::boxed::{ BoxAny };

use typedef::{ TypeDef };
use error::{ FactoryErrorKind };
use aggregate::Aggregate;

pub mod aggregate;
pub mod error;

mod factory;
mod from_clone;
mod from_closure;

/// Gettable value trait.
#[experimental]
pub trait Getter<T> {
    /// Produce a new value.
    fn take(&self) -> T;

    /// Create a clone for this getter.
    ///
    /// This is kind of experimental solution - can not return plain traits
    /// as function result.
    fn boxed_clone(&self) -> Box<Getter<T> + 'static>;
}

/// A factory proxy.
///
/// `Factory` proxy is used to return a concrete value from
/// unknown source. `Factory` will always produce a new owned value -
/// any other pattern can be implemented on top of that.
#[stable]
pub struct Factory<T:'static> {
    getter: Box<Getter<T> + 'static>,
}

#[stable]
impl<'a, T: 'static> Factory<T> {
    /// Create a new `Factory`.
    ///
    /// Create a new factory from any type that implements `Getter` trait.
    pub fn new(getter: Box<Getter<T> + 'static>) -> Factory<T> {
        Factory::<T> {
            getter: getter,
        }
    }

    /// Get a new owned value.
    pub fn take(&self) -> T {
        self.getter.take()
    }
}

impl<'a, T: 'static> Clone for Factory<T> {
    fn clone(&self) -> Factory<T> {
        Factory::<T> {
            getter: self.getter.boxed_clone(),
        }
    }
}

/// Downcast value to `Factory`.
pub trait AsFactoryExt {
    /// Downcast to factory and consume `Box<Any>`.
    fn as_factory_of<T>(self) -> Option<Factory<T>>;
    /// Downcast to factory by creating factory clone.
    fn as_factory_clone_of<T>(&self) -> Option<Factory<T>>;
}

impl AsFactoryExt for Box<Any> {
    fn as_factory_of<'a, T: 'static>(self) -> Option<Factory<T>> {
        match self.downcast::<Factory<T>>().ok() {
            Some(val) => Some(*val),
            None => None
        }
    }

    fn as_factory_clone_of<'a, T: 'static>(&self) -> Option<Factory<T>> {
        match self.downcast_ref::<Factory<T>>() {
            Some(val) => Some(val.clone()),
            None => None
        }
    }
}

/// Implements reflection and initiation of any abstract object constructor.
///
/// ## Information about constructor
///
/// The first goal of this trait is being able to inspect the construction
/// mechanism at the runtime.
///
/// `MetaFactory` contains information about the constructor source: the
/// return type and argument types. It also contains a method `new`
/// that can create a function to invoke this source and get the values.
///
/// ## Factory initiation
///
/// The second goal is to avoid donwcasting construction arguments on every
/// `Factory` invocation.
///
/// There are separate traits for `MetaFactory` and "real" `Factory`.
/// `MetaFactory` is used to build a real `Factory` by passing all the
/// required constructor arguments as factories under `Vec<Box<Any>>`.
///
/// Internaly, all parent `Factory`s will be downcasted to correct types
/// and stored inside returned `Factory`'s scope, so that all of them
/// can be invoked with a simple `take()` call.
///
/// ## Simple value as constructor
///
/// This library allows to use many sources as "constructors", the simplest
/// of which is a cloneable value. In this example we will use such value to
/// create a new constructor metadata, check if argument and return types are
/// correct, and then create an actual getter for the value:
///
/// ```
/// use metafactory::{ metafactory, AsFactoryExt };
///
/// let metafactory = metafactory(5i);
/// assert!(metafactory.get_type().is::<int>());
/// assert!(metafactory.get_arg_types().len() == 0); // clonable int has no arguments
///
/// let factory = metafactory
///     .new(
///         Vec::new() // No arguments in this case.
///     )
///     .ok().unwrap()
///     .as_factory_of::<int>()
///     .unwrap();
///
/// assert_eq!(factory.take(), 5i);
/// ```
#[unstable]
pub trait MetaFactory {
    #[unstable]
    fn get_type(&self) -> TypeDef;
    #[unstable]
    fn get_arg_types(&self) -> Vec<TypeDef>;
    #[unstable]
    fn new(&self, arg_getters: Vec<Box<Any>>) -> Result<Box<Any>, FactoryErrorKind>;
    #[unstable]
    fn new_aggregate(&self) -> Aggregate<'static>;
}

/// Trait for values convertable to `MetaFactory`.
///
/// This trait is implemented for values that can be used as
/// sources for object creation.
#[unstable]
pub trait ToMetaFactory {
    /// Creates a `MetaFactory` that has information about object
    /// constructor: produced object type, argument types, and
    /// a method to get this getter.
    #[unstable]
    fn to_metafactory<'a>(self) -> Box<MetaFactory + 'a>;
}

/// Create a new `MetaFactory` for any compatible value source.
///
/// Compatible value type must have `ToMetaFactory` implementation.
/// Supported sources are in submodules, look at "clone" for simpliest example.
pub fn metafactory<'r, T: ToMetaFactory>(any: T) -> Box<MetaFactory + 'r> {
    any.to_metafactory()
}

/// Create a new `MetaFactory` and return `Factory` in `Box<Any>` for source with no arguments.
///
/// Compatible value type must have `ToMetaFactory` implementation.
/// Supported sources are in submodules, look at "clone" for simpliest example.
pub fn argless_as_factory<T: ToMetaFactory>(any: T) -> Box<Any> {
    any.to_metafactory().new(Vec::new()).ok().unwrap()
}
<commit_msg>AnyRefExt fallout.<commit_after>/*!

*/

//!
//!
//!`MetaFactory` can be used to construct value creation chains from
//! closures or other sources that produce values.
//!
//! Let's look at really small example first:
//!
//! ```
//! use metafactory::{ metafactory, argless_as_factory, AsFactoryExt };
//!
//! fn main() {
//!     let meta_sum = metafactory(
//!         |a: int, b: int| a + b
//!     );
//!
//!     let sum_factory = meta_sum.new(vec![
//!         argless_as_factory(5i),
//!         argless_as_factory(6i),
//!     ]).ok().unwrap();
//!
//!     let getter = sum_factory.as_factory_of::<int>().unwrap();
//!
//!     assert_eq!(getter.take(), 11);
//! }
//! ```
//!
//! What is going on? Well, first we use `metafactory` generic function to
//! convert arbitrary closure to `MetaFactory` object `meta_sum`.
//!
//! It has a method `new`, which is used above to return a real
//! concrete factory `sum_factory`. As argument, it takes other factories.
//! The method `argless_as_factory()` returns factories for clonable values
//! `5i` and `6i`.
//!
//! So, metafactories can be created from different sources: clonable
//! objects or closures. In this case `5i` is a clonable object.
//!
//! Returned `sum_factory` has a `Box<Any>` type, and can be downcasted to
//! a `Factory` of appropriate type with `as_factory_of` method.
//!
//! Then you can call `take()` on this factory `getter` to invoke your closure
//! and return a new value.
//!
//! Note a lot of `unwrap` calls. All the potential argument or type
//! mismatches produce correct errors that can be dealt with.
//!
//! Now, the example above might seem a bit involved, but consider what it
//! allows us to do: provided argument counts and types match, we can
//! connect any chain of factories together, at runtime.
//!
//! Let's expand example to add a new factory that uses `sum_factory` as an
//! argument, and creates our own struct:
//!
//! ```
//! use metafactory::{ metafactory, argless_as_factory, AsFactoryExt };
//!
//! /// Our own struct.
//! struct Foo {
//!     value: int,
//! }
//!
//! fn main() {
//!     // initialization
//!
//!     let meta_sum = metafactory(
//!         |a: int, b: int| a + b
//!     );
//!
//!     let meta_foo = metafactory(
//!         |sum: int| Foo { value: sum }
//!     );
//!
//!     // plugging in
//!
//!     let foo_factory = meta_foo.new(vec![
//!         meta_sum.new(vec![
//!             argless_as_factory(5i),
//!             argless_as_factory(6i),
//!         ]).ok().unwrap()
//!     ]).ok().unwrap();
//!
//!     // using
//!
//!     let getter = foo_factory.as_factory_of::<Foo>().unwrap();
//!
//!     assert_eq!(getter.take().value, 11);
//! }
//! ```
//!
//! So, the intention of this library is to have a mechanism to separate 3
//! things: creating the values, plugging-in the factories
//! values, and using them.
//!
//! Created metafactories can also be used to inspect closure argument types.
//! It is also possible to clone the created factory: in such case, all
//! the call tree is also cloned internally. This makes it possible to
//! pass a copy of a factory to a task.
//!
//! Factories intentionally do not produce any kind of singletons or
//! references, only new values. You can also look at them as configurable
//! stream of values.
//!
//! If this library looks a bit lower-level, it is because it is intended as
//! such: more convenient wrappers like dependency injection or plugin
//! architecture can be implemented on top of this.
//!
//! Finally, a more complete example of available functionality:
//!
//! ```
//! use metafactory::{ metafactory, AsFactoryExt };
//!
//! fn main() {
//!     // build argument-factory from cloneable source.
//!     let meta_arg1 = metafactory(5i);
//!
//!     // build argument-factory from lambda.
//!     let meta_arg2 = metafactory(|| 14i32);
//!
//!     // build a factory that uses other factories create added numbers.
//!     let meta_adder = metafactory(|a1: int, a2: i32| a1 + a2 as int);
//!
//!     // it knows the cloneable source returns int
//!     assert!(meta_arg1.get_type().is::<int>());
//!     // it knows the lambda source returns i32
//!     assert!(meta_arg2.get_type().is::<i32>());
//!     // it knows the lambda with 2 args returns int
//!     assert!(meta_adder.get_type().is::<int>());
//!
//!     // create a factory for adder, pass other 2 factories as arguments
//!     let boxany = meta_adder.new(vec![
//!         meta_arg1.new(Vec::new()).ok().unwrap(),
//!         meta_arg2.new(Vec::new()).ok().unwrap(),
//!     ]).ok().unwrap();
//!
//!     // conveniently downcast factory to callable instance
//!     let factory = boxany.as_factory_of::<int>().unwrap();
//!
//!     // value should be the sum.
//!     assert_eq!(19, factory.take());
//!
//!     // factory can be cloned
//!     let factory2 = factory.clone();
//!
//!     // both clones invoke the same construction path and return the same value
//!     assert_eq!(factory.take(), factory2.take());
//! }
//! ```

#![feature(macro_rules)]
#![feature(unboxed_closures)]

extern crate typedef;

use std::any::{ Any };
use std::boxed::{ BoxAny };

use typedef::{ TypeDef };
use error::{ FactoryErrorKind };
use aggregate::Aggregate;

pub mod aggregate;
pub mod error;

mod factory;
mod from_clone;
mod from_closure;

/// Gettable value trait.
#[experimental]
pub trait Getter<T> {
    /// Produce a new value.
    fn take(&self) -> T;

    /// Create a clone for this getter.
    ///
    /// This is kind of experimental solution - can not return plain traits
    /// as function result.
    fn boxed_clone(&self) -> Box<Getter<T> + 'static>;
}

/// A factory proxy.
///
/// `Factory` proxy is used to return a concrete value from
/// unknown source. `Factory` will always produce a new owned value -
/// any other pattern can be implemented on top of that.
#[stable]
pub struct Factory<T:'static> {
    getter: Box<Getter<T> + 'static>,
}

#[stable]
impl<'a, T: 'static> Factory<T> {
    /// Create a new `Factory`.
    ///
    /// Create a new factory from any type that implements `Getter` trait.
    pub fn new(getter: Box<Getter<T> + 'static>) -> Factory<T> {
        Factory::<T> {
            getter: getter,
        }
    }

    /// Get a new owned value.
    pub fn take(&self) -> T {
        self.getter.take()
    }
}

impl<'a, T: 'static> Clone for Factory<T> {
    fn clone(&self) -> Factory<T> {
        Factory::<T> {
            getter: self.getter.boxed_clone(),
        }
    }
}

/// Downcast value to `Factory`.
pub trait AsFactoryExt {
    /// Downcast to factory and consume `Box<Any>`.
    fn as_factory_of<T>(self) -> Option<Factory<T>>;
    /// Downcast to factory by creating factory clone.
    fn as_factory_clone_of<T>(&self) -> Option<Factory<T>>;
}

impl AsFactoryExt for Box<Any> {
    fn as_factory_of<'a, T: 'static>(self) -> Option<Factory<T>> {
        match self.downcast::<Factory<T>>().ok() {
            Some(val) => Some(*val),
            None => None
        }
    }

    fn as_factory_clone_of<'a, T: 'static>(&self) -> Option<Factory<T>> {
        match self.downcast_ref::<Factory<T>>() {
            Some(val) => Some(val.clone()),
            None => None
        }
    }
}

/// Implements reflection and initiation of any abstract object constructor.
///
/// ## Information about constructor
///
/// The first goal of this trait is being able to inspect the construction
/// mechanism at the runtime.
///
/// `MetaFactory` contains information about the constructor source: the
/// return type and argument types. It also contains a method `new`
/// that can create a function to invoke this source and get the values.
///
/// ## Factory initiation
///
/// The second goal is to avoid donwcasting construction arguments on every
/// `Factory` invocation.
///
/// There are separate traits for `MetaFactory` and "real" `Factory`.
/// `MetaFactory` is used to build a real `Factory` by passing all the
/// required constructor arguments as factories under `Vec<Box<Any>>`.
///
/// Internaly, all parent `Factory`s will be downcasted to correct types
/// and stored inside returned `Factory`'s scope, so that all of them
/// can be invoked with a simple `take()` call.
///
/// ## Simple value as constructor
///
/// This library allows to use many sources as "constructors", the simplest
/// of which is a cloneable value. In this example we will use such value to
/// create a new constructor metadata, check if argument and return types are
/// correct, and then create an actual getter for the value:
///
/// ```
/// use metafactory::{ metafactory, AsFactoryExt };
///
/// let metafactory = metafactory(5i);
/// assert!(metafactory.get_type().is::<int>());
/// assert!(metafactory.get_arg_types().len() == 0); // clonable int has no arguments
///
/// let factory = metafactory
///     .new(
///         Vec::new() // No arguments in this case.
///     )
///     .ok().unwrap()
///     .as_factory_of::<int>()
///     .unwrap();
///
/// assert_eq!(factory.take(), 5i);
/// ```
#[unstable]
pub trait MetaFactory {
    #[unstable]
    fn get_type(&self) -> TypeDef;
    #[unstable]
    fn get_arg_types(&self) -> Vec<TypeDef>;
    #[unstable]
    fn new(&self, arg_getters: Vec<Box<Any>>) -> Result<Box<Any>, FactoryErrorKind>;
    #[unstable]
    fn new_aggregate(&self) -> Aggregate<'static>;
}

/// Trait for values convertable to `MetaFactory`.
///
/// This trait is implemented for values that can be used as
/// sources for object creation.
#[unstable]
pub trait ToMetaFactory {
    /// Creates a `MetaFactory` that has information about object
    /// constructor: produced object type, argument types, and
    /// a method to get this getter.
    #[unstable]
    fn to_metafactory<'a>(self) -> Box<MetaFactory + 'a>;
}

/// Create a new `MetaFactory` for any compatible value source.
///
/// Compatible value type must have `ToMetaFactory` implementation.
/// Supported sources are in submodules, look at "clone" for simpliest example.
pub fn metafactory<'r, T: ToMetaFactory>(any: T) -> Box<MetaFactory + 'r> {
    any.to_metafactory()
}

/// Create a new `MetaFactory` and return `Factory` in `Box<Any>` for source with no arguments.
///
/// Compatible value type must have `ToMetaFactory` implementation.
/// Supported sources are in submodules, look at "clone" for simpliest example.
pub fn argless_as_factory<T: ToMetaFactory>(any: T) -> Box<Any> {
    any.to_metafactory().new(Vec::new()).ok().unwrap()
}
<|endoftext|>


<commit_before>extern crate libc;

mod bindgen;

pub mod ffi_type;
pub mod low;

pub use bindgen::libffi as c;
pub use ffi_type::*;

use std::mem;
use std::os::raw::c_void;

#[derive(Clone, Debug)]
pub struct Cif {
    cif:    c::ffi_cif,
    args:   FfiTypeArray,
    result: FfiType,
}

#[derive(Debug)]
pub struct Arg(*mut c_void);

pub fn arg<T>(r: &T) -> Arg {
    Arg(unsafe { mem::transmute(r as *const T) })
}

impl Cif {
    pub fn new(args: FfiTypeArray, result: FfiType) -> Self {
        let mut cif: c::ffi_cif = Default::default();

        unsafe {
            low::prep_cif(&mut cif,
                          c::FFI_DEFAULT_ABI,
                          args.len(),
                          result.as_raw_ptr(),
                          args.as_raw_ptr())
        }.expect("low::prep_cif");

        // Note that cif retains references to args and result,
        // which is why we hold onto them here.
        Cif {
            cif:    cif,
            args:   args,
            result: result,
        }
    }

    pub unsafe fn call<R>(&self, f: usize, values: &[Arg]) -> R {
        use std::mem;

        assert!(self.cif.nargs as usize == values.len());

        low::call::<R>(mem::transmute(&self.cif),
                       mem::transmute(f),
                       mem::transmute(values.as_ptr()))
    }

    pub fn as_raw_ptr(&self) -> *mut c::ffi_cif {
        unsafe { mem::transmute(&self.cif) }
    }
}

pub struct Closure {
    _cif:  Box<Cif>,
    alloc: *mut ::low::ffi_closure,
    code:  extern "C" fn(),
}

impl Drop for Closure {
    fn drop(&mut self) {
        unsafe {
            low::closure_free(self.alloc);
        }
    }
}

pub fn new_closure(cif: *mut low::ffi_cif,
                   callback: low::Callback,
                   userdata: *mut c_void)
    -> (*mut low::ffi_closure, extern "C" fn())
{
    let (closure, fun) = low::closure_alloc();

    unsafe {
        low::prep_closure_loc(closure,
                              cif,
                              mem::transmute(callback as usize),
                              userdata,
                              fun).unwrap();
    }

    (closure, fun)
}

impl Closure {
    pub fn new(cif:  Cif,
               callback: low::Callback,
               userdata: *mut c_void) -> Self
    {
        let mut cif = Box::new(cif);
        let (alloc, code) = new_closure(cif.as_raw_ptr(), callback, userdata);

        Closure {
            _cif:  cif,
            alloc: alloc,
            code:  code,
        }
    }

    pub fn code_ptr(&self) -> unsafe extern "C" fn() {
        self.code
    }
}

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

    #[test]
    fn call() {
        use ffi_type::*;

        let args = FfiTypeArray::new(vec![FfiType::sint64(),
                                          FfiType::sint64()]);
        let cif  = Cif::new(args, FfiType::sint64());
        let f    = |m: i64, n: i64| -> i64 {
            unsafe { cif.call(add_it as usize, &[arg(&m), arg(&n)]) }
        };

        assert_eq!(12, f(5, 7));
        assert_eq!(13, f(6, 7));
        assert_eq!(15, f(8, 7));
    }

    extern "C" fn add_it(n: i64, m: i64) -> i64 {
        return n + m;
    }

    #[test]
    fn closure() {
        use ffi_type::*;
        let args = FfiTypeArray::new(vec![FfiType::sint64()]);
        let cif  = Cif::new(args, FfiType::sint64());
        let mut env: u64 = 5;

        unsafe {
            let closure = Closure::new(cif.clone(),
                                       mem::transmute(callback as usize),
                                       mem::transmute(&mut env));
            let fun: unsafe extern "C" fn(u64) -> u64
                = mem::transmute(closure.code_ptr());

            assert_eq!(11, fun(6));
            assert_eq!(12, fun(7));
        }
    }

    unsafe extern "C" fn callback(_cif: *mut low::ffi_cif,
                                  result: &mut u64,
                                  args: *const &u64,
                                  userdata: &u64)
    {
        *result = **args + *userdata;
    }
}
<commit_msg>Closure::new refactoring<commit_after>extern crate libc;

mod bindgen;

pub mod ffi_type;
pub mod low;

pub use bindgen::libffi as c;
pub use ffi_type::*;

use std::mem;
use std::os::raw::c_void;

#[derive(Clone, Debug)]
pub struct Cif {
    cif:    c::ffi_cif,
    args:   FfiTypeArray,
    result: FfiType,
}

#[derive(Debug)]
pub struct Arg(*mut c_void);

pub fn arg<T>(r: &T) -> Arg {
    Arg(unsafe { mem::transmute(r as *const T) })
}

impl Cif {
    pub fn new(args: FfiTypeArray, result: FfiType) -> Self {
        let mut cif: c::ffi_cif = Default::default();

        unsafe {
            low::prep_cif(&mut cif,
                          c::FFI_DEFAULT_ABI,
                          args.len(),
                          result.as_raw_ptr(),
                          args.as_raw_ptr())
        }.expect("low::prep_cif");

        // Note that cif retains references to args and result,
        // which is why we hold onto them here.
        Cif {
            cif:    cif,
            args:   args,
            result: result,
        }
    }

    pub unsafe fn call<R>(&self, f: usize, values: &[Arg]) -> R {
        use std::mem;

        assert!(self.cif.nargs as usize == values.len());

        low::call::<R>(mem::transmute(&self.cif),
                       mem::transmute(f),
                       mem::transmute(values.as_ptr()))
    }

    pub fn as_raw_ptr(&self) -> *mut c::ffi_cif {
        unsafe { mem::transmute(&self.cif) }
    }
}

pub struct Closure {
    _cif:  Box<Cif>,
    alloc: *mut ::low::ffi_closure,
    code:  extern "C" fn(),
}

impl Drop for Closure {
    fn drop(&mut self) {
        unsafe {
            low::closure_free(self.alloc);
        }
    }
}

impl Closure {
    pub fn new(cif:  Cif,
               callback: low::Callback,
               userdata: *mut c_void) -> Self
    {
        let cif = Box::new(cif);
        let (alloc, code) = low::closure_alloc();

        unsafe {
            low::prep_closure_loc(alloc,
                                  cif.as_raw_ptr(),
                                  mem::transmute(callback as usize),
                                  userdata,
                                  code).unwrap();
        }

        Closure {
            _cif:  cif,
            alloc: alloc,
            code:  code,
        }
    }

    pub fn code_ptr(&self) -> unsafe extern "C" fn() {
        self.code
    }
}

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

    #[test]
    fn call() {
        use ffi_type::*;

        let args = FfiTypeArray::new(vec![FfiType::sint64(),
                                          FfiType::sint64()]);
        let cif  = Cif::new(args, FfiType::sint64());
        let f    = |m: i64, n: i64| -> i64 {
            unsafe { cif.call(add_it as usize, &[arg(&m), arg(&n)]) }
        };

        assert_eq!(12, f(5, 7));
        assert_eq!(13, f(6, 7));
        assert_eq!(15, f(8, 7));
    }

    extern "C" fn add_it(n: i64, m: i64) -> i64 {
        return n + m;
    }

    #[test]
    fn closure() {
        use ffi_type::*;
        let args = FfiTypeArray::new(vec![FfiType::sint64()]);
        let cif  = Cif::new(args, FfiType::sint64());
        let mut env: u64 = 5;

        unsafe {
            let closure = Closure::new(cif.clone(),
                                       mem::transmute(callback as usize),
                                       mem::transmute(&mut env));
            let fun: unsafe extern "C" fn(u64) -> u64
                = mem::transmute(closure.code_ptr());

            assert_eq!(11, fun(6));
            assert_eq!(12, fun(7));
        }
    }

    unsafe extern "C" fn callback(_cif: *mut low::ffi_cif,
                                  result: &mut u64,
                                  args: *const &u64,
                                  userdata: &u64)
    {
        *result = **args + *userdata;
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

extern crate cairo_sys as ffi;
extern crate libc;

#[macro_use]
extern crate bitflags;

#[cfg(feature = "use_glib")]
#[macro_use]
extern crate glib;

#[cfg(feature = "use_glib")]
extern crate glib_sys as glib_ffi;

#[cfg(feature = "use_glib")]
extern crate gobject_sys as gobject_ffi;

#[cfg(test)]
extern crate tempfile;

// Helper macro for our GValue related trait impls
#[cfg(feature = "use_glib")]
macro_rules! gvalue_impl {
    ($name:ty, $ffi_name:ty, $get_type:expr) => {
        use glib;
        #[allow(unused_imports)]
        use glib::translate::*;
        use glib_ffi;
        use gobject_ffi;

        impl glib::types::StaticType for $name {
            fn static_type() -> glib::types::Type {
                unsafe { from_glib($get_type()) }
            }
        }

        impl<'a> glib::value::FromValueOptional<'a> for $name {
            unsafe fn from_value_optional(v: &'a glib::value::Value) -> Option<Self> {
                let ptr = gobject_ffi::g_value_get_boxed(v.to_glib_none().0);
                assert!(!ptr.is_null());
                from_glib_none(ptr as *mut $ffi_name)
            }
        }

        impl glib::value::SetValue for $name {
            unsafe fn set_value(v: &mut glib::value::Value, s: &Self) {
                gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.to_glib_none().0 as glib_ffi::gpointer);
            }
        }

        impl glib::value::SetValueOptional for $name {
            unsafe fn set_value_optional(v: &mut glib::value::Value, s: Option<&Self>) {
                if let Some(s) = s {
                    gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.to_glib_none().0 as glib_ffi::gpointer);
                } else {
                    gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ::std::ptr::null_mut());
                }
            }
        }
    }
}

pub use context::{
    Context,
    RectangleList,
};

pub use paths::{
    Path,
    PathSegments,
    PathSegment
};

pub use device::Device;

pub use enums::*;

pub use error::{
    BorrowError,
    IoError,
};

pub use patterns::{
    // Enums
    Pattern,
    // Traits
    PatternTrait,
    Gradient,

    // Structs
    LinearGradient,
    RadialGradient,
    SolidPattern,
    SurfacePattern,
};

pub use patterns::{
    Mesh,
};

pub use font::{
    FontFace,
    FontType,
    FontSlant,
    FontWeight,
    ScaledFont,
    FontOptions,

    Glyph,
    FontExtents,
    TextExtents,
    TextCluster,
};

pub use matrices::{
    Matrix,
    MatrixTrait,
};

pub use recording_surface::RecordingSurface;
pub use rectangle::Rectangle;
pub use rectangle_int::RectangleInt;

pub use region::Region;

pub use surface::{
    MappedImageSurface,
    Surface,
};

pub use image_surface::{
    ImageSurface,
    ImageSurfaceData,
};

#[cfg(any(feature = "xcb", feature = "dox"))]
pub use xcb::{
    XCBConnection,
    XCBSurface,
    XCBDrawable,
    XCBPixmap,
    XCBRenderPictFormInfo,
    XCBScreen,
    XCBVisualType,
};

pub mod prelude;

mod constants;
pub use constants::*;
mod utils;
pub use utils::*;

mod font;
mod context;
mod device;
mod enums;
mod error;
mod image_surface;
#[cfg(any(feature = "png", feature = "dox"))]
mod image_surface_png;
mod paths;
mod patterns;
mod recording_surface;
mod rectangle;
mod rectangle_int;
mod region;
mod surface;
mod matrices;
#[cfg(any(feature = "xcb", feature = "dox"))]
mod xcb;

#[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))]
mod support;
#[cfg(any(feature = "pdf", feature = "dox"))]
pub mod pdf;
#[cfg(any(feature = "svg", feature = "dox"))]
pub mod svg;
#[cfg(any(feature = "ps", feature = "dox"))]
pub mod ps;

#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
mod quartz_surface;
#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
pub use quartz_surface::QuartzSurface;

#[cfg(any(windows, feature = "dox"))]
mod win32_surface;

#[cfg(any(windows, feature = "dox"))]
pub use win32_surface::Win32Surface;
<commit_msg>Export SurfaceExt from the private surface module<commit_after>// Copyright 2013-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

extern crate cairo_sys as ffi;
extern crate libc;

#[macro_use]
extern crate bitflags;

#[cfg(feature = "use_glib")]
#[macro_use]
extern crate glib;

#[cfg(feature = "use_glib")]
extern crate glib_sys as glib_ffi;

#[cfg(feature = "use_glib")]
extern crate gobject_sys as gobject_ffi;

#[cfg(test)]
extern crate tempfile;

// Helper macro for our GValue related trait impls
#[cfg(feature = "use_glib")]
macro_rules! gvalue_impl {
    ($name:ty, $ffi_name:ty, $get_type:expr) => {
        use glib;
        #[allow(unused_imports)]
        use glib::translate::*;
        use glib_ffi;
        use gobject_ffi;

        impl glib::types::StaticType for $name {
            fn static_type() -> glib::types::Type {
                unsafe { from_glib($get_type()) }
            }
        }

        impl<'a> glib::value::FromValueOptional<'a> for $name {
            unsafe fn from_value_optional(v: &'a glib::value::Value) -> Option<Self> {
                let ptr = gobject_ffi::g_value_get_boxed(v.to_glib_none().0);
                assert!(!ptr.is_null());
                from_glib_none(ptr as *mut $ffi_name)
            }
        }

        impl glib::value::SetValue for $name {
            unsafe fn set_value(v: &mut glib::value::Value, s: &Self) {
                gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.to_glib_none().0 as glib_ffi::gpointer);
            }
        }

        impl glib::value::SetValueOptional for $name {
            unsafe fn set_value_optional(v: &mut glib::value::Value, s: Option<&Self>) {
                if let Some(s) = s {
                    gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, s.to_glib_none().0 as glib_ffi::gpointer);
                } else {
                    gobject_ffi::g_value_set_boxed(v.to_glib_none_mut().0, ::std::ptr::null_mut());
                }
            }
        }
    }
}

pub use context::{
    Context,
    RectangleList,
};

pub use paths::{
    Path,
    PathSegments,
    PathSegment
};

pub use device::Device;

pub use enums::*;

pub use error::{
    BorrowError,
    IoError,
};

pub use patterns::{
    // Enums
    Pattern,
    // Traits
    PatternTrait,
    Gradient,

    // Structs
    LinearGradient,
    RadialGradient,
    SolidPattern,
    SurfacePattern,
};

pub use patterns::{
    Mesh,
};

pub use font::{
    FontFace,
    FontType,
    FontSlant,
    FontWeight,
    ScaledFont,
    FontOptions,

    Glyph,
    FontExtents,
    TextExtents,
    TextCluster,
};

pub use matrices::{
    Matrix,
    MatrixTrait,
};

pub use recording_surface::RecordingSurface;
pub use rectangle::Rectangle;
pub use rectangle_int::RectangleInt;

pub use region::Region;

pub use surface::{
    MappedImageSurface,
    Surface,
    SurfaceExt,
};

pub use image_surface::{
    ImageSurface,
    ImageSurfaceData,
};

#[cfg(any(feature = "xcb", feature = "dox"))]
pub use xcb::{
    XCBConnection,
    XCBSurface,
    XCBDrawable,
    XCBPixmap,
    XCBRenderPictFormInfo,
    XCBScreen,
    XCBVisualType,
};

pub mod prelude;

mod constants;
pub use constants::*;
mod utils;
pub use utils::*;

mod font;
mod context;
mod device;
mod enums;
mod error;
mod image_surface;
#[cfg(any(feature = "png", feature = "dox"))]
mod image_surface_png;
mod paths;
mod patterns;
mod recording_surface;
mod rectangle;
mod rectangle_int;
mod region;
mod surface;
mod matrices;
#[cfg(any(feature = "xcb", feature = "dox"))]
mod xcb;

#[cfg(any(feature = "pdf", feature = "svg", feature = "ps", feature = "dox"))]
mod support;
#[cfg(any(feature = "pdf", feature = "dox"))]
pub mod pdf;
#[cfg(any(feature = "svg", feature = "dox"))]
pub mod svg;
#[cfg(any(feature = "ps", feature = "dox"))]
pub mod ps;

#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
mod quartz_surface;
#[cfg(any(target_os = "macos", target_os = "ios", feature = "dox"))]
pub use quartz_surface::QuartzSurface;

#[cfg(any(windows, feature = "dox"))]
mod win32_surface;

#[cfg(any(windows, feature = "dox"))]
pub use win32_surface::Win32Surface;
<|endoftext|>


<commit_before>extern crate nalgebra;
extern crate rand;

pub mod csv;
pub mod koe;
pub mod central_body;
pub mod tick;
pub use central_body::*;
pub use csv::*;
pub use koe::*;
pub use tick::*;

#[cfg(test)]
mod tests {
    use std::f64::consts::PI;
    use std::rc::*;
    use central_body::*;
    use csv::*;
    use koe::*;
    use tick::*;
    use rand::*;
    use nalgebra::*;

    #[test]
    fn koe_invariance() {
        let iterations = 10000;
        let eps = 1.0e-3;
        let mut a_ok = 0;
        let mut e_ok = 0;
        let mut inc_ok = 0;
        let mut lan_ok = 0;
        let mut ap_ok = 0;
        let mut m0_ok = 0;
        for _ in 0..iterations {
            let cb = get_random_cb();
            let koe0 = get_random_koe(Rc::<CentralBody>::new(cb));
            let csv0 = koe0.to_csv();
            let koe1 = csv0.to_koe();
            if approx_eq_eps(&koe0.a, &koe1.a, &eps) {
                a_ok += 1;
            }
            if approx_eq_eps(&koe0.e, &koe1.e, &eps) {
                e_ok += 1;
            }
            if approx_eq_eps(&koe0.inc, &koe1.inc, &eps) {
                inc_ok += 1;
            }
            if approx_eq_eps(&koe0.lan, &koe1.lan, &eps) {
                lan_ok += 1;
            }
            if approx_eq_eps(&koe0.ap, &koe1.ap, &eps) {
                ap_ok += 1;
            }
            if approx_eq_eps(&koe0.m0, &koe1.m0, &eps) {
                m0_ok += 1;
            }
        }
        let a_ok_f = a_ok as f32 / iterations as f32;
        let e_ok_f = e_ok as f32 / iterations as f32;
        let inc_ok_f = inc_ok as f32 / iterations as f32;
        let lan_ok_f = lan_ok as f32 / iterations as f32;
        let ap_ok_f = ap_ok as f32 / iterations as f32;
        let m0_ok_f = m0_ok as f32 / iterations as f32;
        let threshold = 0.99;
        let mut failed = false;

        println!("");
        println!("eps = {}", eps);
        println!("threshold = {}", threshold);
        if a_ok_f < threshold {
            println!("a_ok_f = {}", a_ok_f);
            if !failed {
                failed = true;
            }
        }
        if e_ok_f < threshold {
            println!("e_ok_f = {}", e_ok_f);
            if !failed {
                failed = true;
            }
        }
        if inc_ok_f < threshold {
            println!("inc_ok_f = {}", inc_ok_f);
            if !failed {
                failed = true;
            }
        }
        if lan_ok_f < threshold {
            println!("lan_ok_f = {}", lan_ok_f);
            if !failed {
                failed = true;
            }
        }
        if ap_ok_f < threshold {
            println!("ap_ok_f = {}", ap_ok_f);
            if !failed {
                failed = true;
            }
        }
        if m0_ok_f < threshold {
            println!("m0_ok_f = {}", m0_ok_f);
            if !failed {
                failed = true;
            }
        }
        if failed {
            panic!("success rate for one of the parameters is below threshold");
        }
    }

    #[test]
    fn csv_invariance() {
        let iterations = 10000;
        let eps = 1.0e-3;
        let mut r_ok = 0;
        let mut v_ok = 0;
        for _ in 0..iterations {
            let cb = get_random_cb();
            let koe0 = get_random_koe(Rc::<CentralBody>::new(cb));
            let csv0 = koe0.to_csv();
            let koe1 = csv0.to_koe();
            let csv1 = koe1.to_csv();
            if csv0.r.approx_eq_eps(&csv1.r, &eps) {
                r_ok += 1;
            }
            if csv0.v.approx_eq_eps(&csv1.v, &eps) {
                v_ok += 1;
            }
        }
        let r_ok_f = r_ok as f32 / iterations as f32;
        let v_ok_f = v_ok as f32 / iterations as f32;
        let threshold = 0.99;
        let mut failed = false;

        println!("");
        println!("eps = {}", eps);
        println!("threshold = {}", threshold);
        if r_ok_f < threshold {
            println!("r_ok_f = {}", r_ok_f);
            if !failed {
                failed = true;
            }
        }
        if v_ok_f < threshold {
            println!("v_ok_f = {}", v_ok_f);
            if !failed {
                failed = true;
            }
        }
        if failed {
            panic!("success rate for some of the parameters is below the threshold");
        }
    }

    fn get_random_cb() -> CentralBody {
        let mut rng = thread_rng();
        let up = normalize(
                &Vec3::new( // Up vector
                    rng.gen_range(0.1, 1.0),
                    rng.gen_range(0.1, 1.0),
                    rng.gen_range(0.1, 1.0)
                    )
            );
        let x_axis = Vec3::<f64>::new(1.0, 0.0, 0.0);
        let reference = normalize(&cross(&x_axis, &up));
        CentralBody::new(
            rng.gen_range(1.0e9, 1.0e25), // Standard Gravitational Parameter
            up,
            reference
        )
    }

    fn get_random_koe(cb: Rc<CentralBody>) -> KOE {
        let mut rng = thread_rng();
        let ecc = rng.gen_range(0.0, 1.0);
        let inc = rng.gen_range(0.0, PI);
        let mut lan = rng.gen_range(0.0, 2.0*PI);
        let mut ap = rng.gen_range(0.0, 2.0*PI);
        if approx_eq(&ecc, &0.0) {
            ap = 0.0;
        }
        if approx_eq(&inc, &0.0) {
            lan = 0.0;
            ap = 0.0;
            if !approx_eq(&ecc, &0.0) {
                ap = rng.gen_range(0.0, 2.0*PI);
            }
        }
        KOE::new(
            rng.gen_range(1.0, 1.0e10), // Semi major axis
            ecc, // Eccentricity
            inc, // Inclination
            lan, // Longitude of Ascending Node
            ap,  // Argument of Periapsis
            rng.gen_range(-PI, PI), // Mean anomaly
            cb
        )
    }
}
<commit_msg>Remove unused imports in tests module<commit_after>extern crate nalgebra;
extern crate rand;

pub mod csv;
pub mod koe;
pub mod central_body;
pub mod tick;
pub use central_body::*;
pub use csv::*;
pub use koe::*;
pub use tick::*;

#[cfg(test)]
mod tests {
    use std::f64::consts::PI;
    use std::rc::*;
    use central_body::*;
    use koe::*;
    use rand::*;
    use nalgebra::*;

    #[test]
    fn koe_invariance() {
        let iterations = 10000;
        let eps = 1.0e-3;
        let mut a_ok = 0;
        let mut e_ok = 0;
        let mut inc_ok = 0;
        let mut lan_ok = 0;
        let mut ap_ok = 0;
        let mut m0_ok = 0;
        for _ in 0..iterations {
            let cb = get_random_cb();
            let koe0 = get_random_koe(Rc::<CentralBody>::new(cb));
            let csv0 = koe0.to_csv();
            let koe1 = csv0.to_koe();
            if approx_eq_eps(&koe0.a, &koe1.a, &eps) {
                a_ok += 1;
            }
            if approx_eq_eps(&koe0.e, &koe1.e, &eps) {
                e_ok += 1;
            }
            if approx_eq_eps(&koe0.inc, &koe1.inc, &eps) {
                inc_ok += 1;
            }
            if approx_eq_eps(&koe0.lan, &koe1.lan, &eps) {
                lan_ok += 1;
            }
            if approx_eq_eps(&koe0.ap, &koe1.ap, &eps) {
                ap_ok += 1;
            }
            if approx_eq_eps(&koe0.m0, &koe1.m0, &eps) {
                m0_ok += 1;
            }
        }
        let a_ok_f = a_ok as f32 / iterations as f32;
        let e_ok_f = e_ok as f32 / iterations as f32;
        let inc_ok_f = inc_ok as f32 / iterations as f32;
        let lan_ok_f = lan_ok as f32 / iterations as f32;
        let ap_ok_f = ap_ok as f32 / iterations as f32;
        let m0_ok_f = m0_ok as f32 / iterations as f32;
        let threshold = 0.99;
        let mut failed = false;

        println!("");
        println!("eps = {}", eps);
        println!("threshold = {}", threshold);
        if a_ok_f < threshold {
            println!("a_ok_f = {}", a_ok_f);
            if !failed {
                failed = true;
            }
        }
        if e_ok_f < threshold {
            println!("e_ok_f = {}", e_ok_f);
            if !failed {
                failed = true;
            }
        }
        if inc_ok_f < threshold {
            println!("inc_ok_f = {}", inc_ok_f);
            if !failed {
                failed = true;
            }
        }
        if lan_ok_f < threshold {
            println!("lan_ok_f = {}", lan_ok_f);
            if !failed {
                failed = true;
            }
        }
        if ap_ok_f < threshold {
            println!("ap_ok_f = {}", ap_ok_f);
            if !failed {
                failed = true;
            }
        }
        if m0_ok_f < threshold {
            println!("m0_ok_f = {}", m0_ok_f);
            if !failed {
                failed = true;
            }
        }
        if failed {
            panic!("success rate for one of the parameters is below threshold");
        }
    }

    #[test]
    fn csv_invariance() {
        let iterations = 10000;
        let eps = 1.0e-3;
        let mut r_ok = 0;
        let mut v_ok = 0;
        for _ in 0..iterations {
            let cb = get_random_cb();
            let koe0 = get_random_koe(Rc::<CentralBody>::new(cb));
            let csv0 = koe0.to_csv();
            let koe1 = csv0.to_koe();
            let csv1 = koe1.to_csv();
            if csv0.r.approx_eq_eps(&csv1.r, &eps) {
                r_ok += 1;
            }
            if csv0.v.approx_eq_eps(&csv1.v, &eps) {
                v_ok += 1;
            }
        }
        let r_ok_f = r_ok as f32 / iterations as f32;
        let v_ok_f = v_ok as f32 / iterations as f32;
        let threshold = 0.99;
        let mut failed = false;

        println!("");
        println!("eps = {}", eps);
        println!("threshold = {}", threshold);
        if r_ok_f < threshold {
            println!("r_ok_f = {}", r_ok_f);
            if !failed {
                failed = true;
            }
        }
        if v_ok_f < threshold {
            println!("v_ok_f = {}", v_ok_f);
            if !failed {
                failed = true;
            }
        }
        if failed {
            panic!("success rate for some of the parameters is below the threshold");
        }
    }

    fn get_random_cb() -> CentralBody {
        let mut rng = thread_rng();
        let up = normalize(
                &Vec3::new( // Up vector
                    rng.gen_range(0.1, 1.0),
                    rng.gen_range(0.1, 1.0),
                    rng.gen_range(0.1, 1.0)
                    )
            );
        let x_axis = Vec3::<f64>::new(1.0, 0.0, 0.0);
        let reference = normalize(&cross(&x_axis, &up));
        CentralBody::new(
            rng.gen_range(1.0e9, 1.0e25), // Standard Gravitational Parameter
            up,
            reference
        )
    }

    fn get_random_koe(cb: Rc<CentralBody>) -> KOE {
        let mut rng = thread_rng();
        let ecc = rng.gen_range(0.0, 1.0);
        let inc = rng.gen_range(0.0, PI);
        let mut lan = rng.gen_range(0.0, 2.0*PI);
        let mut ap = rng.gen_range(0.0, 2.0*PI);
        if approx_eq(&ecc, &0.0) {
            ap = 0.0;
        }
        if approx_eq(&inc, &0.0) {
            lan = 0.0;
            ap = 0.0;
            if !approx_eq(&ecc, &0.0) {
                ap = rng.gen_range(0.0, 2.0*PI);
            }
        }
        KOE::new(
            rng.gen_range(1.0, 1.0e10), // Semi major axis
            ecc, // Eccentricity
            inc, // Inclination
            lan, // Longitude of Ascending Node
            ap,  // Argument of Periapsis
            rng.gen_range(-PI, PI), // Mean anomaly
            cb
        )
    }
}
<|endoftext|>


<commit_before>#![feature(plugin_registrar, rustc_private)]

extern crate rustc;
extern crate syntax;

use rustc::plugin::Registry;
use std::rc::Rc;
use syntax::ast::TokenTree::{self, TtToken};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::parse::token::{self, DelimToken, Token, IdentStyle};

mod parser_any_macro;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("interpolate_idents", interpolate_idents);
}

fn interpolate_idents<'a>(cx: &'a mut ExtCtxt,
              _: Span,
              tts: &[TokenTree]) -> Box<MacResult + 'a> {
    fn concat_idents(tts: &Vec<TokenTree>, delim: DelimToken) -> Option<TokenTree> {
        match delim {
            DelimToken::Bracket => {
                let mut new_ident = String::new();
                let mut new_span: Option<Span> = None;

                for token in tts.iter() {
                    match token {
                        &TtToken(ref span, Token::Ident(ref ident, IdentStyle::Plain)) => {
                            match new_span {
                                Some(ref mut s) => { s.hi = span.hi; },
                                None => { new_span = Some(span.clone()); },
                            }
                            new_ident.push_str(ident.name.as_str());
                        },
                        _ => return None,
                    }
                }

                match new_span {
                    Some(s) => {
                        let new_ident = token::str_to_ident(&new_ident[..]);
                        Some(TtToken(s, Token::Ident(new_ident, IdentStyle::Plain)))
                    },
                    None => None
                }
            },
            _ => None,
        }
    }

    fn map_tts(tts: &[TokenTree]) -> Vec<TokenTree> {
        tts.iter().map(|t| {
            match t {
                &TokenTree::TtDelimited(ref s, ref d) => {
                    match concat_idents(&d.tts, d.delim) {
                        Some(t) => t,
                        None => {
                            TokenTree::TtDelimited(s.clone(), Rc::new(syntax::ast::Delimited {
                                delim: d.delim,
                                open_span: d.open_span,
                                tts: map_tts(&*d.tts),
                                close_span: d.close_span,
                            }))
                        },
                    }
                },
                &TokenTree::TtSequence(ref s, ref d) => {
                    TokenTree::TtSequence(s.clone(), Rc::new(syntax::ast::SequenceRepetition {
                        tts: map_tts(&*d.tts),
                        separator: d.separator.clone(),
                        op: d.op,
                        num_captures: d.num_captures,
                    }))
                },
                _ => t.clone(),
            }
        }).collect()
    }

    let parser = cx.new_parser_from_tts(&map_tts(tts)[..]);
    Box::new(parser_any_macro::ParserAnyMacro::new(parser)) as Box<MacResult>
}
<commit_msg>Adjust to libsyntax API change (rust-lang/rust#27234)<commit_after>#![feature(plugin_registrar, rustc_private)]

extern crate rustc;
extern crate syntax;

use rustc::plugin::Registry;
use std::rc::Rc;
use syntax::ast::TokenTree::{self, TtToken};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult};
use syntax::parse::token::{self, DelimToken, Token, IdentStyle};

mod parser_any_macro;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("interpolate_idents", interpolate_idents);
}

fn interpolate_idents<'a>(cx: &'a mut ExtCtxt,
              _: Span,
              tts: &[TokenTree]) -> Box<MacResult + 'a> {
    fn concat_idents(tts: &Vec<TokenTree>, delim: DelimToken) -> Option<TokenTree> {
        match delim {
            DelimToken::Bracket => {
                let mut new_ident = String::new();
                let mut new_span: Option<Span> = None;

                for token in tts.iter() {
                    match token {
                        &TtToken(ref span, Token::Ident(ref ident, IdentStyle::Plain)) => {
                            match new_span {
                                Some(ref mut s) => { s.hi = span.hi; },
                                None => { new_span = Some(span.clone()); },
                            }
                            new_ident.push_str(&ident.name.as_str());
                        },
                        _ => return None,
                    }
                }

                match new_span {
                    Some(s) => {
                        let new_ident = token::str_to_ident(&new_ident[..]);
                        Some(TtToken(s, Token::Ident(new_ident, IdentStyle::Plain)))
                    },
                    None => None
                }
            },
            _ => None,
        }
    }

    fn map_tts(tts: &[TokenTree]) -> Vec<TokenTree> {
        tts.iter().map(|t| {
            match t {
                &TokenTree::TtDelimited(ref s, ref d) => {
                    match concat_idents(&d.tts, d.delim) {
                        Some(t) => t,
                        None => {
                            TokenTree::TtDelimited(s.clone(), Rc::new(syntax::ast::Delimited {
                                delim: d.delim,
                                open_span: d.open_span,
                                tts: map_tts(&*d.tts),
                                close_span: d.close_span,
                            }))
                        },
                    }
                },
                &TokenTree::TtSequence(ref s, ref d) => {
                    TokenTree::TtSequence(s.clone(), Rc::new(syntax::ast::SequenceRepetition {
                        tts: map_tts(&*d.tts),
                        separator: d.separator.clone(),
                        op: d.op,
                        num_captures: d.num_captures,
                    }))
                },
                _ => t.clone(),
            }
        }).collect()
    }

    let parser = cx.new_parser_from_tts(&map_tts(tts)[..]);
    Box::new(parser_any_macro::ParserAnyMacro::new(parser)) as Box<MacResult>
}
<|endoftext|>


<commit_before>// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate hyper;
extern crate reqwest;

extern crate base64;
extern crate byteorder;

#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate slog;
#[macro_use]
extern crate slog_scope;

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_xml_rs;

extern crate pnet;

extern crate openssl;

extern crate users;

mod providers;
mod metadata;
mod ssh;
mod network;
mod retry;

pub mod errors {
    error_chain!{
        foreign_links {
            Log(::slog::Error);
            XmlDeserialize(::serde_xml_rs::Error);
            Base64Decode(::base64::DecodeError);
            Io(::std::io::Error);
            Reqwest(::reqwest::Error);
            Hyper(::hyper::error::Error);
        }
        errors {
            UnknownProvider(p: String) {
                description("unknown provider")
                display("unknown provider '{}'", p)
            }
        }
    }
}

use providers::*;
use metadata::Metadata;

use errors::*;

/// fetch_metadata is the generic, top-level function that is used by the main
/// function to fetch metadata. The configured provider is passed in and this
/// function dispatches the call to the correct provider-specific fetch function
pub fn fetch_metadata(provider: &str) -> Result<Metadata> {
    match provider {
        "azure" => azure::fetch_metadata(),
        "digitalocean" => digitalocean::fetch_metadata(),
        "ec2" => ec2::fetch_metadata(),
        "gce" => gce::fetch_metadata(),
        "openstack" => openstack::fetch_metadata(),
        "packet" => packet::fetch_metadata(),
        "vagrant_virtualbox" => vagrant_virtualbox::fetch_metadata(),
        _ => Err(errors::ErrorKind::UnknownProvider(provider.to_owned()).into()),
    }
}
<commit_msg>lib: allow unused doc comments in errors mod<commit_after>// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate hyper;
extern crate reqwest;

extern crate base64;
extern crate byteorder;

#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate slog;
#[macro_use]
extern crate slog_scope;

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_xml_rs;

extern crate pnet;

extern crate openssl;

extern crate users;

mod providers;
mod metadata;
mod ssh;
mod network;
mod retry;

#[allow(unused_doc_comment)]
pub mod errors {
    error_chain!{
        foreign_links {
            Log(::slog::Error);
            XmlDeserialize(::serde_xml_rs::Error);
            Base64Decode(::base64::DecodeError);
            Io(::std::io::Error);
            Reqwest(::reqwest::Error);
            Hyper(::hyper::error::Error);
        }
        errors {
            UnknownProvider(p: String) {
                description("unknown provider")
                display("unknown provider '{}'", p)
            }
        }
    }
}

use providers::*;
use metadata::Metadata;

use errors::*;

/// fetch_metadata is the generic, top-level function that is used by the main
/// function to fetch metadata. The configured provider is passed in and this
/// function dispatches the call to the correct provider-specific fetch function
pub fn fetch_metadata(provider: &str) -> Result<Metadata> {
    match provider {
        "azure" => azure::fetch_metadata(),
        "digitalocean" => digitalocean::fetch_metadata(),
        "ec2" => ec2::fetch_metadata(),
        "gce" => gce::fetch_metadata(),
        "openstack" => openstack::fetch_metadata(),
        "packet" => packet::fetch_metadata(),
        "vagrant_virtualbox" => vagrant_virtualbox::fetch_metadata(),
        _ => Err(errors::ErrorKind::UnknownProvider(provider.to_owned()).into()),
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Matthew D. Michelotti
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This crate contains floating point types that panic if they are set
//! to an illegal value, such as NaN.
//!
//! The name "Noisy Float" comes from
//! the terms "quiet NaN" and "signaling NaN"; "signaling" was too long
//! to put in a struct/crate name, so "noisy" is used instead, being the opposite
//! of "quiet."
//!
//! The standard types defined in `noisy_float::types` follow the principle
//! demonstrated by Rust's handling of integer overflow:
//! a bad arithmetic operation is considered an error,
//! but it is too costly to check everywhere in optimized builds.
//! For each floating point number that is created, a `debug_assert!` invocation is used
//! to check if it is valid or not.
//! This way, there are guarantees when developing code that floating point
//! numbers have valid values,
//! but during a release run there is *no overhead* for using these floating
//! point types compared to using `f32` or `f64` directly.
//!
//! This crate makes use of the floating point and number traits in the
//! popular `num_traits` crate.
//!
//! #Examples
//! An example using the `R64` type, which corresponds to *finite* `f64` values.
//!
//! ```
//! use noisy_float::prelude::*;
//!
//! fn geometric_mean(a: R64, b: R64) -> R64 {
//!     (a * b).sqrt() //used just like regular floating point numbers
//! }
//!
//! fn mean(a: R64, b: R64) -> R64 {
//!     (a + b) * 0.5 //the RHS of ops can be the underlying float type
//! }
//!
//! println!("geometric_mean(10.0, 20.0) = {}", geometric_mean(r64(10.0), r64(20.0)));
//! //prints 14.142...
//! assert!(mean(r64(10.0), r64(20.0)) == 15.0);
//! ```
//!
//! An example using the `N32` type, which corresponds to *non-NaN* `f32` values.
//! The float types in this crate are able to implement `Eq` and `Ord` properly,
//! since NaN is not allowed.
//!
//! ```
//! use noisy_float::prelude::*;
//!
//! let values = vec![n32(3.0), n32(-1.5), n32(71.3), N32::infinity()];
//! assert!(values.iter().cloned().min() == Some(n32(-1.5)));
//! assert!(values.iter().cloned().max() == Some(N32::infinity()));
//! ```

extern crate num_traits;

mod float_impl;
pub mod checkers;
pub mod types;

/// Prelude for the `noisy_float` crate.
///
/// This includes all of the types defined in the `noisy_float::types` module,
/// as well as a re-export of the `Float` trait from the `num_traits` crate.
/// It is important to have this re-export here, because it allows the user
/// to access common floating point methods like `abs()`, `sqrt()`, etc.
pub mod prelude {
    pub use types::*;

    #[doc(no_inline)]
    pub use num_traits::Float;
}

use std::marker::PhantomData;
use std::fmt;
use num_traits::Float;

/// Trait for checking whether a floating point number is *valid*.
///
/// The implementation defines its own criteria for what constitutes a *valid* value.
pub trait FloatChecker<F> {
    /// Returns `true` if (and only if) the given floating point number is *valid*
    /// according to this checker's criteria.
    ///
    /// The only hard requirement is that NaN *must* be considered *invalid*
    /// for all implementations of `FloatChecker`.
    fn check(value: F) -> bool;

    /// A function that may panic if the floating point number is *invalid*.
    ///
    /// Should either call `assert!(check(value), ...)` or `debug_assert!(check(value), ...)`.
    fn assert(value: F);
}

/// A floating point number with a restricted set of legal values.
///
/// Typical users will not need to access this struct directly, but
/// can instead use the type aliases found in the module `noisy_float::types`.
/// However, this struct together with a `FloatChecker` implementation can be used
/// to define custom behavior.
///
/// The underlying float type is `F`, usually `f32` or `f64`.
/// Valid values for the float are determined by the float checker `C`.
/// If an invalid value would ever be returned from a method on this type,
/// the method will panic instead, using either `assert!` or `debug_assert!`
/// as defined by the float checker.
/// The exception to this rule is for methods that return an `Option` containing
/// a `NoisyFloat`, in which case the result would be `None` if the value is invalid.
pub struct NoisyFloat<F: Float, C: FloatChecker<F>> {
    value: F,
    checker: PhantomData<C>
}

impl<F: Float, C: FloatChecker<F>> NoisyFloat<F, C> {
    /// Constructs a `NoisyFloat` with the given value.
    ///
    /// Uses the `FloatChecker` to assert that the value is valid.
    #[inline]
    pub fn new(value: F) -> Self {
        C::assert(value);
        Self::unchecked_new(value)
    }

    #[inline]
    fn unchecked_new(value: F) -> Self {
        NoisyFloat {
            value: value,
            checker: PhantomData
        }
    }

    /// Tries to construct a `NoisyFloat` with the given value.
    ///
    /// Returns `None` if the value is invalid.
    #[inline]
    pub fn try_new(value: F) -> Option<Self> {
        if C::check(value) {
            Some(NoisyFloat {
                value: value,
                checker: PhantomData
            })
        } else {
            None
        }
    }

    /// Constructs a `NoisyFloat` with the given `f32` value.
    ///
    /// May panic not only by the `FloatChecker` but also
    /// by unwrapping the result of a `NumCast` invocation for type `F`,
    /// although the later should not occur in normal situations.
    #[inline]
    pub fn from_f32(value: f32) -> Self {
        Self::new(F::from(value).unwrap())
    }

    /// Constructs a `NoisyFloat` with the given `f64` value.
    ///
    /// May panic not only by the `FloatChecker` but also
    /// by unwrapping the result of a `NumCast` invocation for type `F`,
    /// although the later should not occur in normal situations.
    #[inline]
    pub fn from_f64(value: f64) -> Self {
        Self::new(F::from(value).unwrap())
    }

    /// Returns the underlying float value.
    #[inline]
    pub fn raw(self) -> F {
        self.value
    }
}

impl<F: Float + Default, C: FloatChecker<F>> Default for NoisyFloat<F, C> {
    #[inline]
    fn default() -> Self {
        Self::new(F::default())
    }
}

impl<F: Float + fmt::Debug, C: FloatChecker<F>> fmt::Debug for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&self.value, f)
    }
}

impl<F: Float + fmt::Display, C: FloatChecker<F>> fmt::Display for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Display::fmt(&self.value, f)
    }
}

impl<F: Float + fmt::LowerExp, C: FloatChecker<F>> fmt::LowerExp for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::LowerExp::fmt(&self.value, f)
    }
}

impl<F: Float + fmt::UpperExp, C: FloatChecker<F>> fmt::UpperExp for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::UpperExp::fmt(&self.value, f)
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;
    use std::f32;
    use std::f64::{self, consts};

    #[test]
    fn smoke_test() {
        assert!(n64(1.0) + 2.0 == 3.0);
        assert!(n64(3.0) != n64(2.9));
        assert!(r64(1.0) < 2.0);
        let mut value = n64(18.0);
        value %= n64(5.0);
        assert!(-value == n64(-3.0));
        assert!(r64(1.0).exp() == consts::E);
        assert!((N64::try_new(1.0).unwrap() / N64::infinity()) == 0.0);
        assert!(N64::from_f32(f32::INFINITY) == N64::from_f64(f64::INFINITY));
        assert!(R64::try_new(f64::NEG_INFINITY) == None);
        assert!(N64::try_new(f64::NAN) == None);
        assert!(R64::try_new(f64::NAN) == None);
    }

    #[test]
    #[should_panic]
    fn n64_nan() {
        n64(0.0) / n64(0.0);
    }

    #[test]
    #[should_panic]
    fn r64_nan() {
        r64(0.0) / r64(0.0);
    }

    #[test]
    #[should_panic]
    fn r64_infinity() {
        r64(1.0) / r64(0.0);
    }
}
<commit_msg>Ensure that layouts are right. Change tests to use assert_eq/ne.<commit_after>// Copyright 2016 Matthew D. Michelotti
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! This crate contains floating point types that panic if they are set
//! to an illegal value, such as NaN.
//!
//! The name "Noisy Float" comes from
//! the terms "quiet NaN" and "signaling NaN"; "signaling" was too long
//! to put in a struct/crate name, so "noisy" is used instead, being the opposite
//! of "quiet."
//!
//! The standard types defined in `noisy_float::types` follow the principle
//! demonstrated by Rust's handling of integer overflow:
//! a bad arithmetic operation is considered an error,
//! but it is too costly to check everywhere in optimized builds.
//! For each floating point number that is created, a `debug_assert!` invocation is used
//! to check if it is valid or not.
//! This way, there are guarantees when developing code that floating point
//! numbers have valid values,
//! but during a release run there is *no overhead* for using these floating
//! point types compared to using `f32` or `f64` directly.
//!
//! This crate makes use of the floating point and number traits in the
//! popular `num_traits` crate.
//!
//! #Examples
//! An example using the `R64` type, which corresponds to *finite* `f64` values.
//!
//! ```
//! use noisy_float::prelude::*;
//!
//! fn geometric_mean(a: R64, b: R64) -> R64 {
//!     (a * b).sqrt() //used just like regular floating point numbers
//! }
//!
//! fn mean(a: R64, b: R64) -> R64 {
//!     (a + b) * 0.5 //the RHS of ops can be the underlying float type
//! }
//!
//! println!("geometric_mean(10.0, 20.0) = {}", geometric_mean(r64(10.0), r64(20.0)));
//! //prints 14.142...
//! assert!(mean(r64(10.0), r64(20.0)) == 15.0);
//! ```
//!
//! An example using the `N32` type, which corresponds to *non-NaN* `f32` values.
//! The float types in this crate are able to implement `Eq` and `Ord` properly,
//! since NaN is not allowed.
//!
//! ```
//! use noisy_float::prelude::*;
//!
//! let values = vec![n32(3.0), n32(-1.5), n32(71.3), N32::infinity()];
//! assert!(values.iter().cloned().min() == Some(n32(-1.5)));
//! assert!(values.iter().cloned().max() == Some(N32::infinity()));
//! ```

extern crate num_traits;

mod float_impl;
pub mod checkers;
pub mod types;

/// Prelude for the `noisy_float` crate.
///
/// This includes all of the types defined in the `noisy_float::types` module,
/// as well as a re-export of the `Float` trait from the `num_traits` crate.
/// It is important to have this re-export here, because it allows the user
/// to access common floating point methods like `abs()`, `sqrt()`, etc.
pub mod prelude {
    pub use types::*;

    #[doc(no_inline)]
    pub use num_traits::Float;
}

use std::marker::PhantomData;
use std::fmt;
use num_traits::Float;

/// Trait for checking whether a floating point number is *valid*.
///
/// The implementation defines its own criteria for what constitutes a *valid* value.
pub trait FloatChecker<F> {
    /// Returns `true` if (and only if) the given floating point number is *valid*
    /// according to this checker's criteria.
    ///
    /// The only hard requirement is that NaN *must* be considered *invalid*
    /// for all implementations of `FloatChecker`.
    fn check(value: F) -> bool;

    /// A function that may panic if the floating point number is *invalid*.
    ///
    /// Should either call `assert!(check(value), ...)` or `debug_assert!(check(value), ...)`.
    fn assert(value: F);
}

/// A floating point number with a restricted set of legal values.
///
/// Typical users will not need to access this struct directly, but
/// can instead use the type aliases found in the module `noisy_float::types`.
/// However, this struct together with a `FloatChecker` implementation can be used
/// to define custom behavior.
///
/// The underlying float type is `F`, usually `f32` or `f64`.
/// Valid values for the float are determined by the float checker `C`.
/// If an invalid value would ever be returned from a method on this type,
/// the method will panic instead, using either `assert!` or `debug_assert!`
/// as defined by the float checker.
/// The exception to this rule is for methods that return an `Option` containing
/// a `NoisyFloat`, in which case the result would be `None` if the value is invalid.
#[repr(C)]
pub struct NoisyFloat<F: Float, C: FloatChecker<F>> {
    value: F,
    checker: PhantomData<C>
}

impl<F: Float, C: FloatChecker<F>> NoisyFloat<F, C> {
    /// Constructs a `NoisyFloat` with the given value.
    ///
    /// Uses the `FloatChecker` to assert that the value is valid.
    #[inline]
    pub fn new(value: F) -> Self {
        C::assert(value);
        Self::unchecked_new(value)
    }

    #[inline]
    fn unchecked_new(value: F) -> Self {
        NoisyFloat {
            value: value,
            checker: PhantomData
        }
    }

    /// Tries to construct a `NoisyFloat` with the given value.
    ///
    /// Returns `None` if the value is invalid.
    #[inline]
    pub fn try_new(value: F) -> Option<Self> {
        if C::check(value) {
            Some(NoisyFloat {
                value: value,
                checker: PhantomData
            })
        } else {
            None
        }
    }

    /// Constructs a `NoisyFloat` with the given `f32` value.
    ///
    /// May panic not only by the `FloatChecker` but also
    /// by unwrapping the result of a `NumCast` invocation for type `F`,
    /// although the later should not occur in normal situations.
    #[inline]
    pub fn from_f32(value: f32) -> Self {
        Self::new(F::from(value).unwrap())
    }

    /// Constructs a `NoisyFloat` with the given `f64` value.
    ///
    /// May panic not only by the `FloatChecker` but also
    /// by unwrapping the result of a `NumCast` invocation for type `F`,
    /// although the later should not occur in normal situations.
    #[inline]
    pub fn from_f64(value: f64) -> Self {
        Self::new(F::from(value).unwrap())
    }

    /// Returns the underlying float value.
    #[inline]
    pub fn raw(self) -> F {
        self.value
    }
}

impl<F: Float + Default, C: FloatChecker<F>> Default for NoisyFloat<F, C> {
    #[inline]
    fn default() -> Self {
        Self::new(F::default())
    }
}

impl<F: Float + fmt::Debug, C: FloatChecker<F>> fmt::Debug for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&self.value, f)
    }
}

impl<F: Float + fmt::Display, C: FloatChecker<F>> fmt::Display for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Display::fmt(&self.value, f)
    }
}

impl<F: Float + fmt::LowerExp, C: FloatChecker<F>> fmt::LowerExp for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::LowerExp::fmt(&self.value, f)
    }
}

impl<F: Float + fmt::UpperExp, C: FloatChecker<F>> fmt::UpperExp for NoisyFloat<F, C> {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::UpperExp::fmt(&self.value, f)
    }
}

#[cfg(test)]
mod tests {
    use prelude::*;
    use std::f32;
    use std::f64::{self, consts};
    use std::mem::{size_of, align_of};

    #[test]
    fn smoke_test() {
        assert_eq!(n64(1.0) + 2.0, 3.0);
        assert_ne!(n64(3.0), n64(2.9));
        assert!(r64(1.0) < 2.0);
        let mut value = n64(18.0);
        value %= n64(5.0);
        assert_eq!(-value, n64(-3.0));
        assert_eq!(r64(1.0).exp(), consts::E);
        assert_eq!((N64::try_new(1.0).unwrap() / N64::infinity()), 0.0);
        assert_eq!(N64::from_f32(f32::INFINITY), N64::from_f64(f64::INFINITY));
        assert_eq!(R64::try_new(f64::NEG_INFINITY), None);
        assert_eq!(N64::try_new(f64::NAN), None);
        assert_eq!(R64::try_new(f64::NAN), None);
    }

    #[test]
    fn ensure_layout() {
        assert_eq!(size_of::<N32>(), size_of::<f32>());
        assert_eq!(align_of::<N32>(), align_of::<f32>());

        assert_eq!(size_of::<N64>(), size_of::<f64>());
        assert_eq!(align_of::<N64>(), align_of::<f64>());
    }

    #[test]
    #[should_panic]
    fn n64_nan() {
        n64(0.0) / n64(0.0);
    }

    #[test]
    #[should_panic]
    fn r64_nan() {
        r64(0.0) / r64(0.0);
    }

    #[test]
    #[should_panic]
    fn r64_infinity() {
        r64(1.0) / r64(0.0);
    }
}
<|endoftext|>


<commit_before>#![no_std]

#![feature(slicing_syntax)]
#![feature(overloaded_calls)]
#![feature(unboxed_closures)]
#![feature(macro_rules)]
#![feature(globs)]

extern crate core;

pub use sort::{sort, sort_by, insertion_sort, heapsort};

mod sort;

mod std {
    mod slice {
        pub use core::slice::AsSlice;
    }
}<commit_msg>Remove overloaded_calls feature gate<commit_after>#![no_std]

#![feature(slicing_syntax)]
#![feature(unboxed_closures)]
#![feature(macro_rules)]
#![feature(globs)]

extern crate core;

pub use sort::{sort, sort_by, insertion_sort, heapsort};

mod sort;

mod std {
    mod slice {
        pub use core::slice::AsSlice;
    }
}<|endoftext|>