<commit_before>use std::collections::HashMap;
use std::num::NonZeroU64;
use std::rc::Rc;

use failure::format_err;
use log::debug;

use crate::core::interning::InternedString;
use crate::core::{Dependency, PackageId, SourceId, Summary};
use crate::util::Graph;

use super::dep_cache::RegistryQueryer;
use super::errors::ActivateResult;
use super::types::{ConflictMap, FeaturesSet, ResolveOpts};

pub use super::encode::Metadata;
pub use super::encode::{EncodableDependency, EncodablePackageId, EncodableResolve};
pub use super::resolve::Resolve;

// A `Context` is basically a bunch of local resolution information which is
// kept around for all `BacktrackFrame` instances. As a result, this runs the
// risk of being cloned *a lot* so we want to make this as cheap to clone as
// possible.
#[derive(Clone)]
pub struct Context {
    pub activations: Activations,
    /// list the features that are activated for each package
    pub resolve_features: im_rc::HashMap<PackageId, FeaturesSet>,
    /// get the package that will be linking to a native library by its links attribute
    pub links: im_rc::HashMap<InternedString, PackageId>,
    /// for each package the list of names it can see,
    /// then for each name the exact version that name represents and weather the name is public.
    pub public_dependency:
        Option<im_rc::HashMap<PackageId, im_rc::HashMap<InternedString, (PackageId, bool)>>>,

    /// a way to look up for a package in activations what packages required it
    /// and all of the exact deps that it fulfilled.
    pub parents: Graph<PackageId, Rc<Vec<Dependency>>>,
}

/// When backtracking it can be useful to know how far back to go.
/// The `ContextAge` of a `Context` is a monotonically increasing counter of the number
/// of decisions made to get to this state.
/// Several structures store the `ContextAge` when it was added,
/// to be used in `find_candidate` for backtracking.
pub type ContextAge = usize;

/// Find the activated version of a crate based on the name, source, and semver compatibility.
/// By storing this in a hash map we ensure that there is only one
/// semver compatible version of each crate.
/// This all so stores the `ContextAge`.
pub type Activations =
    im_rc::HashMap<(InternedString, SourceId, SemverCompatibility), (Summary, ContextAge)>;

/// A type that represents when cargo treats two Versions as compatible.
/// Versions `a` and `b` are compatible if their left-most nonzero digit is the
/// same.
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub enum SemverCompatibility {
    Major(NonZeroU64),
    Minor(NonZeroU64),
    Patch(u64),
}

impl From<&semver::Version> for SemverCompatibility {
    fn from(ver: &semver::Version) -> Self {
        if let Some(m) = NonZeroU64::new(ver.major) {
            return SemverCompatibility::Major(m);
        }
        if let Some(m) = NonZeroU64::new(ver.minor) {
            return SemverCompatibility::Minor(m);
        }
        SemverCompatibility::Patch(ver.patch)
    }
}

impl PackageId {
    pub fn as_activations_key(self) -> (InternedString, SourceId, SemverCompatibility) {
        (self.name(), self.source_id(), self.version().into())
    }
}

impl Context {
    pub fn new(check_public_visible_dependencies: bool) -> Context {
        Context {
            resolve_features: im_rc::HashMap::new(),
            links: im_rc::HashMap::new(),
            public_dependency: if check_public_visible_dependencies {
                Some(im_rc::HashMap::new())
            } else {
                None
            },
            parents: Graph::new(),
            activations: im_rc::HashMap::new(),
        }
    }

    /// Activate this summary by inserting it into our list of known activations.
    ///
    /// The `parent` passed in here is the parent summary/dependency edge which
    /// cased `summary` to get activated. This may not be present for the root
    /// crate, for example.
    ///
    /// Returns `true` if this summary with the given features is already activated.
    pub fn flag_activated(
        &mut self,
        summary: &Summary,
        opts: &ResolveOpts,
        parent: Option<(&Summary, &Dependency)>,
    ) -> ActivateResult<bool> {
        let id = summary.package_id();
        let age: ContextAge = self.age();
        match self.activations.entry(id.as_activations_key()) {
            im_rc::hashmap::Entry::Occupied(o) => {
                debug_assert_eq!(
                    &o.get().0,
                    summary,
                    "cargo does not allow two semver compatible versions"
                );
            }
            im_rc::hashmap::Entry::Vacant(v) => {
                if let Some(link) = summary.links() {
                    if self.links.insert(link, id).is_some() {
                        return Err(format_err!(
                            "Attempting to resolve a dependency with more then \
                             one crate with links={}.\nThis will not build as \
                             is. Consider rebuilding the .lock file.",
                            &*link
                        )
                        .into());
                    }
                }
                v.insert((summary.clone(), age));

                // If we've got a parent dependency which activated us, *and*
                // the dependency has a different source id listed than the
                // `summary` itself, then things get interesting. This basically
                // means that a `[patch]` was used to augment `dep.source_id()`
                // with `summary`.
                //
                // In this scenario we want to consider the activation key, as
                // viewed from the perspective of `dep.source_id()`, as being
                // fulfilled. This means that we need to add a second entry in
                // the activations map for the source that was patched, in
                // addition to the source of the actual `summary` itself.
                //
                // Without this it would be possible to have both 1.0.0 and
                // 1.1.0 "from crates.io" in a dependency graph if one of those
                // versions came from a `[patch]` source.
                if let Some((_, dep)) = parent {
                    if dep.source_id() != id.source_id() {
                        let key = (id.name(), dep.source_id(), id.version().into());
                        let prev = self.activations.insert(key, (summary.clone(), age));
                        assert!(prev.is_none());
                    }
                }

                return Ok(false);
            }
        }
        debug!("checking if {} is already activated", summary.package_id());
        if opts.all_features {
            return Ok(false);
        }

        let has_default_feature = summary.features().contains_key("default");
        Ok(match self.resolve_features.get(&id) {
            Some(prev) => {
                opts.features.is_subset(prev)
                    && (!opts.uses_default_features
                        || prev.contains("default")
                        || !has_default_feature)
            }
            None => {
                opts.features.is_empty() && (!opts.uses_default_features || !has_default_feature)
            }
        })
    }

    /// Returns the `ContextAge` of this `Context`.
    /// For now we use (len of activations) as the age.
    /// See the `ContextAge` docs for more details.
    pub fn age(&self) -> ContextAge {
        self.activations.len()
    }

    /// If the package is active returns the `ContextAge` when it was added
    pub fn is_active(&self, id: PackageId) -> Option<ContextAge> {
        self.activations
            .get(&id.as_activations_key())
            .and_then(|(s, l)| if s.package_id() == id { Some(*l) } else { None })
    }

    /// Checks whether all of `parent` and the keys of `conflicting activations`
    /// are still active.
    /// If so returns the `ContextAge` when the newest one was added.
    pub fn is_conflicting(
        &self,
        parent: Option<PackageId>,
        conflicting_activations: &ConflictMap,
    ) -> Option<usize> {
        let mut max = 0;
        for &id in conflicting_activations.keys().chain(parent.as_ref()) {
            if let Some(age) = self.is_active(id) {
                max = std::cmp::max(max, age);
            } else {
                return None;
            }
        }
        Some(max)
    }

    pub fn resolve_replacements(
        &self,
        registry: &RegistryQueryer<'_>,
    ) -> HashMap<PackageId, PackageId> {
        self.activations
            .values()
            .filter_map(|(s, _)| registry.used_replacement_for(s.package_id()))
            .collect()
    }

    pub fn graph(&self) -> Graph<PackageId, Vec<Dependency>> {
        let mut graph: Graph<PackageId, Vec<Dependency>> = Graph::new();
        self.activations
            .values()
            .for_each(|(r, _)| graph.add(r.package_id()));
        for i in self.parents.iter() {
            graph.add(*i);
            for (o, e) in self.parents.edges(i) {
                let old_link = graph.link(*o, *i);
                assert!(old_link.is_empty());
                *old_link = e.to_vec();
            }
        }
        graph
    }
}
<commit_msg>Don't panic on a non-fatal error<commit_after>use std::collections::HashMap;
use std::num::NonZeroU64;
use std::rc::Rc;

use failure::format_err;
use log::debug;

use crate::core::interning::InternedString;
use crate::core::{Dependency, PackageId, SourceId, Summary};
use crate::util::Graph;

use super::dep_cache::RegistryQueryer;
use super::errors::ActivateResult;
use super::types::{ConflictMap, ConflictReason, FeaturesSet, ResolveOpts};

pub use super::encode::Metadata;
pub use super::encode::{EncodableDependency, EncodablePackageId, EncodableResolve};
pub use super::resolve::Resolve;

// A `Context` is basically a bunch of local resolution information which is
// kept around for all `BacktrackFrame` instances. As a result, this runs the
// risk of being cloned *a lot* so we want to make this as cheap to clone as
// possible.
#[derive(Clone)]
pub struct Context {
    pub activations: Activations,
    /// list the features that are activated for each package
    pub resolve_features: im_rc::HashMap<PackageId, FeaturesSet>,
    /// get the package that will be linking to a native library by its links attribute
    pub links: im_rc::HashMap<InternedString, PackageId>,
    /// for each package the list of names it can see,
    /// then for each name the exact version that name represents and weather the name is public.
    pub public_dependency:
        Option<im_rc::HashMap<PackageId, im_rc::HashMap<InternedString, (PackageId, bool)>>>,

    /// a way to look up for a package in activations what packages required it
    /// and all of the exact deps that it fulfilled.
    pub parents: Graph<PackageId, Rc<Vec<Dependency>>>,
}

/// When backtracking it can be useful to know how far back to go.
/// The `ContextAge` of a `Context` is a monotonically increasing counter of the number
/// of decisions made to get to this state.
/// Several structures store the `ContextAge` when it was added,
/// to be used in `find_candidate` for backtracking.
pub type ContextAge = usize;

/// Find the activated version of a crate based on the name, source, and semver compatibility.
/// By storing this in a hash map we ensure that there is only one
/// semver compatible version of each crate.
/// This all so stores the `ContextAge`.
pub type Activations =
    im_rc::HashMap<(InternedString, SourceId, SemverCompatibility), (Summary, ContextAge)>;

/// A type that represents when cargo treats two Versions as compatible.
/// Versions `a` and `b` are compatible if their left-most nonzero digit is the
/// same.
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
pub enum SemverCompatibility {
    Major(NonZeroU64),
    Minor(NonZeroU64),
    Patch(u64),
}

impl From<&semver::Version> for SemverCompatibility {
    fn from(ver: &semver::Version) -> Self {
        if let Some(m) = NonZeroU64::new(ver.major) {
            return SemverCompatibility::Major(m);
        }
        if let Some(m) = NonZeroU64::new(ver.minor) {
            return SemverCompatibility::Minor(m);
        }
        SemverCompatibility::Patch(ver.patch)
    }
}

impl PackageId {
    pub fn as_activations_key(self) -> (InternedString, SourceId, SemverCompatibility) {
        (self.name(), self.source_id(), self.version().into())
    }
}

impl Context {
    pub fn new(check_public_visible_dependencies: bool) -> Context {
        Context {
            resolve_features: im_rc::HashMap::new(),
            links: im_rc::HashMap::new(),
            public_dependency: if check_public_visible_dependencies {
                Some(im_rc::HashMap::new())
            } else {
                None
            },
            parents: Graph::new(),
            activations: im_rc::HashMap::new(),
        }
    }

    /// Activate this summary by inserting it into our list of known activations.
    ///
    /// The `parent` passed in here is the parent summary/dependency edge which
    /// cased `summary` to get activated. This may not be present for the root
    /// crate, for example.
    ///
    /// Returns `true` if this summary with the given features is already activated.
    pub fn flag_activated(
        &mut self,
        summary: &Summary,
        opts: &ResolveOpts,
        parent: Option<(&Summary, &Dependency)>,
    ) -> ActivateResult<bool> {
        let id = summary.package_id();
        let age: ContextAge = self.age();
        match self.activations.entry(id.as_activations_key()) {
            im_rc::hashmap::Entry::Occupied(o) => {
                debug_assert_eq!(
                    &o.get().0,
                    summary,
                    "cargo does not allow two semver compatible versions"
                );
            }
            im_rc::hashmap::Entry::Vacant(v) => {
                if let Some(link) = summary.links() {
                    if self.links.insert(link, id).is_some() {
                        return Err(format_err!(
                            "Attempting to resolve a dependency with more then \
                             one crate with links={}.\nThis will not build as \
                             is. Consider rebuilding the .lock file.",
                            &*link
                        )
                        .into());
                    }
                }
                v.insert((summary.clone(), age));

                // If we've got a parent dependency which activated us, *and*
                // the dependency has a different source id listed than the
                // `summary` itself, then things get interesting. This basically
                // means that a `[patch]` was used to augment `dep.source_id()`
                // with `summary`.
                //
                // In this scenario we want to consider the activation key, as
                // viewed from the perspective of `dep.source_id()`, as being
                // fulfilled. This means that we need to add a second entry in
                // the activations map for the source that was patched, in
                // addition to the source of the actual `summary` itself.
                //
                // Without this it would be possible to have both 1.0.0 and
                // 1.1.0 "from crates.io" in a dependency graph if one of those
                // versions came from a `[patch]` source.
                if let Some((_, dep)) = parent {
                    if dep.source_id() != id.source_id() {
                        let key = (id.name(), dep.source_id(), id.version().into());
                        let prev = self.activations.insert(key, (summary.clone(), age));
                        if let Some((previous_summary, _)) = prev {
                            return Err(
                                (previous_summary.package_id(), ConflictReason::Semver).into()
                            );
                        }
                    }
                }

                return Ok(false);
            }
        }
        debug!("checking if {} is already activated", summary.package_id());
        if opts.all_features {
            return Ok(false);
        }

        let has_default_feature = summary.features().contains_key("default");
        Ok(match self.resolve_features.get(&id) {
            Some(prev) => {
                opts.features.is_subset(prev)
                    && (!opts.uses_default_features
                        || prev.contains("default")
                        || !has_default_feature)
            }
            None => {
                opts.features.is_empty() && (!opts.uses_default_features || !has_default_feature)
            }
        })
    }

    /// Returns the `ContextAge` of this `Context`.
    /// For now we use (len of activations) as the age.
    /// See the `ContextAge` docs for more details.
    pub fn age(&self) -> ContextAge {
        self.activations.len()
    }

    /// If the package is active returns the `ContextAge` when it was added
    pub fn is_active(&self, id: PackageId) -> Option<ContextAge> {
        self.activations
            .get(&id.as_activations_key())
            .and_then(|(s, l)| if s.package_id() == id { Some(*l) } else { None })
    }

    /// Checks whether all of `parent` and the keys of `conflicting activations`
    /// are still active.
    /// If so returns the `ContextAge` when the newest one was added.
    pub fn is_conflicting(
        &self,
        parent: Option<PackageId>,
        conflicting_activations: &ConflictMap,
    ) -> Option<usize> {
        let mut max = 0;
        for &id in conflicting_activations.keys().chain(parent.as_ref()) {
            if let Some(age) = self.is_active(id) {
                max = std::cmp::max(max, age);
            } else {
                return None;
            }
        }
        Some(max)
    }

    pub fn resolve_replacements(
        &self,
        registry: &RegistryQueryer<'_>,
    ) -> HashMap<PackageId, PackageId> {
        self.activations
            .values()
            .filter_map(|(s, _)| registry.used_replacement_for(s.package_id()))
            .collect()
    }

    pub fn graph(&self) -> Graph<PackageId, Vec<Dependency>> {
        let mut graph: Graph<PackageId, Vec<Dependency>> = Graph::new();
        self.activations
            .values()
            .for_each(|(r, _)| graph.add(r.package_id()));
        for i in self.parents.iter() {
            graph.add(*i);
            for (o, e) in self.parents.edges(i) {
                let old_link = graph.link(*o, *i);
                assert!(old_link.is_empty());
                *old_link = e.to_vec();
            }
        }
        graph
    }
}
<|endoftext|>


<commit_before>use arena::{DropArena, DroplessArena, TypedArena};
use std::marker::PhantomData;
use std::mem;

/// This declares a list of types which can be allocated by `Arena`.
///
/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
/// This is faster and more memory efficient if there's only a few allocations of the type.
/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
/// faster and more memory efficient if there is lots of allocations.
///
/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
/// listed. These impls will appear in the implement_ty_decoder! macro.
#[macro_export]
macro_rules! arena_types {
    ($macro:path, $args:tt, $tcx:lifetime) => (
        $macro!($args, [
            [] layouts: rustc::ty::layout::LayoutDetails,
            [] generics: rustc::ty::Generics,
            [] trait_def: rustc::ty::TraitDef,
            [] adt_def: rustc::ty::AdtDef,
            [] steal_mir: rustc::ty::steal::Steal<rustc::mir::BodyAndCache<$tcx>>,
            [] mir: rustc::mir::BodyAndCache<$tcx>,
            [] steal_promoted: rustc::ty::steal::Steal<
                rustc_index::vec::IndexVec<
                    rustc::mir::Promoted,
                    rustc::mir::BodyAndCache<$tcx>
                >
            >,
            [] promoted: rustc_index::vec::IndexVec<
                rustc::mir::Promoted,
                rustc::mir::BodyAndCache<$tcx>
            >,
            [decode] tables: rustc::ty::TypeckTables<$tcx>,
            [decode] borrowck_result: rustc::mir::BorrowCheckResult<$tcx>,
            [] const_allocs: rustc::mir::interpret::Allocation,
            [] vtable_method: Option<(
                rustc_hir::def_id::DefId,
                rustc::ty::subst::SubstsRef<$tcx>
            )>,
            [few, decode] mir_keys: rustc_hir::def_id::DefIdSet,
            [decode] specialization_graph: rustc::traits::specialization_graph::Graph,
            [] region_scope_tree: rustc::middle::region::ScopeTree,
            [] item_local_set: rustc_hir::ItemLocalSet,
            [decode] mir_const_qualif: rustc_index::bit_set::BitSet<rustc::mir::Local>,
            [] trait_impls_of: rustc::ty::trait_def::TraitImpls,
            [] associated_items: rustc::ty::AssociatedItems,
            [] dropck_outlives:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx,
                        rustc::traits::query::DropckOutlivesResult<'tcx>
                    >
                >,
            [] normalize_projection_ty:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx,
                        rustc::traits::query::NormalizationResult<'tcx>
                    >
                >,
            [] implied_outlives_bounds:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx,
                        Vec<rustc::traits::query::OutlivesBound<'tcx>>
                    >
                >,
            [] type_op_subtype:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, ()>
                >,
            [] type_op_normalize_poly_fn_sig:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::PolyFnSig<'tcx>>
                >,
            [] type_op_normalize_fn_sig:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::FnSig<'tcx>>
                >,
            [] type_op_normalize_predicate:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Predicate<'tcx>>
                >,
            [] type_op_normalize_ty:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
                >,
            [few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
            [few] upstream_monomorphizations:
                rustc_hir::def_id::DefIdMap<
                    rustc_data_structures::fx::FxHashMap<
                        rustc::ty::subst::SubstsRef<'tcx>,
                        rustc_hir::def_id::CrateNum
                    >
                >,
            [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
                rustc_span::symbol::Symbol,
                rustc_hir::def_id::DefId,
            >,
            [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
            [few] lint_levels: rustc::lint::LintLevelMap,
            [few] stability_index: rustc::middle::stability::Index<'tcx>,
            [few] features: rustc_feature::Features,
            [few] all_traits: Vec<rustc_hir::def_id::DefId>,
            [few] privacy_access_levels: rustc::middle::privacy::AccessLevels,
            [few] target_features_whitelist: rustc_data_structures::fx::FxHashMap<
                String,
                Option<rustc_span::symbol::Symbol>
            >,
            [few] wasm_import_module_map: rustc_data_structures::fx::FxHashMap<
                rustc_hir::def_id::DefId,
                String
            >,
            [few] get_lib_features: rustc::middle::lib_features::LibFeatures,
            [few] defined_lib_features: rustc::middle::lang_items::LanguageItems,
            [few] visible_parent_map: rustc_hir::def_id::DefIdMap<rustc_hir::def_id::DefId>,
            [few] foreign_module: rustc::middle::cstore::ForeignModule,
            [few] foreign_modules: Vec<rustc::middle::cstore::ForeignModule>,
            [few] reachable_non_generics: rustc_hir::def_id::DefIdMap<
                rustc::middle::exported_symbols::SymbolExportLevel
            >,
            [few] crate_variances: rustc::ty::CrateVariancesMap<'tcx>,
            [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
            [] upvars: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,

            // Interned types
            [] tys: rustc::ty::TyS<$tcx>,

            // HIR types
            [few] hir_krate: rustc_hir::Crate<$tcx>,
            [] arm: rustc_hir::Arm<$tcx>,
            [] attribute: rustc_ast::ast::Attribute,
            [] block: rustc_hir::Block<$tcx>,
            [] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
            [few] global_asm: rustc_hir::GlobalAsm,
            [] generic_arg: rustc_hir::GenericArg<$tcx>,
            [] generic_args: rustc_hir::GenericArgs<$tcx>,
            [] generic_bound: rustc_hir::GenericBound<$tcx>,
            [] generic_param: rustc_hir::GenericParam<$tcx>,
            [] expr: rustc_hir::Expr<$tcx>,
            [] field: rustc_hir::Field<$tcx>,
            [] field_pat: rustc_hir::FieldPat<$tcx>,
            [] fn_decl: rustc_hir::FnDecl<$tcx>,
            [] foreign_item: rustc_hir::ForeignItem<$tcx>,
            [] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
            [] inline_asm: rustc_hir::InlineAsm<$tcx>,
            [] local: rustc_hir::Local<$tcx>,
            [few] macro_def: rustc_hir::MacroDef<$tcx>,
            [] param: rustc_hir::Param<$tcx>,
            [] pat: rustc_hir::Pat<$tcx>,
            [] path: rustc_hir::Path<$tcx>,
            [] path_segment: rustc_hir::PathSegment<$tcx>,
            [] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
            [] qpath: rustc_hir::QPath<$tcx>,
            [] stmt: rustc_hir::Stmt<$tcx>,
            [] struct_field: rustc_hir::StructField<$tcx>,
            [] trait_item_ref: rustc_hir::TraitItemRef,
            [] ty: rustc_hir::Ty<$tcx>,
            [] type_binding: rustc_hir::TypeBinding<$tcx>,
            [] variant: rustc_hir::Variant<$tcx>,
            [] where_predicate: rustc_hir::WherePredicate<$tcx>,

            // HIR query types
            [few] indexed_hir: rustc::hir::map::IndexedHir<$tcx>,
            [few] hir_definitions: rustc::hir::map::definitions::Definitions,
            [] hir_owner: rustc::hir::Owner<$tcx>,
            [] hir_owner_nodes: rustc::hir::OwnerNodes<$tcx>,
        ], $tcx);
    )
}

macro_rules! arena_for_type {
    ([][$ty:ty]) => {
        TypedArena<$ty>
    };
    ([few $(, $attrs:ident)*][$ty:ty]) => {
        PhantomData<$ty>
    };
    ([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
        arena_for_type!([$($attrs),*]$args)
    };
}

macro_rules! declare_arena {
    ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
        #[derive(Default)]
        pub struct Arena<$tcx> {
            pub dropless: DroplessArena,
            drop: DropArena,
            $($name: arena_for_type!($a[$ty]),)*
        }

        $(
            impl ArenaAllocatable for $ty {}
            unsafe impl<$tcx> ArenaField<$tcx> for $ty {
                #[inline]
                fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> {
                    which_arena_for_type!($a[&_arena.$name])
                }
            }
        )*
    }
}

macro_rules! which_arena_for_type {
    ([][$arena:expr]) => {
        Some($arena)
    };
    ([few$(, $attrs:ident)*][$arena:expr]) => {
        None
    };
    ([$ignore:ident$(, $attrs:ident)*]$args:tt) => {
        which_arena_for_type!([$($attrs),*]$args)
    };
}

arena_types!(declare_arena, [], 'tcx);

#[marker]
pub trait ArenaAllocatable {}

impl<T: Copy> ArenaAllocatable for T {}

unsafe trait ArenaField<'tcx>: Sized {
    /// Returns a specific arena to allocate from.
    /// If `None` is returned, the `DropArena` will be used.
    fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;
}

unsafe impl<'tcx, T> ArenaField<'tcx> for T {
    #[inline]
    default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> {
        panic!()
    }
}

impl<'tcx> Arena<'tcx> {
    #[inline]
    pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
        if !mem::needs_drop::<T>() {
            return self.dropless.alloc(value);
        }
        match <T as ArenaField<'tcx>>::arena(self) {
            Some(arena) => arena.alloc(value),
            None => unsafe { self.drop.alloc(value) },
        }
    }

    #[inline]
    pub fn alloc_slice<T: Copy>(&self, value: &[T]) -> &mut [T] {
        if value.is_empty() {
            return &mut [];
        }
        self.dropless.alloc_slice(value)
    }

    pub fn alloc_from_iter<T: ArenaAllocatable, I: IntoIterator<Item = T>>(
        &'a self,
        iter: I,
    ) -> &'a mut [T] {
        if !mem::needs_drop::<T>() {
            return self.dropless.alloc_from_iter(iter);
        }
        match <T as ArenaField<'tcx>>::arena(self) {
            Some(arena) => arena.alloc_from_iter(iter),
            None => unsafe { self.drop.alloc_from_iter(iter) },
        }
    }
}
<commit_msg>move more logic into declare_arena!<commit_after>use arena::{DropArena, DroplessArena, TypedArena};
use std::marker::PhantomData;
use std::mem;

/// This declares a list of types which can be allocated by `Arena`.
///
/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
/// This is faster and more memory efficient if there's only a few allocations of the type.
/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
/// faster and more memory efficient if there is lots of allocations.
///
/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
/// listed. These impls will appear in the implement_ty_decoder! macro.
#[macro_export]
macro_rules! arena_types {
    ($macro:path, $args:tt, $tcx:lifetime) => (
        $macro!($args, [
            [] layouts: rustc::ty::layout::LayoutDetails,
            [] generics: rustc::ty::Generics,
            [] trait_def: rustc::ty::TraitDef,
            [] adt_def: rustc::ty::AdtDef,
            [] steal_mir: rustc::ty::steal::Steal<rustc::mir::BodyAndCache<$tcx>>,
            [] mir: rustc::mir::BodyAndCache<$tcx>,
            [] steal_promoted: rustc::ty::steal::Steal<
                rustc_index::vec::IndexVec<
                    rustc::mir::Promoted,
                    rustc::mir::BodyAndCache<$tcx>
                >
            >,
            [] promoted: rustc_index::vec::IndexVec<
                rustc::mir::Promoted,
                rustc::mir::BodyAndCache<$tcx>
            >,
            [decode] tables: rustc::ty::TypeckTables<$tcx>,
            [decode] borrowck_result: rustc::mir::BorrowCheckResult<$tcx>,
            [] const_allocs: rustc::mir::interpret::Allocation,
            [] vtable_method: Option<(
                rustc_hir::def_id::DefId,
                rustc::ty::subst::SubstsRef<$tcx>
            )>,
            [few, decode] mir_keys: rustc_hir::def_id::DefIdSet,
            [decode] specialization_graph: rustc::traits::specialization_graph::Graph,
            [] region_scope_tree: rustc::middle::region::ScopeTree,
            [] item_local_set: rustc_hir::ItemLocalSet,
            [decode] mir_const_qualif: rustc_index::bit_set::BitSet<rustc::mir::Local>,
            [] trait_impls_of: rustc::ty::trait_def::TraitImpls,
            [] associated_items: rustc::ty::AssociatedItems,
            [] dropck_outlives:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx,
                        rustc::traits::query::DropckOutlivesResult<'tcx>
                    >
                >,
            [] normalize_projection_ty:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx,
                        rustc::traits::query::NormalizationResult<'tcx>
                    >
                >,
            [] implied_outlives_bounds:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx,
                        Vec<rustc::traits::query::OutlivesBound<'tcx>>
                    >
                >,
            [] type_op_subtype:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, ()>
                >,
            [] type_op_normalize_poly_fn_sig:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::PolyFnSig<'tcx>>
                >,
            [] type_op_normalize_fn_sig:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::FnSig<'tcx>>
                >,
            [] type_op_normalize_predicate:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Predicate<'tcx>>
                >,
            [] type_op_normalize_ty:
                rustc::infer::canonical::Canonical<'tcx,
                    rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
                >,
            [few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
            [few] upstream_monomorphizations:
                rustc_hir::def_id::DefIdMap<
                    rustc_data_structures::fx::FxHashMap<
                        rustc::ty::subst::SubstsRef<'tcx>,
                        rustc_hir::def_id::CrateNum
                    >
                >,
            [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
                rustc_span::symbol::Symbol,
                rustc_hir::def_id::DefId,
            >,
            [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
            [few] lint_levels: rustc::lint::LintLevelMap,
            [few] stability_index: rustc::middle::stability::Index<'tcx>,
            [few] features: rustc_feature::Features,
            [few] all_traits: Vec<rustc_hir::def_id::DefId>,
            [few] privacy_access_levels: rustc::middle::privacy::AccessLevels,
            [few] target_features_whitelist: rustc_data_structures::fx::FxHashMap<
                String,
                Option<rustc_span::symbol::Symbol>
            >,
            [few] wasm_import_module_map: rustc_data_structures::fx::FxHashMap<
                rustc_hir::def_id::DefId,
                String
            >,
            [few] get_lib_features: rustc::middle::lib_features::LibFeatures,
            [few] defined_lib_features: rustc::middle::lang_items::LanguageItems,
            [few] visible_parent_map: rustc_hir::def_id::DefIdMap<rustc_hir::def_id::DefId>,
            [few] foreign_module: rustc::middle::cstore::ForeignModule,
            [few] foreign_modules: Vec<rustc::middle::cstore::ForeignModule>,
            [few] reachable_non_generics: rustc_hir::def_id::DefIdMap<
                rustc::middle::exported_symbols::SymbolExportLevel
            >,
            [few] crate_variances: rustc::ty::CrateVariancesMap<'tcx>,
            [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
            [] upvars: rustc_data_structures::fx::FxIndexMap<rustc_hir::HirId, rustc_hir::Upvar>,

            // Interned types
            [] tys: rustc::ty::TyS<$tcx>,

            // HIR types
            [few] hir_krate: rustc_hir::Crate<$tcx>,
            [] arm: rustc_hir::Arm<$tcx>,
            [] attribute: rustc_ast::ast::Attribute,
            [] block: rustc_hir::Block<$tcx>,
            [] bare_fn_ty: rustc_hir::BareFnTy<$tcx>,
            [few] global_asm: rustc_hir::GlobalAsm,
            [] generic_arg: rustc_hir::GenericArg<$tcx>,
            [] generic_args: rustc_hir::GenericArgs<$tcx>,
            [] generic_bound: rustc_hir::GenericBound<$tcx>,
            [] generic_param: rustc_hir::GenericParam<$tcx>,
            [] expr: rustc_hir::Expr<$tcx>,
            [] field: rustc_hir::Field<$tcx>,
            [] field_pat: rustc_hir::FieldPat<$tcx>,
            [] fn_decl: rustc_hir::FnDecl<$tcx>,
            [] foreign_item: rustc_hir::ForeignItem<$tcx>,
            [] impl_item_ref: rustc_hir::ImplItemRef<$tcx>,
            [] inline_asm: rustc_hir::InlineAsm<$tcx>,
            [] local: rustc_hir::Local<$tcx>,
            [few] macro_def: rustc_hir::MacroDef<$tcx>,
            [] param: rustc_hir::Param<$tcx>,
            [] pat: rustc_hir::Pat<$tcx>,
            [] path: rustc_hir::Path<$tcx>,
            [] path_segment: rustc_hir::PathSegment<$tcx>,
            [] poly_trait_ref: rustc_hir::PolyTraitRef<$tcx>,
            [] qpath: rustc_hir::QPath<$tcx>,
            [] stmt: rustc_hir::Stmt<$tcx>,
            [] struct_field: rustc_hir::StructField<$tcx>,
            [] trait_item_ref: rustc_hir::TraitItemRef,
            [] ty: rustc_hir::Ty<$tcx>,
            [] type_binding: rustc_hir::TypeBinding<$tcx>,
            [] variant: rustc_hir::Variant<$tcx>,
            [] where_predicate: rustc_hir::WherePredicate<$tcx>,

            // HIR query types
            [few] indexed_hir: rustc::hir::map::IndexedHir<$tcx>,
            [few] hir_definitions: rustc::hir::map::definitions::Definitions,
            [] hir_owner: rustc::hir::Owner<$tcx>,
            [] hir_owner_nodes: rustc::hir::OwnerNodes<$tcx>,
        ], $tcx);
    )
}

macro_rules! arena_for_type {
    ([][$ty:ty]) => {
        TypedArena<$ty>
    };
    ([few $(, $attrs:ident)*][$ty:ty]) => {
        PhantomData<$ty>
    };
    ([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
        arena_for_type!([$($attrs),*]$args)
    };
}

macro_rules! which_arena_for_type {
    ([][$arena:expr]) => {
        Some($arena)
    };
    ([few$(, $attrs:ident)*][$arena:expr]) => {
        None
    };
    ([$ignore:ident$(, $attrs:ident)*]$args:tt) => {
        which_arena_for_type!([$($attrs),*]$args)
    };
}

macro_rules! declare_arena {
    ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
        #[derive(Default)]
        pub struct Arena<$tcx> {
            pub dropless: DroplessArena,
            drop: DropArena,
            $($name: arena_for_type!($a[$ty]),)*
        }

        #[marker]
        pub trait ArenaAllocatable {}

        impl<T: Copy> ArenaAllocatable for T {}

        unsafe trait ArenaField<'tcx>: Sized {
            /// Returns a specific arena to allocate from.
            /// If `None` is returned, the `DropArena` will be used.
            fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;
        }

        unsafe impl<'tcx, T> ArenaField<'tcx> for T {
            #[inline]
            default fn arena<'a>(_: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>> {
                panic!()
            }
        }

        $(
            impl ArenaAllocatable for $ty {}
            unsafe impl<$tcx> ArenaField<$tcx> for $ty {
                #[inline]
                fn arena<'a>(_arena: &'a Arena<$tcx>) -> Option<&'a TypedArena<Self>> {
                    which_arena_for_type!($a[&_arena.$name])
                }
            }
        )*

        impl<'tcx> Arena<'tcx> {
            #[inline]
            pub fn alloc<T: ArenaAllocatable>(&self, value: T) -> &mut T {
                if !mem::needs_drop::<T>() {
                    return self.dropless.alloc(value);
                }
                match <T as ArenaField<'tcx>>::arena(self) {
                    Some(arena) => arena.alloc(value),
                    None => unsafe { self.drop.alloc(value) },
                }
            }

            #[inline]
            pub fn alloc_slice<T: Copy>(&self, value: &[T]) -> &mut [T] {
                if value.is_empty() {
                    return &mut [];
                }
                self.dropless.alloc_slice(value)
            }

            pub fn alloc_from_iter<T: ArenaAllocatable, I: IntoIterator<Item = T>>(
                &'a self,
                iter: I,
            ) -> &'a mut [T] {
                if !mem::needs_drop::<T>() {
                    return self.dropless.alloc_from_iter(iter);
                }
                match <T as ArenaField<'tcx>>::arena(self) {
                    Some(arena) => arena.alloc_from_iter(iter),
                    None => unsafe { self.drop.alloc_from_iter(iter) },
                }
            }
        }
    }
}

arena_types!(declare_arena, [], 'tcx);
<|endoftext|>


<commit_before>pub extern crate syslog;

pub use self::syslog::Severity;

#[cfg(not(test))]
use self::prod_calls::{stdout_log, syslog_log};
#[cfg(test)]
use self::test_calls::{stdout_log, syslog_log};

#[derive(Debug, PartialEq, Clone)]
pub enum LogDest {
    StdOut,
    Syslog,
}

#[derive(Debug, Clone)]
pub struct Logger {
    dest: LogDest
}

impl Logger {
    pub fn new(dest: LogDest) -> Logger {
        Logger { dest: dest }
    }

    pub fn log(&self, severity: Severity, msg: &str) -> () {
        match self.dest {
            LogDest::StdOut => {
                stdout_log(severity, msg);
            }
            LogDest::Syslog => {
                syslog_log(severity, msg);
            }
        }
    }
}

#[allow(dead_code)]
mod prod_calls {
    extern crate ansi_term;

    use self::ansi_term::Colour::{Red, Yellow, White, Green, Cyan, Blue};
    use super::Severity;
    use super::syslog::{unix, Facility};

    pub fn stdout_log(severity: Severity, msg: &str) -> () {
        match severity {
            Severity::LOG_EMERG => {
                println!("<0> {}", Cyan.paint(msg));
            }
            Severity::LOG_ALERT => {
                println!("<1> {}", Red.paint(msg));
            }
            Severity::LOG_CRIT => {
                println!("<2> {}", Red.paint(msg));
            }
            Severity::LOG_ERR => {
                println!("<3> {}", Red.paint(msg));
            }
            Severity::LOG_WARNING => {
                println!("<4> {}", Yellow.paint(msg));
            }
            Severity::LOG_NOTICE => {
                println!("<5> {}", Blue.paint(msg));
            }
            Severity::LOG_INFO => {
                println!("<6> {}", White.paint(msg));
            }
            Severity::LOG_DEBUG => {
                println!("<7> {}", Green.paint(msg));
            }
        }
    }

    pub fn syslog_log(severity: Severity, msg: &str) -> () {
        match unix(Facility::LOG_DAEMON) {
            Err(e) => println!("[!] impossible to connect to syslog: {:?}", e),
            Ok(writer) => {
                let r = writer.send(severity, msg);
                if r.is_err() {
                    println!("[!] error sending the log {}", r.err().expect("got error"));
                }
            }
        }
    }
}

#[allow(dead_code)]
mod test_calls {
    use super::Severity;
    use std::mem;

    pub static mut FUNC_USED: u8 = 0;
    pub static mut SEVERITY_TRANSMUTED: u8 = 255;

    pub fn stdout_log(severity: Severity, msg: &str) -> () {
        unsafe {
            let ordinal: u8 = mem::transmute(severity);
            FUNC_USED = 1;
            SEVERITY_TRANSMUTED = ordinal;
            println!("stdout_log({}, {})", ordinal, msg);
        }
    }

    pub fn syslog_log(severity: Severity, msg: &str) -> () {
        unsafe {
            let ordinal: u8 = mem::transmute(severity);
            FUNC_USED = 2;
            SEVERITY_TRANSMUTED = ordinal;
            println!("syslog_log({}, {})", ordinal, msg);
        }
    }
}

#[cfg(test)]
mod tests {
    use super::{Logger, LogDest};
    use super::{Severity};

    #[test]
    fn test_stdout_match() {
        let l = Logger::new(LogDest::StdOut);
        l.log(Severity::LOG_EMERG, "foo");
        unsafe {
            assert_eq! (1, super::test_calls::FUNC_USED);
            assert_eq! (0, super::test_calls::SEVERITY_TRANSMUTED);
        }
    }

    #[test]
    fn test_syslog_match() {
        let l = Logger::new(LogDest::Syslog);
        l.log(Severity::LOG_ALERT, "foo");
        unsafe {
            assert_eq! (2, super::test_calls::FUNC_USED);
            assert_eq! (1, super::test_calls::SEVERITY_TRANSMUTED);
        }
    }
}<commit_msg>pointless test removed<commit_after>pub extern crate syslog;
extern crate ansi_term;

use self::syslog::Facility;
pub use self::syslog::Severity;
use self::ansi_term::Colour::{Red, Yellow, White, Green, Cyan, Blue};

#[derive(Debug, PartialEq, Clone)]
pub enum LogDest {
    StdOut,
    Syslog,
}

#[derive(Debug, Clone)]
pub struct Logger {
    dest: LogDest
}

impl Logger {
    pub fn new(dest: LogDest) -> Logger {
        Logger { dest: dest }
    }

    pub fn log(&self, severity: Severity, msg: &str) -> () {
        match self.dest {
            LogDest::StdOut => {
                match severity {
                    Severity::LOG_EMERG => {
                        println!("<0> {}", Cyan.paint(msg));
                    }
                    Severity::LOG_ALERT => {
                        println!("<1> {}", Red.paint(msg));
                    }
                    Severity::LOG_CRIT => {
                        println!("<2> {}", Red.paint(msg));
                    }
                    Severity::LOG_ERR => {
                        println!("<3> {}", Red.paint(msg));
                    }
                    Severity::LOG_WARNING => {
                        println!("<4> {}", Yellow.paint(msg));
                    }
                    Severity::LOG_NOTICE => {
                        println!("<5> {}", Blue.paint(msg));
                    }
                    Severity::LOG_INFO => {
                        println!("<6> {}", White.paint(msg));
                    }
                    Severity::LOG_DEBUG => {
                        println!("<7> {}", Green.paint(msg));
                    }
                }
            }
            LogDest::Syslog => {
                match syslog::unix(Facility::LOG_DAEMON) {
                    Err(e) => println!("[!] impossible to connect to syslog: {:?}", e),
                    Ok(writer) => {
                        let r = writer.send(severity, msg);
                        if r.is_err() {
                            println!("[!] error sending the log {}", r.err().expect("got error"));
                        }
                    }
                }
            }
        }
    }
}<|endoftext|>


<commit_before>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Rank/Select data structure based on Gonzalez, Grabowski, Mäkinen, Navarro (2005).
//! This implementation uses only a single level of blocks, and performs well for large n.
//!
//! Example
//!
//! ```
//! extern crate bit_vec;
//! # extern crate bio;
//! # fn main() {
//! use bio::data_structures::rank_select::RankSelect;
//! use bit_vec::BitVec;
//!
//! let mut bits = BitVec::from_elem(64, false);
//! bits.set(5, true);
//! bits.set(32, true);
//! let rs = RankSelect::new(bits, 1);
//! assert!(rs.rank(1).unwrap() == 0);
//! assert!(rs.rank(5).unwrap() == 1);
//! assert!(rs.rank(6).unwrap() == 1);
//! assert!(rs.rank(32).unwrap() == 2);
//! assert!(rs.rank(33).unwrap() == 2);
//! assert!(rs.rank(64) == None);
//!
//! assert!(rs.select(0).unwrap() == 0);
//! assert!(rs.select(1).unwrap() == 5);
//! # }
//! ```

use bit_vec::BitVec;

/// A rank/select data structure.
#[cfg_attr(feature = "serde_macros", derive(Serialize, Deserialize))]
pub struct RankSelect {
    n: usize,
    bits: Vec<u8>,
    superblocks: Vec<u32>,
    s: usize,
}

impl RankSelect {
    /// Create a new instance.
    ///
    /// # Arguments
    ///
    /// * `bits` - A bit vector.
    /// * `k` - Determines the size (k * 32 bits) of the superblocks.
    ///   A small k means faster rank query times at the expense of using more
    ///   space and slower select query times.
    ///   The data structure needs O(n + n log n / (k * 32)) bits with n being the bits of the given bitvector.
    ///   The data structure is succinct if k is chosen as a sublinear function of n
    ///   (e.g. k = (log n)² / 32).
    pub fn new(bits: BitVec, k: usize) -> RankSelect {
        let n = bits.len();
        let raw = bits.to_bytes();
        let s = k * 32;

        RankSelect {
            n: n,
            s: s,
            superblocks: superblocks(n, s, &raw),
            bits: raw,
        }
    }

    /// Get the rank of a given bit, i.e. the number of 1-bits in the bitvector up to i (inclusive).
    /// Complexity: O(k).
    ///
    /// # Arguments
    ///
    /// * `i` - Position of the bit to determine the rank for.
    pub fn rank(&self, i: usize) -> Option<u32> {
        if i >= self.n {
            None
        } else {
            let s = i / self.s; // the superblock
            let b = i / 8; // the block
            // take the superblock rank
            let mut rank = self.superblocks[s];
            // add the rank within the block
            rank += (self.bits[b] >> (7 - i % 8)).count_ones();
            // add the popcounts of blocks in between
            rank += self.bits[s * 32 / 8..b]
                        .iter()
                        .map(|&a| a.count_ones())
                        .fold(0, |a, b| a + b);

            Some(rank)
        }
    }

    /// Get the smallest bit with a given rank.
    /// Complexity: O(log (n / k) + k).
    ///
    /// # Arguments
    ///
    /// * `j` - The rank to find the smallest bit for.
    pub fn select(&self, j: u32) -> Option<usize> {
        let mut superblock = match self.superblocks.binary_search(&j) {
            Ok(i) | Err(i) => i, // superblock with same rank exists
        };
        if superblock > 0 {
            superblock -= 1;
        }
        let mut rank = self.superblocks[superblock];

        let first_block = superblock * self.s / 8;
        for (block, &b) in self.bits[first_block..].iter().enumerate() {
            let p = b.count_ones();
            if rank + p >= j {
                let mut bit = 0b10000000;
                for i in 0..8usize {
                    rank += (b & bit > 0) as u32;
                    if rank == j {
                        return Some((first_block + block) * 8 + i);
                    }
                    bit >>= 1;
                }
            }
            rank += p;
        }

        None
    }
}

/// Create `n` superblocks of size `s` from a given bitvector.
fn superblocks(n: usize, s: usize, raw_bits: &[u8]) -> Vec<u32> {
    let mut superblocks = Vec::with_capacity(n / s + 1);
    let mut rank: u32 = 0;
    let mut i = 0;
    for &b in raw_bits.iter() {
        if i % s == 0 {
            superblocks.push(rank);
        }
        rank += b.count_ones();
        i += 8;
    }

    superblocks
}

#[cfg(tests)]
mod tests {
    use super::*;
    use bit_vec::BitVec;

    #[test]
    fn test_rank_select() {
        let mut bits = BitVec::from_elem(64, false);
        bits.set(5, true);
        bits.set(32, true);
        let rs = RankSelect::new(bits, 1);
        assert!(rs.rank(1).unwrap() == 0);
        assert!(rs.rank(5).unwrap() == 1);
        assert!(rs.rank(6).unwrap() == 1);
        assert!(rs.rank(32).unwrap() == 2);
        assert!(rs.rank(33).unwrap() == 2);
        assert!(rs.rank(64) == None);
        assert!(rs.select(0).unwrap() == 0);
        assert!(rs.select(1).unwrap() == 5);
    }

    #[test]
    #[cfg(feature = "nightly")]
    fn test_serde() {
        use serde::{Serialize, Deserialize};
        fn impls_serde_traits<S: Serialize + Deserialize>() {}

        impls_serde_traits::<RankSelect>();
    }
}
<commit_msg>Cleanup example.<commit_after>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Rank/Select data structure based on Gonzalez, Grabowski, Mäkinen, Navarro (2005).
//! This implementation uses only a single level of blocks, and performs well for large n.
//!
//! Example
//!
//! ```
//! extern crate bit_vec;
//! # extern crate bio;
//! # fn main() {
//! use bio::data_structures::rank_select::RankSelect;
//! use bit_vec::BitVec;
//!
//! let mut bits = BitVec::from_elem(64, false);
//! bits.set(5, true);
//! bits.set(32, true);
//! let rs = RankSelect::new(bits, 1);
//! assert!(rs.rank(6).unwrap() == 1);
//! # }
//! ```

use bit_vec::BitVec;

/// A rank/select data structure.
#[cfg_attr(feature = "serde_macros", derive(Serialize, Deserialize))]
pub struct RankSelect {
    n: usize,
    bits: Vec<u8>,
    superblocks: Vec<u32>,
    s: usize,
}

impl RankSelect {
    /// Create a new instance.
    ///
    /// # Arguments
    ///
    /// * `bits` - A bit vector.
    /// * `k` - Determines the size (k * 32 bits) of the superblocks.
    ///   A small k means faster rank query times at the expense of using more
    ///   space and slower select query times.
    ///   The data structure needs O(n + n log n / (k * 32)) bits with n being the bits of the given bitvector.
    ///   The data structure is succinct if k is chosen as a sublinear function of n
    ///   (e.g. k = (log n)² / 32).
    pub fn new(bits: BitVec, k: usize) -> RankSelect {
        let n = bits.len();
        let raw = bits.to_bytes();
        let s = k * 32;

        RankSelect {
            n: n,
            s: s,
            superblocks: superblocks(n, s, &raw),
            bits: raw,
        }
    }

    /// Get the rank of a given bit, i.e. the number of 1-bits in the bitvector up to i (inclusive).
    /// Complexity: O(k).
    ///
    /// # Arguments
    ///
    /// * `i` - Position of the bit to determine the rank for.
    pub fn rank(&self, i: usize) -> Option<u32> {
        if i >= self.n {
            None
        } else {
            let s = i / self.s; // the superblock
            let b = i / 8; // the block
            // take the superblock rank
            let mut rank = self.superblocks[s];
            // add the rank within the block
            rank += (self.bits[b] >> (7 - i % 8)).count_ones();
            // add the popcounts of blocks in between
            rank += self.bits[s * 32 / 8..b]
                        .iter()
                        .map(|&a| a.count_ones())
                        .fold(0, |a, b| a + b);

            Some(rank)
        }
    }

    /// Get the smallest bit with a given rank.
    /// Complexity: O(log (n / k) + k).
    ///
    /// # Arguments
    ///
    /// * `j` - The rank to find the smallest bit for.
    pub fn select(&self, j: u32) -> Option<usize> {
        let mut superblock = match self.superblocks.binary_search(&j) {
            Ok(i) | Err(i) => i, // superblock with same rank exists
        };
        if superblock > 0 {
            superblock -= 1;
        }
        let mut rank = self.superblocks[superblock];

        let first_block = superblock * self.s / 8;
        for (block, &b) in self.bits[first_block..].iter().enumerate() {
            let p = b.count_ones();
            if rank + p >= j {
                let mut bit = 0b10000000;
                for i in 0..8usize {
                    rank += (b & bit > 0) as u32;
                    if rank == j {
                        return Some((first_block + block) * 8 + i);
                    }
                    bit >>= 1;
                }
            }
            rank += p;
        }

        None
    }
}

/// Create `n` superblocks of size `s` from a given bitvector.
fn superblocks(n: usize, s: usize, raw_bits: &[u8]) -> Vec<u32> {
    let mut superblocks = Vec::with_capacity(n / s + 1);
    let mut rank: u32 = 0;
    let mut i = 0;
    for &b in raw_bits.iter() {
        if i % s == 0 {
            superblocks.push(rank);
        }
        rank += b.count_ones();
        i += 8;
    }

    superblocks
}

#[cfg(tests)]
mod tests {
    use super::*;
    use bit_vec::BitVec;

    #[test]
    fn test_rank_select() {
        let mut bits = BitVec::from_elem(64, false);
        bits.set(5, true);
        bits.set(32, true);
        let rs = RankSelect::new(bits, 1);
        assert!(rs.rank(1).unwrap() == 0);
        assert!(rs.rank(5).unwrap() == 1);
        assert!(rs.rank(6).unwrap() == 1);
        assert!(rs.rank(32).unwrap() == 2);
        assert!(rs.rank(33).unwrap() == 2);
        assert!(rs.rank(64) == None);
        assert!(rs.select(0).unwrap() == 0);
        assert!(rs.select(1).unwrap() == 5);
    }

    #[test]
    #[cfg(feature = "nightly")]
    fn test_serde() {
        use serde::{Serialize, Deserialize};
        fn impls_serde_traits<S: Serialize + Deserialize>() {}

        impls_serde_traits::<RankSelect>();
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Converting decimal strings into IEEE 754 binary floating point numbers.
//!
//! # Problem statement
//!
//! We are given a decimal string such as `12.34e56`. This string consists of integral (`12`),
//! fractional (`45`), and exponent (`56`) parts. All parts are optional and interpreted as zero
//! when missing.
//!
//! We seek the IEEE 754 floating point number that is closest to the exact value of the decimal
//! string. It is well-known that many decimal strings do not have terminating representations in
//! base two, so we round to 0.5 units in the last place (in other words, as well as possible).
//! Ties, decimal values exactly half-way between two consecutive floats, are resolved with the
//! half-to-even strategy, also known as banker's rounding.
//!
//! Needless to say, this is quite hard, both in terms of implementation complexity and in terms
//! of CPU cycles taken.
//!
//! # Implementation
//!
//! First, we ignore signs. Or rather, we remove it at the very beginning of the conversion
//! process and re-apply it at the very end. This is correct in all edge cases since IEEE
//! floats are symmetric around zero, negating one simply flips the first bit.
//!
//! Then we remove the decimal point by adjusting the exponent: Conceptually, `12.34e56` turns
//! into `1234e54`, which we describe with a positive integer `f = 1234` and an integer `e = 54`.
//! The `(f, e)` representation is used by almost all code past the parsing stage.
//!
//! We then try a long chain of progressively more general and expensive special cases using
//! machine-sized integers and small, fixed-sized floating point numbers (first `f32`/`f64`, then
//! a type with 64 bit significand, `Fp`). When all these fail, we bite the bullet and resort to a
//! simple but very slow algorithm that involved computing `f * 10^e` fully and doing an iterative
//! search for the best approximation.
//!
//! Primarily, this module and its children implement the algorithms described in:
//! "How to Read Floating Point Numbers Accurately" by William D. Clinger,
//! available online: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.4152
//!
//! In addition, there are numerous helper functions that are used in the paper but not available
//! in Rust (or at least in core). Our version is additionally complicated by the need to handle
//! overflow and underflow and the desire to handle subnormal numbers.  Bellerophon and
//! Algorithm R have trouble with overflow, subnormals, and underflow. We conservatively switch to
//! Algorithm M (with the modifications described in section 8 of the paper) well before the
//! inputs get into the critical region.
//!
//! Another aspect that needs attention is the ``RawFloat`` trait by which almost all functions
//! are parametrized. One might think that it's enough to parse to `f64` and cast the result to
//! `f32`. Unfortunately this is not the world we live in, and this has nothing to do with using
//! base two or half-to-even rounding.
//!
//! Consider for example two types `d2` and `d4` representing a decimal type with two decimal
//! digits and four decimal digits each and take "0.01499" as input. Let's use half-up rounding.
//! Going directly to two decimal digits gives `0.01`, but if we round to four digits first,
//! we get `0.0150`, which is then rounded up to `0.02`. The same principle applies to other
//! operations as well, if you want 0.5 ULP accuracy you need to do *everything* in full precision
//! and round *exactly once, at the end*, by considering all truncated bits at once.
//!
//! FIXME Although some code duplication is necessary, perhaps parts of the code could be shuffled
//! around such that less code is duplicated. Large parts of the algorithms are independent of the
//! float type to output, or only needs access to a few constants, which could be passed in as
//! parameters.
//!
//! # Other
//!
//! The conversion should *never* panic. There are assertions and explicit panics in the code,
//! but they should never be triggered and only serve as internal sanity checks. Any panics should
//! be considered a bug.
//!
//! There are unit tests but they are woefully inadequate at ensuring correctness, they only cover
//! a small percentage of possible errors. Far more extensive tests are located in the directory
//! `src/etc/test-float-parse` as a Python script.
//!
//! A note on integer overflow: Many parts of this file perform arithmetic with the decimal
//! exponent `e`. Primarily, we shift the decimal point around: Before the first decimal digit,
//! after the last decimal digit, and so on. This could overflow if done carelessly. We rely on
//! the parsing submodule to only hand out sufficiently small exponents, where "sufficient" means
//! "such that the exponent +/- the number of decimal digits fits into a 64 bit integer".
//! Larger exponents are accepted, but we don't do arithmetic with them, they are immediately
//! turned into {positive,negative} {zero,infinity}.

#![doc(hidden)]
#![unstable(feature = "dec2flt",
            reason = "internal routines only exposed for testing",
            issue = "0")]

use prelude::v1::*;
use fmt;
use str::FromStr;

use self::parse::{parse_decimal, Decimal, Sign};
use self::parse::ParseResult::{Valid, Invalid, ShortcutToInf, ShortcutToZero};
use self::num::digits_to_big;
use self::rawfp::RawFloat;

mod algorithm;
mod table;
mod num;
// These two have their own tests.
pub mod rawfp;
pub mod parse;

macro_rules! from_str_float_impl {
    ($t:ty) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl FromStr for $t {
            type Err = ParseFloatError;

            /// Converts a string in base 10 to a float.
            /// Accepts an optional decimal exponent.
            ///
            /// This function accepts strings such as
            ///
            /// * '3.14'
            /// * '-3.14'
            /// * '2.5E10', or equivalently, '2.5e10'
            /// * '2.5E-10'
            /// * '.' (understood as 0)
            /// * '5.'
            /// * '.5', or, equivalently,  '0.5'
            /// * 'inf', '-inf', 'NaN'
            ///
            /// Leading and trailing whitespace represent an error.
            ///
            /// # Arguments
            ///
            /// * src - A string
            ///
            /// # Return value
            ///
            /// `Err(ParseFloatError)` if the string did not represent a valid
            /// number.  Otherwise, `Ok(n)` where `n` is the floating-point
            /// number represented by `src`.
            #[inline]
            fn from_str(src: &str) -> Result<Self, ParseFloatError> {
                dec2flt(src)
            }
        }
    }
}
from_str_float_impl!(f32);
from_str_float_impl!(f64);

/// An error which can be returned when parsing a float.
#[derive(Debug, Clone, PartialEq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseFloatError {
    kind: FloatErrorKind
}

#[derive(Debug, Clone, PartialEq)]
enum FloatErrorKind {
    Empty,
    Invalid,
}

impl ParseFloatError {
    #[unstable(feature = "int_error_internals",
               reason = "available through Error trait and this method should \
                         not be exposed publicly",
               issue = "0")]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            FloatErrorKind::Empty => "cannot parse float from empty string",
            FloatErrorKind::Invalid => "invalid float literal",
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for ParseFloatError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.__description().fmt(f)
    }
}

fn pfe_empty() -> ParseFloatError {
    ParseFloatError { kind: FloatErrorKind::Empty }
}

fn pfe_invalid() -> ParseFloatError {
    ParseFloatError { kind: FloatErrorKind::Invalid }
}

/// Split decimal string into sign and the rest, without inspecting or validating the rest.
fn extract_sign(s: &str) -> (Sign, &str) {
    match s.as_bytes()[0] {
        b'+' => (Sign::Positive, &s[1..]),
        b'-' => (Sign::Negative, &s[1..]),
        // If the string is invalid, we never use the sign, so we don't need to validate here.
        _ => (Sign::Positive, s),
    }
}

/// Convert a decimal string into a floating point number.
fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
    if s.is_empty() {
        return Err(pfe_empty())
    }
    let (sign, s) = extract_sign(s);
    let flt = match parse_decimal(s) {
        Valid(decimal) => try!(convert(decimal)),
        ShortcutToInf => T::infinity(),
        ShortcutToZero => T::zero(),
        Invalid => match s {
            "inf" => T::infinity(),
            "NaN" => T::nan(),
            _ => { return Err(pfe_invalid()); }
        }
    };

    match sign {
        Sign::Positive => Ok(flt),
        Sign::Negative => Ok(-flt),
    }
}

/// The main workhorse for the decimal-to-float conversion: Orchestrate all the preprocessing
/// and figure out which algorithm should do the actual conversion.
fn convert<T: RawFloat>(mut decimal: Decimal) -> Result<T, ParseFloatError> {
    simplify(&mut decimal);
    if let Some(x) = trivial_cases(&decimal) {
        return Ok(x);
    }
    // AlgorithmM and AlgorithmR both compute approximately `f * 10^e`.
    let max_digits = decimal.integral.len() + decimal.fractional.len() +
                     decimal.exp.abs() as usize;
    // Remove/shift out the decimal point.
    let e = decimal.exp - decimal.fractional.len() as i64;
    if let Some(x) = algorithm::fast_path(decimal.integral, decimal.fractional, e) {
        return Ok(x);
    }
    // Big32x40 is limited to 1280 bits, which translates to about 385 decimal digits.
    // If we exceed this, perhaps while calculating `f * 10^e` in Algorithm R or Algorithm M,
    // we'll crash. So we error out before getting too close, with a generous safety margin.
    if max_digits > 375 {
        return Err(pfe_invalid());
    }
    let f = digits_to_big(decimal.integral, decimal.fractional);

    // Now the exponent certainly fits in 16 bit, which is used throughout the main algorithms.
    let e = e as i16;
    // FIXME These bounds are rather conservative. A more careful analysis of the failure modes
    // of Bellerophon could allow using it in more cases for a massive speed up.
    let exponent_in_range = table::MIN_E <= e && e <= table::MAX_E;
    let value_in_range = max_digits <= T::max_normal_digits();
    if exponent_in_range && value_in_range {
        Ok(algorithm::bellerophon(&f, e))
    } else {
        Ok(algorithm::algorithm_m(&f, e))
    }
}

// As written, this optimizes badly (see #27130, though it refers to an old version of the code).
// `inline(always)` is a workaround for that. There are only two call sites overall and it doesn't
// make code size worse.

/// Strip zeros where possible, even when this requires changing the exponent
#[inline(always)]
fn simplify(decimal: &mut Decimal) {
    let is_zero = &|&&d: &&u8| -> bool { d == b'0' };
    // Trimming these zeros does not change anything but may enable the fast path (< 15 digits).
    let leading_zeros = decimal.integral.iter().take_while(is_zero).count();
    decimal.integral = &decimal.integral[leading_zeros..];
    let trailing_zeros = decimal.fractional.iter().rev().take_while(is_zero).count();
    let end = decimal.fractional.len() - trailing_zeros;
    decimal.fractional = &decimal.fractional[..end];
    // Simplify numbers of the form 0.0...x and x...0.0, adjusting the exponent accordingly.
    // This may not always be a win (possibly pushes some numbers out of the fast path), but it
    // simplifies other parts significantly (notably, approximating the magnitude of the value).
    if decimal.integral.is_empty() {
        let leading_zeros = decimal.fractional.iter().take_while(is_zero).count();
        decimal.fractional = &decimal.fractional[leading_zeros..];
        decimal.exp -= leading_zeros as i64;
    } else if decimal.fractional.is_empty() {
        let trailing_zeros = decimal.integral.iter().rev().take_while(is_zero).count();
        let end = decimal.integral.len() - trailing_zeros;
        decimal.integral = &decimal.integral[..end];
        decimal.exp += trailing_zeros as i64;
    }
}

/// Detect obvious overflows and underflows without even looking at the decimal digits.
fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
    // There were zeros but they were stripped by simplify()
    if decimal.integral.is_empty() && decimal.fractional.is_empty() {
        return Some(T::zero());
    }
    // This is a crude approximation of ceil(log10(the real value)).
    let max_place = decimal.exp + decimal.integral.len() as i64;
    if max_place > T::inf_cutoff() {
        return Some(T::infinity());
    } else if max_place < T::zero_cutoff() {
        return Some(T::zero());
    }
    None
}
<commit_msg>Auto merge of #30435 - Ms2ger:ParseResult, r=alexcrichton<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Converting decimal strings into IEEE 754 binary floating point numbers.
//!
//! # Problem statement
//!
//! We are given a decimal string such as `12.34e56`. This string consists of integral (`12`),
//! fractional (`45`), and exponent (`56`) parts. All parts are optional and interpreted as zero
//! when missing.
//!
//! We seek the IEEE 754 floating point number that is closest to the exact value of the decimal
//! string. It is well-known that many decimal strings do not have terminating representations in
//! base two, so we round to 0.5 units in the last place (in other words, as well as possible).
//! Ties, decimal values exactly half-way between two consecutive floats, are resolved with the
//! half-to-even strategy, also known as banker's rounding.
//!
//! Needless to say, this is quite hard, both in terms of implementation complexity and in terms
//! of CPU cycles taken.
//!
//! # Implementation
//!
//! First, we ignore signs. Or rather, we remove it at the very beginning of the conversion
//! process and re-apply it at the very end. This is correct in all edge cases since IEEE
//! floats are symmetric around zero, negating one simply flips the first bit.
//!
//! Then we remove the decimal point by adjusting the exponent: Conceptually, `12.34e56` turns
//! into `1234e54`, which we describe with a positive integer `f = 1234` and an integer `e = 54`.
//! The `(f, e)` representation is used by almost all code past the parsing stage.
//!
//! We then try a long chain of progressively more general and expensive special cases using
//! machine-sized integers and small, fixed-sized floating point numbers (first `f32`/`f64`, then
//! a type with 64 bit significand, `Fp`). When all these fail, we bite the bullet and resort to a
//! simple but very slow algorithm that involved computing `f * 10^e` fully and doing an iterative
//! search for the best approximation.
//!
//! Primarily, this module and its children implement the algorithms described in:
//! "How to Read Floating Point Numbers Accurately" by William D. Clinger,
//! available online: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.45.4152
//!
//! In addition, there are numerous helper functions that are used in the paper but not available
//! in Rust (or at least in core). Our version is additionally complicated by the need to handle
//! overflow and underflow and the desire to handle subnormal numbers.  Bellerophon and
//! Algorithm R have trouble with overflow, subnormals, and underflow. We conservatively switch to
//! Algorithm M (with the modifications described in section 8 of the paper) well before the
//! inputs get into the critical region.
//!
//! Another aspect that needs attention is the ``RawFloat`` trait by which almost all functions
//! are parametrized. One might think that it's enough to parse to `f64` and cast the result to
//! `f32`. Unfortunately this is not the world we live in, and this has nothing to do with using
//! base two or half-to-even rounding.
//!
//! Consider for example two types `d2` and `d4` representing a decimal type with two decimal
//! digits and four decimal digits each and take "0.01499" as input. Let's use half-up rounding.
//! Going directly to two decimal digits gives `0.01`, but if we round to four digits first,
//! we get `0.0150`, which is then rounded up to `0.02`. The same principle applies to other
//! operations as well, if you want 0.5 ULP accuracy you need to do *everything* in full precision
//! and round *exactly once, at the end*, by considering all truncated bits at once.
//!
//! FIXME Although some code duplication is necessary, perhaps parts of the code could be shuffled
//! around such that less code is duplicated. Large parts of the algorithms are independent of the
//! float type to output, or only needs access to a few constants, which could be passed in as
//! parameters.
//!
//! # Other
//!
//! The conversion should *never* panic. There are assertions and explicit panics in the code,
//! but they should never be triggered and only serve as internal sanity checks. Any panics should
//! be considered a bug.
//!
//! There are unit tests but they are woefully inadequate at ensuring correctness, they only cover
//! a small percentage of possible errors. Far more extensive tests are located in the directory
//! `src/etc/test-float-parse` as a Python script.
//!
//! A note on integer overflow: Many parts of this file perform arithmetic with the decimal
//! exponent `e`. Primarily, we shift the decimal point around: Before the first decimal digit,
//! after the last decimal digit, and so on. This could overflow if done carelessly. We rely on
//! the parsing submodule to only hand out sufficiently small exponents, where "sufficient" means
//! "such that the exponent +/- the number of decimal digits fits into a 64 bit integer".
//! Larger exponents are accepted, but we don't do arithmetic with them, they are immediately
//! turned into {positive,negative} {zero,infinity}.

#![doc(hidden)]
#![unstable(feature = "dec2flt",
            reason = "internal routines only exposed for testing",
            issue = "0")]

use prelude::v1::*;
use fmt;
use str::FromStr;

use self::parse::{parse_decimal, Decimal, Sign, ParseResult};
use self::num::digits_to_big;
use self::rawfp::RawFloat;

mod algorithm;
mod table;
mod num;
// These two have their own tests.
pub mod rawfp;
pub mod parse;

macro_rules! from_str_float_impl {
    ($t:ty) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl FromStr for $t {
            type Err = ParseFloatError;

            /// Converts a string in base 10 to a float.
            /// Accepts an optional decimal exponent.
            ///
            /// This function accepts strings such as
            ///
            /// * '3.14'
            /// * '-3.14'
            /// * '2.5E10', or equivalently, '2.5e10'
            /// * '2.5E-10'
            /// * '.' (understood as 0)
            /// * '5.'
            /// * '.5', or, equivalently,  '0.5'
            /// * 'inf', '-inf', 'NaN'
            ///
            /// Leading and trailing whitespace represent an error.
            ///
            /// # Arguments
            ///
            /// * src - A string
            ///
            /// # Return value
            ///
            /// `Err(ParseFloatError)` if the string did not represent a valid
            /// number.  Otherwise, `Ok(n)` where `n` is the floating-point
            /// number represented by `src`.
            #[inline]
            fn from_str(src: &str) -> Result<Self, ParseFloatError> {
                dec2flt(src)
            }
        }
    }
}
from_str_float_impl!(f32);
from_str_float_impl!(f64);

/// An error which can be returned when parsing a float.
#[derive(Debug, Clone, PartialEq)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct ParseFloatError {
    kind: FloatErrorKind
}

#[derive(Debug, Clone, PartialEq)]
enum FloatErrorKind {
    Empty,
    Invalid,
}

impl ParseFloatError {
    #[unstable(feature = "int_error_internals",
               reason = "available through Error trait and this method should \
                         not be exposed publicly",
               issue = "0")]
    #[doc(hidden)]
    pub fn __description(&self) -> &str {
        match self.kind {
            FloatErrorKind::Empty => "cannot parse float from empty string",
            FloatErrorKind::Invalid => "invalid float literal",
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for ParseFloatError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.__description().fmt(f)
    }
}

fn pfe_empty() -> ParseFloatError {
    ParseFloatError { kind: FloatErrorKind::Empty }
}

fn pfe_invalid() -> ParseFloatError {
    ParseFloatError { kind: FloatErrorKind::Invalid }
}

/// Split decimal string into sign and the rest, without inspecting or validating the rest.
fn extract_sign(s: &str) -> (Sign, &str) {
    match s.as_bytes()[0] {
        b'+' => (Sign::Positive, &s[1..]),
        b'-' => (Sign::Negative, &s[1..]),
        // If the string is invalid, we never use the sign, so we don't need to validate here.
        _ => (Sign::Positive, s),
    }
}

/// Convert a decimal string into a floating point number.
fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
    if s.is_empty() {
        return Err(pfe_empty())
    }
    let (sign, s) = extract_sign(s);
    let flt = match parse_decimal(s) {
        ParseResult::Valid(decimal) => try!(convert(decimal)),
        ParseResult::ShortcutToInf => T::infinity(),
        ParseResult::ShortcutToZero => T::zero(),
        ParseResult::Invalid => match s {
            "inf" => T::infinity(),
            "NaN" => T::nan(),
            _ => { return Err(pfe_invalid()); }
        }
    };

    match sign {
        Sign::Positive => Ok(flt),
        Sign::Negative => Ok(-flt),
    }
}

/// The main workhorse for the decimal-to-float conversion: Orchestrate all the preprocessing
/// and figure out which algorithm should do the actual conversion.
fn convert<T: RawFloat>(mut decimal: Decimal) -> Result<T, ParseFloatError> {
    simplify(&mut decimal);
    if let Some(x) = trivial_cases(&decimal) {
        return Ok(x);
    }
    // AlgorithmM and AlgorithmR both compute approximately `f * 10^e`.
    let max_digits = decimal.integral.len() + decimal.fractional.len() +
                     decimal.exp.abs() as usize;
    // Remove/shift out the decimal point.
    let e = decimal.exp - decimal.fractional.len() as i64;
    if let Some(x) = algorithm::fast_path(decimal.integral, decimal.fractional, e) {
        return Ok(x);
    }
    // Big32x40 is limited to 1280 bits, which translates to about 385 decimal digits.
    // If we exceed this, perhaps while calculating `f * 10^e` in Algorithm R or Algorithm M,
    // we'll crash. So we error out before getting too close, with a generous safety margin.
    if max_digits > 375 {
        return Err(pfe_invalid());
    }
    let f = digits_to_big(decimal.integral, decimal.fractional);

    // Now the exponent certainly fits in 16 bit, which is used throughout the main algorithms.
    let e = e as i16;
    // FIXME These bounds are rather conservative. A more careful analysis of the failure modes
    // of Bellerophon could allow using it in more cases for a massive speed up.
    let exponent_in_range = table::MIN_E <= e && e <= table::MAX_E;
    let value_in_range = max_digits <= T::max_normal_digits();
    if exponent_in_range && value_in_range {
        Ok(algorithm::bellerophon(&f, e))
    } else {
        Ok(algorithm::algorithm_m(&f, e))
    }
}

// As written, this optimizes badly (see #27130, though it refers to an old version of the code).
// `inline(always)` is a workaround for that. There are only two call sites overall and it doesn't
// make code size worse.

/// Strip zeros where possible, even when this requires changing the exponent
#[inline(always)]
fn simplify(decimal: &mut Decimal) {
    let is_zero = &|&&d: &&u8| -> bool { d == b'0' };
    // Trimming these zeros does not change anything but may enable the fast path (< 15 digits).
    let leading_zeros = decimal.integral.iter().take_while(is_zero).count();
    decimal.integral = &decimal.integral[leading_zeros..];
    let trailing_zeros = decimal.fractional.iter().rev().take_while(is_zero).count();
    let end = decimal.fractional.len() - trailing_zeros;
    decimal.fractional = &decimal.fractional[..end];
    // Simplify numbers of the form 0.0...x and x...0.0, adjusting the exponent accordingly.
    // This may not always be a win (possibly pushes some numbers out of the fast path), but it
    // simplifies other parts significantly (notably, approximating the magnitude of the value).
    if decimal.integral.is_empty() {
        let leading_zeros = decimal.fractional.iter().take_while(is_zero).count();
        decimal.fractional = &decimal.fractional[leading_zeros..];
        decimal.exp -= leading_zeros as i64;
    } else if decimal.fractional.is_empty() {
        let trailing_zeros = decimal.integral.iter().rev().take_while(is_zero).count();
        let end = decimal.integral.len() - trailing_zeros;
        decimal.integral = &decimal.integral[..end];
        decimal.exp += trailing_zeros as i64;
    }
}

/// Detect obvious overflows and underflows without even looking at the decimal digits.
fn trivial_cases<T: RawFloat>(decimal: &Decimal) -> Option<T> {
    // There were zeros but they were stripped by simplify()
    if decimal.integral.is_empty() && decimal.fractional.is_empty() {
        return Some(T::zero());
    }
    // This is a crude approximation of ceil(log10(the real value)).
    let max_place = decimal.exp + decimal.integral.len() as i64;
    if max_place > T::inf_cutoff() {
        return Some(T::infinity());
    } else if max_place < T::zero_cutoff() {
        return Some(T::zero());
    }
    None
}
<|endoftext|>


<commit_before>use error::{RuntimeError, VoidResult};
use frame::GPUFrame;

use sys::wgl;

use super::display::WindowsDisplay;
use super::window::{WindowsWindow, PollEventsIterator};
use super::wgl_context::WglContext;

pub struct WindowsApplication {
   display: WindowsDisplay,
   window: WindowsWindow,
   #[allow(dead_code)] wgl: WglContext,
}

impl WindowsApplication {
   pub fn new(
      display: WindowsDisplay,
      title: &str,
      x: i32, y: i32,
      width: u32, height: u32
   ) -> Result<Self, RuntimeError> {

      let window = try!(WindowsWindow::new(title, x, y, width, height));

      let wgl = try!(WglContext::new(&window.device_context));

      Ok(WindowsApplication {
         display: display,
         window: window,
         wgl: wgl,
      })
   }

   #[inline]
   pub fn create_gpu_frame(
      &self, width: u32, height: u32
   ) -> Result<Box<GPUFrame>, RuntimeError> {
      self.wgl.create_gpu_frame(width, height)
   }

   #[inline]
   pub fn screen_size(&self) -> (u32, u32) {
      self.display.screen_size()
   }

   #[inline]
   pub fn poll_events(&self) -> PollEventsIterator {
      self.window.poll_events()
   }

   #[inline]
   pub fn swap_buffers(&self) -> VoidResult {
      wgl::swap_buffers(&self.window.device_context);
      Ok(())
   }
}
<commit_msg>Removing unused compiler warning supression<commit_after>use error::{RuntimeError, VoidResult};
use frame::GPUFrame;

use sys::wgl;

use super::display::WindowsDisplay;
use super::window::{WindowsWindow, PollEventsIterator};
use super::wgl_context::WglContext;

pub struct WindowsApplication {
   display: WindowsDisplay,
   window: WindowsWindow,
   wgl: WglContext,
}

impl WindowsApplication {
   pub fn new(
      display: WindowsDisplay,
      title: &str,
      x: i32, y: i32,
      width: u32, height: u32
   ) -> Result<Self, RuntimeError> {

      let window = try!(WindowsWindow::new(title, x, y, width, height));

      let wgl = try!(WglContext::new(&window.device_context));

      Ok(WindowsApplication {
         display: display,
         window: window,
         wgl: wgl,
      })
   }

   #[inline]
   pub fn create_gpu_frame(
      &self, width: u32, height: u32
   ) -> Result<Box<GPUFrame>, RuntimeError> {
      self.wgl.create_gpu_frame(width, height)
   }

   #[inline]
   pub fn screen_size(&self) -> (u32, u32) {
      self.display.screen_size()
   }

   #[inline]
   pub fn poll_events(&self) -> PollEventsIterator {
      self.window.poll_events()
   }

   #[inline]
   pub fn swap_buffers(&self) -> VoidResult {
      wgl::swap_buffers(&self.window.device_context);
      Ok(())
   }
}
<|endoftext|>


<commit_before>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Myers bit-parallel approximate pattern matching algorithm.
//! Finds all matches up to a given edit distance. The pattern has to fit into a bitvector,
//! and is here limited to 64 symbols.
//! Complexity: O(n)
//!
//! # Example
//!
//! ```
//! # extern crate itertools;
//! # extern crate bio;
//! use bio::pattern_matching::myers::Myers;
//! use itertools::Itertools;
//!
//! # fn main() {
//! let text = b"ACCGTGGATGAGCGCCATAG";
//! let pattern = b"TGAGCGT";
//!
//! let myers = Myers::new(pattern);
//! let occ = myers.find_all_end(text, 1).collect_vec();
//!
//! assert_eq!(occ, [(13, 1), (14, 1)]);
//! # }
//! ```

use std::iter;
use std::u64;

use utils::{TextSlice, IntoTextIterator, TextIterator};

/// Myers algorithm.
pub struct Myers {
    peq: [u64; 256],
    bound: u64,
    m: u8,
}

impl Myers {
    /// Create a new instance of Myers algorithm for a given pattern.
    pub fn new<'a, P: IntoTextIterator<'a>>(pattern: P) -> Self
        where P::IntoIter: ExactSizeIterator
    {
        let pattern = pattern.into_iter();
        let m = pattern.len();
        assert!(m <= 64 && m > 0);

        let mut peq = [0; 256];
        for (i, &a) in pattern.enumerate() {
            peq[a as usize] |= 1 << i;
        }

        Myers {
            peq: peq,
            bound: 1 << (m - 1),
            m: m as u8,
        }
    }

    /// Create a new instance of Myers algorithm for a given pattern and a wildcard character
    /// that shall match any character.
    pub fn with_wildcard(pattern: TextSlice, wildcard: u8) -> Self {
        let mut myers = Self::new(pattern);
        // wildcard matches all symbols of the pattern.
        myers.peq[wildcard as usize] = u64::MAX;

        myers
    }

    fn step(&self, state: &mut State, a: u8) {
        let eq = self.peq[a as usize];
        let xv = eq | state.mv;
        let xh = (((eq & state.pv) + state.pv) ^ state.pv) | eq;

        let mut ph = state.mv | !(xh | state.pv);
        let mut mh = state.pv & xh;

        if ph & self.bound > 0 {
            state.dist += 1;
        } else if mh & self.bound > 0 {
            state.dist -= 1;
        }

        ph <<= 1;
        mh <<= 1;
        state.pv = mh | !(xv | ph);
        state.mv = ph & xv;
    }

    /// Calculate the global distance of the pattern to the given text.
    pub fn distance<'a, I: IntoTextIterator<'a>>(&self, text: I) -> u8 {
        let mut state = State::new(self.m);
        for &a in text {
            self.step(&mut state, a);
        }
        state.dist
    }

    /// Find all matches of pattern in the given text up to a given maximum distance.
    /// Matches are returned as an iterator over pairs of end position and distance.
    pub fn find_all_end<'a, I: IntoTextIterator<'a>>(&'a self,
                                                     text: I,
                                                     max_dist: u8)
                                                     -> Matches<I::IntoIter> {
        Matches {
            myers: self,
            state: State::new(self.m),
            text: text.into_iter().enumerate(),
            max_dist: max_dist,
        }
    }
}

/// The current algorithm state.
struct State {
    pv: u64,
    mv: u64,
    dist: u8,
}

impl State {
    /// Create new state.
    pub fn new(m: u8) -> Self {
        State {
            pv: (1 << m) - 1,
            mv: 0,
            dist: m,
        }
    }
}

/// Iterator over pairs of end positions and distance of matches.
pub struct Matches<'a, I: TextIterator<'a>> {
    myers: &'a Myers,
    state: State,
    text: iter::Enumerate<I>,
    max_dist: u8,
}

impl<'a, I: Iterator<Item = &'a u8>> Iterator for Matches<'a, I> {
    type Item = (usize, u8);

    fn next(&mut self) -> Option<(usize, u8)> {
        for (i, &a) in self.text.by_ref() {
            self.myers.step(&mut self.state, a);
            if self.state.dist <= self.max_dist {
                return Some((i, self.state.dist));
            }
        }
        None
    }
}

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

    #[test]
    fn test_find_all_end() {
        let text = b"ACCGTGGATGAGCGCCATAG";
        let pattern = b"TGAGCGT";
        let myers = Myers::new(pattern);
        let occ = myers.find_all_end(text, 1).collect_vec();
        assert_eq!(occ, [(13, 1), (14, 1)]);
    }

    #[test]
    fn test_distance() {
        let text = b"TGAGCNT";
        let pattern = b"TGAGCGT";

        let myers = Myers::new(pattern);
        assert_eq!(myers.distance(text), 1);

        let myers_wildcard = Myers::with_wildcard(pattern, b'N');
        assert_eq!(myers_wildcard.distance(text), 0);
    }

}
<commit_msg>Add test case and fix overflow.<commit_after>// Copyright 2014-2016 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Myers bit-parallel approximate pattern matching algorithm.
//! Finds all matches up to a given edit distance. The pattern has to fit into a bitvector,
//! and is here limited to 64 symbols.
//! Complexity: O(n)
//!
//! # Example
//!
//! ```
//! # extern crate itertools;
//! # extern crate bio;
//! use bio::pattern_matching::myers::Myers;
//! use itertools::Itertools;
//!
//! # fn main() {
//! let text = b"ACCGTGGATGAGCGCCATAG";
//! let pattern = b"TGAGCGT";
//!
//! let myers = Myers::new(pattern);
//! let occ = myers.find_all_end(text, 1).collect_vec();
//!
//! assert_eq!(occ, [(13, 1), (14, 1)]);
//! # }
//! ```

use std::iter;
use std::u64;

use utils::{TextSlice, IntoTextIterator, TextIterator};

/// Myers algorithm.
pub struct Myers {
    peq: [u64; 256],
    bound: u64,
    m: u8,
}

impl Myers {
    /// Create a new instance of Myers algorithm for a given pattern.
    pub fn new<'a, P: IntoTextIterator<'a>>(pattern: P) -> Self
        where P::IntoIter: ExactSizeIterator
    {
        let pattern = pattern.into_iter();
        let m = pattern.len();
        assert!(m <= 64 && m > 0);

        let mut peq = [0; 256];
        for (i, &a) in pattern.enumerate() {
            peq[a as usize] |= 1 << i;
        }

        Myers {
            peq: peq,
            bound: 1 << (m - 1),
            m: m as u8,
        }
    }

    /// Create a new instance of Myers algorithm for a given pattern and a wildcard character
    /// that shall match any character.
    pub fn with_wildcard(pattern: TextSlice, wildcard: u8) -> Self {
        let mut myers = Self::new(pattern);
        // wildcard matches all symbols of the pattern.
        myers.peq[wildcard as usize] = u64::MAX;

        myers
    }

    fn step(&self, state: &mut State, a: u8) {
        let eq = self.peq[a as usize];
        let xv = eq | state.mv;
        let xh = (((eq & state.pv).saturating_add(state.pv)) ^ state.pv) | eq;

        let mut ph = state.mv | !(xh | state.pv);
        let mut mh = state.pv & xh;

        if ph & self.bound > 0 {
            state.dist += 1;
        } else if mh & self.bound > 0 {
            state.dist -= 1;
        }

        ph <<= 1;
        mh <<= 1;
        state.pv = mh | !(xv | ph);
        state.mv = ph & xv;
    }

    /// Calculate the global distance of the pattern to the given text.
    pub fn distance<'a, I: IntoTextIterator<'a>>(&self, text: I) -> u8 {
        let mut state = State::new(self.m);
        for &a in text {
            self.step(&mut state, a);
        }
        state.dist
    }

    /// Find all matches of pattern in the given text up to a given maximum distance.
    /// Matches are returned as an iterator over pairs of end position and distance.
    pub fn find_all_end<'a, I: IntoTextIterator<'a>>(&'a self,
                                                     text: I,
                                                     max_dist: u8)
                                                     -> Matches<I::IntoIter> {
        Matches {
            myers: self,
            state: State::new(self.m),
            text: text.into_iter().enumerate(),
            max_dist: max_dist,
        }
    }
}

/// The current algorithm state.
struct State {
    pv: u64,
    mv: u64,
    dist: u8,
}

impl State {
    /// Create new state.
    pub fn new(m: u8) -> Self {
        State {
            pv: (1 << m) - 1,
            mv: 0,
            dist: m,
        }
    }
}

/// Iterator over pairs of end positions and distance of matches.
pub struct Matches<'a, I: TextIterator<'a>> {
    myers: &'a Myers,
    state: State,
    text: iter::Enumerate<I>,
    max_dist: u8,
}

impl<'a, I: Iterator<Item = &'a u8>> Iterator for Matches<'a, I> {
    type Item = (usize, u8);

    fn next(&mut self) -> Option<(usize, u8)> {
        for (i, &a) in self.text.by_ref() {
            self.myers.step(&mut self.state, a);
            if self.state.dist <= self.max_dist {
                return Some((i, self.state.dist));
            }
        }
        None
    }
}

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

    #[test]
    fn test_find_all_end() {
        let text = b"ACCGTGGATGAGCGCCATAG";
        let pattern = b"TGAGCGT";
        let myers = Myers::new(pattern);
        let occ = myers.find_all_end(text, 1).collect_vec();
        assert_eq!(occ, [(13, 1), (14, 1)]);
    }

    #[test]
    fn test_distance() {
        let text = b"TGAGCNT";
        let pattern = b"TGAGCGT";

        let myers = Myers::new(pattern);
        assert_eq!(myers.distance(text), 1);

        let myers_wildcard = Myers::with_wildcard(pattern, b'N');
        assert_eq!(myers_wildcard.distance(text), 0);
    }

    #[test]
    fn test_long() {
        let text = b"ACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAGACCGTGGATGAGCGCCATAG";
        let pattern = b"TGAGCGTTGAGCGTTGAGCGTTGAGCGTTGAGCGTTGAGCGT";
        let myers = Myers::new(&pattern[..]);
        let occ = myers.find_all_end(&text[..], 1).collect_vec();
        println!("{:?}", occ);
    }
}
<|endoftext|>