text:
use astconv::AstConv;
use check::{FnCtxt, Inherited, blank_fn_ctxt, regionck};
use constrained_type_params::{identify_constrained_type_params, Parameter};
use CrateCtxt;
use middle::region;
use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
use middle::traits;
use middle::ty::{self, Ty};
use middle::ty::liberate_late_bound_regions;
use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
use util::ppaux::{Repr, UserString};

use std::collections::HashSet;
use syntax::ast;
use syntax::ast_util::local_def;
use syntax::codemap::Span;
use syntax::parse::token::{self, special_idents};
use syntax::visit;
use syntax::visit::Visitor;

pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> {
    ccx: &'ccx CrateCtxt<'ccx, 'tcx>,
    cache: HashSet<Ty<'tcx>>
}

impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
    pub fn new(ccx: &'ccx CrateCtxt<'ccx, 'tcx>) -> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
        CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() }
    }

    fn tcx(&self) -> &ty::ctxt<'tcx> {
        self.ccx.tcx
    }

    /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
    /// well-formed, meaning that they do not require any constraints not declared in the struct
    /// definition itself. For example, this definition would be illegal:
    ///
    ///     struct Ref<'a, T> { x: &'a T }
    ///
    /// because the type did not declare that `T:'a`.
    ///
    /// We do this check as a pre-pass before checking fn bodies because if these constraints are
    /// not included it frequently leads to confusing errors in fn bodies. So it's better to check
    /// the types first.
    fn check_item_well_formed(&mut self, item: &ast::Item) {
        let ccx = self.ccx;
        debug!("check_item_well_formed(it.id={}, it.ident={})",
               item.id,
               ty::item_path_str(ccx.tcx, local_def(item.id)));

        match item.node {
            /// Right now we check that every default trait implementation
            /// has an implementation of itself. Basically, a case like:
            ///
            /// `impl Trait for T {}`
            ///
            /// has a requirement of `T: Trait` which was required for default
            /// method implementations. Although this could be improved now that
            /// there's a better infrastructure in place for this, it's being left
            /// for a follow-up work.
            ///
            /// Since there's such a requirement, we need to check *just* positive
            /// implementations, otherwise things like:
            ///
            /// impl !Send for T {}
            ///
            /// won't be allowed unless there's an *explicit* implementation of `Send`
            /// for `T`
            ast::ItemImpl(_, ast::ImplPolarity::Positive, _, _, _, _) => {
                self.check_impl(item);
            }
            ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => {
                let trait_ref = ty::impl_id_to_trait_ref(ccx.tcx, item.id);
                ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id);
                match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
                    Some(ty::BoundSend) | Some(ty::BoundSync) => {}
                    Some(_) | None => {
                        if !ty::trait_has_default_impl(ccx.tcx, trait_ref.def_id) {
                            span_err!(ccx.tcx.sess, item.span, E0192,
                                      "negative impls are only allowed for traits with \
                                       default impls (e.g., `Send` and `Sync`)")
                        }
                    }
                }
            }
            ast::ItemFn(..) => {
                self.check_item_type(item);
            }
            ast::ItemStatic(..) => {
                self.check_item_type(item);
            }
            ast::ItemConst(..) => {
                self.check_item_type(item);
            }
            ast::ItemStruct(ref struct_def, ref ast_generics) => {
                self.check_type_defn(item, |fcx| {
                    vec![struct_variant(fcx, &**struct_def)]
                });

                self.check_variances_for_type_defn(item, ast_generics);
            }
            ast::ItemEnum(ref enum_def, ref ast_generics) => {
                self.check_type_defn(item, |fcx| {
                    enum_variants(fcx, enum_def)
                });

                self.check_variances_for_type_defn(item, ast_generics);
            }
            ast::ItemTrait(_, _, _, ref items) => {
                let trait_predicates =
                    ty::lookup_predicates(ccx.tcx, local_def(item.id));
                reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates);
                if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) {
                    if !items.is_empty() {
                        ccx.tcx.sess.span_err(
                            item.span,
                            "traits with default impls (`e.g. unsafe impl Trait for ..`) must \
                            have no methods or associated items")
                    }
                }
            }
            _ => {}
        }
    }

    fn with_fcx<F>(&mut self, item: &ast::Item, mut f: F) where
        F: for<'fcx> FnMut(&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>, &FnCtxt<'fcx, 'tcx>),
    {
        let ccx = self.ccx;
        let item_def_id = local_def(item.id);
        let type_scheme = ty::lookup_item_type(ccx.tcx, item_def_id);
        let type_predicates = ty::lookup_predicates(ccx.tcx, item_def_id);
        reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
        let param_env =
            ty::construct_parameter_environment(ccx.tcx,
                                                item.span,
                                                &type_scheme.generics,
                                                &type_predicates,
                                                item.id);
        let inh = Inherited::new(ccx.tcx, param_env);
        let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
        f(self, &fcx);
        fcx.select_all_obligations_or_error();
        regionck::regionck_item(&fcx, item);
    }

    /// In a type definition, we check that to ensure that the types of the fields are well-formed.
    fn check_type_defn<F>(&mut self, item: &ast::Item, mut lookup_fields: F) where
        F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec<AdtVariant<'tcx>>,
    {
        self.with_fcx(item, |this, fcx| {
            let variants = lookup_fields(fcx);
            let mut bounds_checker = BoundsChecker::new(fcx,
                                                        item.span,
                                                        item.id,
                                                        Some(&mut this.cache));
            debug!("check_type_defn at bounds_checker.scope: {:?}", bounds_checker.scope);

             for variant in &variants {
                for field in &variant.fields {
                    // Regions are checked below.
                    bounds_checker.check_traits_in_ty(field.ty);
                }

                // For DST, all intermediate types must be sized.
                if !variant.fields.is_empty() {
                    for field in variant.fields.init() {
                        fcx.register_builtin_bound(
                            field.ty,
                            ty::BoundSized,
                            traits::ObligationCause::new(field.span,
                                                         fcx.body_id,
                                                         traits::FieldSized));
                    }
                }
            }

            let field_tys: Vec<Ty> =
                variants.iter().flat_map(|v| v.fields.iter().map(|f| f.ty)).collect();

            regionck::regionck_ensure_component_tys_wf(
                fcx, item.span, &field_tys);
        });
    }

    fn check_item_type(&mut self,
                       item: &ast::Item)
    {
        self.with_fcx(item, |this, fcx| {
            let mut bounds_checker = BoundsChecker::new(fcx,
                                                        item.span,
                                                        item.id,
                                                        Some(&mut this.cache));
            debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope);

            let type_scheme = ty::lookup_item_type(fcx.tcx(), local_def(item.id));
            let item_ty = fcx.instantiate_type_scheme(item.span,
                                                      &fcx.inh.param_env.free_substs,
                                                      &type_scheme.ty);

            bounds_checker.check_traits_in_ty(item_ty);
        });
    }

    fn check_impl(&mut self,
                  item: &ast::Item)
    {
        self.with_fcx(item, |this, fcx| {
            let mut bounds_checker = BoundsChecker::new(fcx,
                                                        item.span,
                                                        item.id,
                                                        Some(&mut this.cache));
            debug!("check_impl at bounds_checker.scope: {:?}", bounds_checker.scope);

            // Find the impl self type as seen from the "inside" --
            // that is, with all type parameters converted from bound
            // to free.
            let self_ty = ty::node_id_to_type(fcx.tcx(), item.id);
            let self_ty = fcx.instantiate_type_scheme(item.span,
                                                      &fcx.inh.param_env.free_substs,
                                                      &self_ty);

            bounds_checker.check_traits_in_ty(self_ty);

            // Similarly, obtain an "inside" reference to the trait
            // that the impl implements.
            let trait_ref = match ty::impl_trait_ref(fcx.tcx(), local_def(item.id)) {
                None => { return; }
                Some(t) => { t }
            };

            let trait_ref = fcx.instantiate_type_scheme(item.span,
                                                        &fcx.inh.param_env.free_substs,
                                                        &trait_ref);

            // We are stricter on the trait-ref in an impl than the
            // self-type.  In particular, we enforce region
            // relationships. The reason for this is that (at least
            // presently) "applying" an impl does not require that the
            // application site check the well-formedness constraints on the
            // trait reference. Instead, this is done at the impl site.
            // Arguably this is wrong and we should treat the trait-reference
            // the same way as we treat the self-type.
            bounds_checker.check_trait_ref(&trait_ref);

            let cause =
                traits::ObligationCause::new(
                    item.span,
                    fcx.body_id,
                    traits::ItemObligation(trait_ref.def_id));

            // Find the supertrait bounds. This will add `int:Bar`.
            let poly_trait_ref = ty::Binder(trait_ref);
            let predicates = ty::lookup_super_predicates(fcx.tcx(), poly_trait_ref.def_id());
            let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref);
            let predicates = {
                let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx);
                traits::normalize(selcx, cause.clone(), &predicates)
            };
            for predicate in predicates.value.predicates {
                fcx.register_predicate(traits::Obligation::new(cause.clone(), predicate));
            }
            for obligation in predicates.obligations {
                fcx.register_predicate(obligation);
            }
        });
    }

    fn check_variances_for_type_defn(&self,
                                     item: &ast::Item,
                                     ast_generics: &ast::Generics)
    {
        let item_def_id = local_def(item.id);
        let ty_predicates = ty::lookup_predicates(self.tcx(), item_def_id);
        let variances = ty::item_variances(self.tcx(), item_def_id);

        let mut constrained_parameters: HashSet<_> =
            variances.types
                     .iter_enumerated()
                     .filter(|&(_, _, &variance)| variance != ty::Bivariant)
                     .map(|(space, index, _)| self.param_ty(ast_generics, space, index))
                     .map(|p| Parameter::Type(p))
                     .collect();

        identify_constrained_type_params(self.tcx(),
                                         ty_predicates.predicates.as_slice(),
                                         None,
                                         &mut constrained_parameters);

        for (space, index, _) in variances.types.iter_enumerated() {
            let param_ty = self.param_ty(ast_generics, space, index);
            if constrained_parameters.contains(&Parameter::Type(param_ty)) {
                continue;
            }
            let span = self.ty_param_span(ast_generics, item, space, index);
            self.report_bivariance(span, param_ty.name);
        }

        for (space, index, &variance) in variances.regions.iter_enumerated() {
            if variance != ty::Bivariant {
                continue;
            }

            assert_eq!(space, TypeSpace);
            let span = ast_generics.lifetimes[index].lifetime.span;
            let name = ast_generics.lifetimes[index].lifetime.name;
            self.report_bivariance(span, name);
        }
    }

    fn param_ty(&self,
                ast_generics: &ast::Generics,
                space: ParamSpace,
                index: usize)
                -> ty::ParamTy
    {
        let name = match space {
            TypeSpace => ast_generics.ty_params[index].ident.name,
            SelfSpace => special_idents::type_self.name,
            FnSpace => self.tcx().sess.bug("Fn space occupied?"),
        };

        ty::ParamTy { space: space, idx: index as u32, name: name }
    }

    fn ty_param_span(&self,
                     ast_generics: &ast::Generics,
                     item: &ast::Item,
                     space: ParamSpace,
                     index: usize)
                     -> Span
    {
        match space {
            TypeSpace => ast_generics.ty_params[index].span,
            SelfSpace => item.span,
            FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"),
        }
    }

    fn report_bivariance(&self,
                         span: Span,
                         param_name: ast::Name)
    {
        self.tcx().sess.span_err(
            span,
            &format!("parameter `{}` is never used",
                     param_name.user_string(self.tcx())));

        let suggested_marker_id = self.tcx().lang_items.phantom_data();
        match suggested_marker_id {
            Some(def_id) => {
                self.tcx().sess.fileline_help(
                    span,
                    &format!("consider removing `{}` or using a marker such as `{}`",
                             param_name.user_string(self.tcx()),
                             ty::item_path_str(self.tcx(), def_id)));
            }
            None => {
                // no lang items, no help!
            }
        }
    }
}

// Reject any predicates that do not involve a type parameter.
fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      span: Span,
                                      predicates: &ty::GenericPredicates<'tcx>) {
    for predicate in predicates.predicates.iter() {
        match predicate {
            &ty::Predicate::Trait(ty::Binder(ref tr)) => {
                let found_param = tr.input_types().iter()
                                    .flat_map(|ty| ty.walk())
                                    .any(is_ty_param);
                if !found_param { report_bound_error(tcx, span, tr.self_ty() )}
            }
            &ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(ty, _))) => {
                let found_param = ty.walk().any(|t| is_ty_param(t));
                if !found_param { report_bound_error(tcx, span, ty) }
            }
            _ => {}
        };
    }

    fn report_bound_error<'t>(tcx: &ty::ctxt<'t>,
                          span: Span,
                          bounded_ty: ty::Ty<'t>) {
        span_err!(tcx.sess, span, E0193,
            "cannot bound type `{}`, where clause \
                bounds may only be attached to types involving \
                type parameters",
                bounded_ty.repr(tcx))
    }

    fn is_ty_param(ty: ty::Ty) -> bool {
        match &ty.sty {
            &ty::sty::ty_param(_) => true,
            _ => false
        }
    }
}

fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>,
                                          span: Span,
                                          generics: &ty::Generics<'tcx>) {
    let impl_params = generics.types.get_slice(subst::TypeSpace).iter()
        .map(|tp| tp.name).collect::<HashSet<_>>();

    for method_param in generics.types.get_slice(subst::FnSpace) {
        if impl_params.contains(&method_param.name) {
            span_err!(tcx.sess, span, E0194,
                "type parameter `{}` shadows another type parameter of the same name",
                          token::get_name(method_param.name));
        }
    }
}

impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
    fn visit_item(&mut self, i: &ast::Item) {
        self.check_item_well_formed(i);
        visit::walk_item(self, i);
    }

    fn visit_fn(&mut self,
                fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
                b: &'v ast::Block, span: Span, id: ast::NodeId) {
        match fk {
            visit::FkFnBlock | visit::FkItemFn(..) => {}
            visit::FkMethod(..) => {
                match ty::impl_or_trait_item(self.tcx(), local_def(id)) {
                    ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
                        reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics)
                    }
                    _ => {}
                }
            }
        }
        visit::walk_fn(self, fk, fd, b, span)
    }

    fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) {
        if let ast::MethodTraitItem(_, None) = trait_item.node {
            match ty::impl_or_trait_item(self.tcx(), local_def(trait_item.id)) {
                ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
                    reject_non_type_param_bounds(
                        self.tcx(),
                        trait_item.span,
                        &ty_method.predicates);
                    reject_shadowing_type_parameters(
                        self.tcx(),
                        trait_item.span,
                        &ty_method.generics);
                }
                _ => {}
            }
        }

        visit::walk_trait_item(self, trait_item)
    }
}

pub struct BoundsChecker<'cx,'tcx:'cx> {
    fcx: &'cx FnCtxt<'cx,'tcx>,
    span: Span,

    // This field is often attached to item impls; it is not clear
    // that `CodeExtent` is well-defined for such nodes, so pnkfelix
    // has left it as a NodeId rather than porting to CodeExtent.
    scope: ast::NodeId,

    binding_count: usize,
    cache: Option<&'cx mut HashSet<Ty<'tcx>>>,
}

impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
    pub fn new(fcx: &'cx FnCtxt<'cx,'tcx>,
               span: Span,
               scope: ast::NodeId,
               cache: Option<&'cx mut HashSet<Ty<'tcx>>>)
               -> BoundsChecker<'cx,'tcx> {
        BoundsChecker { fcx: fcx, span: span, scope: scope,
                        cache: cache, binding_count: 0 }
    }

    /// Given a trait ref like `A : Trait<B>`, where `Trait` is defined as (say):
    ///
    ///     trait Trait<B:OtherTrait> : Copy { ... }
    ///
    /// This routine will check that `B : OtherTrait` and `A : Trait<B>`. It will also recursively
    /// check that the types `A` and `B` are well-formed.
    ///
    /// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
    /// to the point where impl `A : Trait<B>` is implemented).
    pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
        let trait_predicates = ty::lookup_predicates(self.fcx.tcx(), trait_ref.def_id);

        let bounds = self.fcx.instantiate_bounds(self.span,
                                                 trait_ref.substs,
                                                 &trait_predicates);

        self.fcx.add_obligations_for_parameters(
            traits::ObligationCause::new(
                self.span,
                self.fcx.body_id,
                traits::ItemObligation(trait_ref.def_id)),
            &bounds);

        for &ty in trait_ref.substs.types.iter() {
            self.check_traits_in_ty(ty);
        }
    }

    pub fn check_ty(&mut self, ty: Ty<'tcx>) {
        ty.fold_with(self);
    }

    fn check_traits_in_ty(&mut self, ty: Ty<'tcx>) {
        // When checking types outside of a type def'n, we ignore
        // region obligations. See discussion below in fold_ty().
        self.binding_count += 1;
        ty.fold_with(self);
        self.binding_count -= 1;
    }
}

impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
    fn tcx(&self) -> &ty::ctxt<'tcx> {
        self.fcx.tcx()
    }

    fn fold_binder<T>(&mut self, binder: &ty::Binder<T>) -> ty::Binder<T>
        where T : TypeFoldable<'tcx> + Repr<'tcx>
    {
        self.binding_count += 1;
        let value = liberate_late_bound_regions(
            self.fcx.tcx(),
            region::DestructionScopeData::new(self.scope),
            binder);
        debug!("BoundsChecker::fold_binder: late-bound regions replaced: {} at scope: {:?}",
               value.repr(self.tcx()), self.scope);
        let value = value.fold_with(self);
        self.binding_count -= 1;
        ty::Binder(value)
    }

    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
        debug!("BoundsChecker t={}",
               t.repr(self.tcx()));

        match self.cache {
            Some(ref mut cache) => {
                if !cache.insert(t) {
                    // Already checked this type! Don't check again.
                    debug!("cached");
                    return t;
                }
            }
            None => { }
        }

        match t.sty{
            ty::ty_struct(type_id, substs) |
            ty::ty_enum(type_id, substs) => {
                let type_predicates = ty::lookup_predicates(self.fcx.tcx(), type_id);
                let bounds = self.fcx.instantiate_bounds(self.span, substs,
                                                         &type_predicates);

                if self.binding_count == 0 {
                    self.fcx.add_obligations_for_parameters(
                        traits::ObligationCause::new(self.span,
                                                     self.fcx.body_id,
                                                     traits::ItemObligation(type_id)),
                        &bounds);
                } else {
                    // There are two circumstances in which we ignore
                    // region obligations.
                    //
                    // The first is when we are inside of a closure
                    // type. This is because in that case the region
                    // obligations for the parameter types are things
                    // that the closure body gets to assume and the
                    // caller must prove at the time of call. In other
                    // words, if there is a type like `<'a, 'b> | &'a
                    // &'b int |`, it is well-formed, and caller will
                    // have to show that `'b : 'a` at the time of
                    // call.
                    //
                    // The second is when we are checking for
                    // well-formedness outside of a type def'n or fn
                    // body. This is for a similar reason: in general,
                    // we only do WF checking for regions in the
                    // result of expressions and type definitions, so
                    // to as allow for implicit where clauses.
                    //
                    // (I believe we should do the same for traits, but
                    // that will require an RFC. -nmatsakis)
                    let bounds = filter_to_trait_obligations(bounds);
                    self.fcx.add_obligations_for_parameters(
                        traits::ObligationCause::new(self.span,
                                                     self.fcx.body_id,
                                                     traits::ItemObligation(type_id)),
                        &bounds);
                }

                self.fold_substs(substs);
            }
            _ => {
                super_fold_ty(self, t);
            }
        }

        t // we're not folding to produce a new type, so just return `t` here
    }
}

///////////////////////////////////////////////////////////////////////////
// ADT

struct AdtVariant<'tcx> {
    fields: Vec<AdtField<'tcx>>,
}

struct AdtField<'tcx> {
    ty: Ty<'tcx>,
    span: Span,
}

fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                            struct_def: &ast::StructDef)
                            -> AdtVariant<'tcx> {
    let fields =
        struct_def.fields
        .iter()
        .map(|field| {
            let field_ty = ty::node_id_to_type(fcx.tcx(), field.node.id);
            let field_ty = fcx.instantiate_type_scheme(field.span,
                                                       &fcx.inh.param_env.free_substs,
                                                       &field_ty);
            AdtField { ty: field_ty, span: field.span }
        })
        .collect();
    AdtVariant { fields: fields }
}

fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                           enum_def: &ast::EnumDef)
                           -> Vec<AdtVariant<'tcx>> {
    enum_def.variants.iter()
        .map(|variant| {
            match variant.node.kind {
                ast::TupleVariantKind(ref args) if !args.is_empty() => {
                    let ctor_ty = ty::node_id_to_type(fcx.tcx(), variant.node.id);

                    // the regions in the argument types come from the
                    // enum def'n, and hence will all be early bound
                    let arg_tys =
                        ty::no_late_bound_regions(
                            fcx.tcx(), &ty::ty_fn_args(ctor_ty)).unwrap();
                    AdtVariant {
                        fields: args.iter().enumerate().map(|(index, arg)| {
                            let arg_ty = arg_tys[index];
                            let arg_ty =
                                fcx.instantiate_type_scheme(variant.span,
                                                            &fcx.inh.param_env.free_substs,
                                                            &arg_ty);
                            AdtField {
                                ty: arg_ty,
                                span: arg.ty.span
                            }
                        }).collect()
                    }
                }
                ast::TupleVariantKind(_) => {
                    AdtVariant {
                        fields: Vec::new()
                    }
                }
                ast::StructVariantKind(ref struct_def) => {
                    struct_variant(fcx, &**struct_def)
                }
            }
        })
        .collect()
}

fn filter_to_trait_obligations<'tcx>(bounds: ty::InstantiatedPredicates<'tcx>)
                                     -> ty::InstantiatedPredicates<'tcx>
{
    let mut result = ty::InstantiatedPredicates::empty();
    for (space, _, predicate) in bounds.predicates.iter_enumerated() {
        match *predicate {
            ty::Predicate::Trait(..) |
            ty::Predicate::Projection(..) => {
                result.predicates.push(space, predicate.clone())
            }
            ty::Predicate::Equate(..) |
            ty::Predicate::TypeOutlives(..) |
            ty::Predicate::RegionOutlives(..) => {
            }
        }
    }
    result
}


text:
class SearchResult
  include ActiveModel::Model

  attr_accessor :query, :page, :size, :total_count, :articles
end

redpajama_set_name: RedPajamaGithub


text:
<?php // vim:ts=4:sw=4:et:fdm=marker
/*
 * Undocumented
 *
 * @link http://agiletoolkit.org/
*//*
==ATK4===================================================
   This file is part of Agile Toolkit 4
    http://agiletoolkit.org/

   (c) 2008-2013 Agile Toolkit Limited <info@agiletoolkit.org>
   Distributed under Affero General Public License v3 and
   commercial license.

   See LICENSE or LICENSE_COM for more information
 =====================================================ATK4=*/
class DB_dsql_prefixed extends DB_dsql {
    /** Prefix */
    public $prefix=null;

    function prefix($prefix){
        $this->prefix=$prefix;
        return $this;
    }
    function table($table=undefined,$alias=undefined){
        if($this->prefix && $alias==undefined)$alias=$table;
        return parent::table($this->prefix.$table,$alias);
    }
    function join($table,$on,$type='inner'){
        return parent::join($this->prefix.$table,$alias);
    }
}


text:
:mod:`apscheduler.jobstores.base`
=================================

.. automodule:: apscheduler.jobstores.base

API
---

.. autoclass:: BaseJobStore
    :members:


text:
// <auto-generated />
namespace BattleChess.Utilities
{
    using Microsoft.Xna.Framework.Graphics;

    public static class Images
    {
        public static Texture2D TitleScreen;

        public static Texture2D ChessBoard;
    }
}


text:
package smile.feature;

import smile.math.Math;
import smile.data.Attribute;
import smile.data.NumericAttribute;
import smile.sort.QuickSelect;

/**
 * Numeric attribute normalization/standardization feature generator.
 * Many machine learning methods such as Neural Networks and SVM with Gaussian
 * kernel also require the features properly scaled/standardized. For example,
 * each variable is scaled into interval [0, 1] or to have mean 0 and standard
 * deviation 1.
 *
 * @author Haifeng Li
 */
public class NumericAttributeFeature implements Feature<double[]> {
    /**
     * The types of data scaling.
     */
    public static enum Scaling {
        /**
         * No scaling at all.
         */
        NONE,
        /**
         * Takes logarithms of input data when they contain order-of-magnitude
         * larger and smaller values. Note logarithms are defined only for
         * positive values.
         */
        LOGARITHM,
        /**
         * Normalization scales all numeric variables in the range [0, 1].
         * If the dataset has outliers, normalization will certainly scale
         * the "normal" data to a very small interval. In this case, the
         * Winsorization procedure should be applied: values greater than the
         * specified upper limit are replaced with the upper limit, and those
         * below the lower limit are replace with the lower limit. Often, the
         * specified range is indicate in terms of percentiles of the original
         * distribution (like the 5th and 95th percentile).
         */
        NORMALIZATION,
        /**
         * Standardization transforms a variable to have zero mean and unit
         * variance. Standardization makes an assumption that the data follows
         * a Gaussian distribution and are also not robust when outliers present.
         * A robust alternative is to subtract the median and divide by the IQR.
         */
        STANDARDIZATION
    }

    /**
     * The variable attributes.
     */
    private Attribute[] attributes;
    /**
     * The attributes of generated binary dummy variables.
     */
    private Attribute[] features;
    /**
     * A map from feature id to original attribute index.
     */
    private int[] map;
    /**
     * The types of scaling.
     */
    private Scaling scaling;
    /**
     * For normalization, this is min or lower limit.
     * For standardization, this is mean or median.
     */
    private double[] a;
    /**
     * For normalization, this is max - min or upper limit - lower limit.
     * For standardization, this is standard deviation or IQR.
     */
    private double[] b;

    /**
     * Constructor. Scales numeric attributes into proper range. For logarithm
     * scaling, the attributes must have positive values.
     * @param attributes the variable attributes. Of which, numeric variables
     * will be scaled.
     * @param scaling the way of scaling. The scaling type must be NONE or
     * LOGARITHM because they do not need training data.
     */
    public NumericAttributeFeature(Attribute[] attributes, Scaling scaling) {
        if (scaling != Scaling.NONE && scaling != Scaling.LOGARITHM) {
            throw new IllegalArgumentException("Invalid scaling operation without training data: " + scaling);
        }

        this.attributes = attributes;
        this.scaling = scaling;

        int p = 0;
        for (Attribute attribute : attributes) {
            if (attribute instanceof NumericAttribute) {
                p++;
            }
        }

        features = new Attribute[p];
        map = new int[p];
        for (int i = 0, j = 0; j < attributes.length; j++) {
            Attribute attribute = attributes[j];
            if (attribute instanceof NumericAttribute) {
                if (scaling == Scaling.NONE) {
                    features[i] = attribute;
                } else {
                    features[i] = new NumericAttribute(attribute.name + "_" + scaling, attribute.description, attribute.weight);
                }

                map[i++] = j;
            }
        }
    }

    /**
     * Constructor. Scales numeric attributes into proper range. For logarithm
     * scaling, the attributes must have positive values. In case of
     * normalization, the min and max values of attributes are used as lower
     * and upper limits. For standardization, variables are scaled to have zero
     * mean and unit variance.
     * @param attributes the variable attributes. Of which, numeric variables
     * will be scaled.
     * @param scaling the way of scaling.
     * @param data the training data to learn scaling parameters.
     */
    public NumericAttributeFeature(Attribute[] attributes, Scaling scaling, double[][] data) {
        this.attributes = attributes;
        this.scaling = scaling;

        int n = data.length;
        int p = 0;
        for (Attribute attribute : attributes) {
            if (attribute instanceof NumericAttribute) {
                p++;
            }
        }

        features = new Attribute[p];
        map = new int[p];
        a = new double[p];
        b = new double[p];
        double[] x = new double[n];

        for (int i = 0, j = 0; j < attributes.length; j++) {
            Attribute attribute = attributes[j];
            if (attribute instanceof NumericAttribute) {
                if (scaling == Scaling.NONE) {
                    features[i] = attribute;
                } else {
                    features[i] = new NumericAttribute(attribute.name + "_" + scaling, attribute.description, attribute.weight);
                    if (scaling == Scaling.NORMALIZATION || scaling == Scaling.STANDARDIZATION) {
                        for (int k = 0; k < n; k++) {
                            x[k] = data[k][j];
                        }

                        if (scaling == Scaling.NORMALIZATION) {
                            a[i] = Math.min(x);
                            b[i] = Math.max(x) - a[i];
                            if (b[i] == 0.0) {
                                throw new IllegalArgumentException("Attribute " + attribute + " has constant values.");
                            }
                        }

                        if (scaling == Scaling.STANDARDIZATION) {
                            a[i] = Math.mean(x);
                            b[i] = Math.sd(x);
                            if (b[i] == 0.0) {
                                throw new IllegalArgumentException("Attribute " + attribute + " has constant values.");
                            }
                        }
                    }

                }

                map[i++] = j;
            }
        }
    }

    /**
     * Constructor. Normalizes numeric attributes with Winsorization: values
     * greater than the specified upper limit are replaced with the upper
     * limit, and those below the lower limit are replace with the lower limit.
     * The specified lower/upper limits are indicate in terms of percentiles of
     * the original distribution.
     * @param attributes the variable attributes. Of which, numeric variables
     * will be normalized.
     * @param lower the lower limit in terms of percentiles of the original
     * distribution (say 5th percentile).
     * @param upper the upper limit in terms of percentiles of the original
     * distribution (say 95th percentile).
     * @param data the training data to learn scaling parameters.
     */
    public NumericAttributeFeature(Attribute[] attributes, double lower, double upper, double[][] data) {
        if (lower < 0.0 || lower > 0.5) {
            throw new IllegalArgumentException("Invalid lower limit: " + lower);
        }

        if (upper < 0.5 || lower > 1.0) {
            throw new IllegalArgumentException("Invalid upper limit: " + upper);
        }

        if (upper <= lower) {
            throw new IllegalArgumentException("Invalid lower and upper limit pair: " + lower + " >= " + upper);
        }

        this.attributes = attributes;
        this.scaling = Scaling.NORMALIZATION;

        int n = data.length;
        int p = 0;
        for (Attribute attribute : attributes) {
            if (attribute instanceof NumericAttribute) {
                p++;
            }
        }

        int i1 = (int) Math.round(lower * n);
        int i2 = (int) Math.round(upper * n);
        if (i2 == n) {
            i2 = n - 1;
        }

        features = new Attribute[p];
        map = new int[p];
        a = new double[p];
        b = new double[p];
        double[] x = new double[n];

        for (int i = 0, j = 0; j < attributes.length; j++) {
            Attribute attribute = attributes[j];
            if (attribute instanceof NumericAttribute) {
                features[i] = new NumericAttribute(attribute.name + "_" + scaling, attribute.description, attribute.weight);
                for (int k = 0; k < n; k++) {
                    x[k] = data[k][j];
                }

                a[i] = QuickSelect.select(x, i1);
                b[i] = QuickSelect.select(x, i2) - a[i];
                if (b[i] == 0.0) {
                    throw new IllegalArgumentException("Attribute " + attribute + " has constant values in the given range.");
                }

                map[i++] = j;
            }
        }
    }

    /**
     * Constructor. Robustly standardizes numeric attributes by subtracting
     * the median and dividing by the IQR.
     * @param attributes the variable attributes. Of which, numeric variables
     * will be standardized.
     * @param data the training data to learn scaling parameters.
     */
    public NumericAttributeFeature(Attribute[] attributes, double[][] data) {
        this.attributes = attributes;
        this.scaling = Scaling.STANDARDIZATION;

        int n = data.length;
        int p = 0;
        for (Attribute attribute : attributes) {
            if (attribute instanceof NumericAttribute) {
                p++;
            }
        }

        features = new Attribute[p];
        map = new int[p];
        a = new double[p];
        b = new double[p];
        double[] x = new double[n];

        for (int i = 0, j = 0; j < attributes.length; j++) {
            Attribute attribute = attributes[j];
            if (attribute instanceof NumericAttribute) {
                features[i] = new NumericAttribute(attribute.name + "_" + scaling, attribute.description, attribute.weight);
                for (int k = 0; k < n; k++) {
                    x[k] = data[k][j];
                }

                a[i] = QuickSelect.median(x);
                b[i] = QuickSelect.q3(x) - QuickSelect.q1(x);
                if (b[i] == 0.0) {
                    throw new IllegalArgumentException("Attribute " + attribute + " has constant values between Q1 and Q3.");
                }

                map[i++] = j;
            }
        }
    }

    @Override
    public Attribute[] attributes() {
        return features;
    }

    @Override
    public double f(double[] object, int id) {
        if (object.length != attributes.length) {
            throw new IllegalArgumentException(String.format("Invalide object size %d, expected %d", object.length, attributes.length));
        }

        if (id < 0 || id >= features.length) {
            throw new IllegalArgumentException("Invalide feature id: " + id);
        }

        double x = object[map[id]];
        switch (scaling) {
            case NONE:
                return x;
            case LOGARITHM:
                if (x <= 0.0) {
                    throw new IllegalArgumentException("Invalid value for logarithm: " + x);
                }
                return Math.log(x);
            case NORMALIZATION:
                double y = (x - a[id]) / b[id];
                if (y < 0.0) y = 0.0;
                if (y > 1.0) y = 1.0;
                return y;
            case STANDARDIZATION:
                return (x - a[id]) / b[id];
        }

        throw new IllegalStateException("Impossible to reach here.");
    }
}


text:
.. automodule:: insights.combiners.ceph_osd_tree
   :members:
   :show-inheritance:


text:
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

  <LinearLayout
      android:id="@+id/header"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/primary"
      >

    <android.support.v7.widget.Toolbar
        android:id="@id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        >

    </android.support.v7.widget.Toolbar>

    <FrameLayout
        android:id="@id/tab"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

  </LinearLayout>

  <android.support.v4.view.ViewPager
      android:id="@id/viewpager"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_below="@id/header"
      />

</RelativeLayout>


text:
#include "ble_radio_notification.h"
#include <stdlib.h>

static bool                                 m_radio_active = false;  /**< Current radio state. */
static ble_radio_notification_evt_handler_t m_evt_handler  = NULL;   /**< Application event handler for handling Radio Notification events. */

void SWI1_IRQHandler(void)
{
    m_radio_active = !m_radio_active;
    if (m_evt_handler != NULL)
    {
        m_evt_handler(m_radio_active);
    }
}

uint32_t ble_radio_notification_init(uint32_t                             irq_priority,
                                     uint8_t                              distance,
                                     ble_radio_notification_evt_handler_t evt_handler)
{
    uint32_t err_code;

    m_evt_handler = evt_handler;

    // Initialize Radio Notification software interrupt
    err_code = sd_nvic_ClearPendingIRQ(SWI1_IRQn);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = sd_nvic_SetPriority(SWI1_IRQn, irq_priority);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = sd_nvic_EnableIRQ(SWI1_IRQn);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    // Configure the event
    return sd_radio_notification_cfg_set(NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, distance);
}


text:
namespace scm {
namespace gl {
namespace util {

class __scm_export(gl_util) overlay_text_output
{
public:
    overlay_text_output(const gl::render_device_ptr& device,
                        const math::vec2ui&          vp_size,
                        const int                    text_size);
    virtual ~overlay_text_output();

    const math::vec4f&                  back_color() const;
    void                                back_color(const math::vec4f& c);
    const math::vec4f&                  frame_color() const;
    void                                frame_color(const math::vec4f& c);

    const math::vec4f&                  text_color() const;
    void                                text_color(const math::vec4f& c);
    const math::vec4f&                  text_outline_color() const;
    void                                text_outline_color(const math::vec4f& c);

    void                                update(const gl::render_context_ptr& context,
                                               const std::string&            text,
                                               const math::vec2i&            out_pos);
    void                                update(const gl::render_context_ptr& context,
                                               const std::string&            text);
    void                                draw(const gl::render_context_ptr& context);
protected:
    math::vec2ui                        _viewport_size;

    math::vec4f                         _back_color;
    math::vec4f                         _frame_color;

    gl::text_renderer_ptr               _text_renderer;
    gl::text_ptr                        _output_text;
    int                                 _output_text_size;
    math::vec2i                         _output_text_pos;
    math::vec2i                         _output_text_frame_size;
    gl::quad_geometry_ptr               _output_text_background;
    gl::geometry_highlight_ptr          _geom_highlighter;

}; // class overlay_text_output

} // namespace util
} // namespace gl
} // namespace scm

#include <scm/core/utilities/platform_warning_enable.h>

#endif //SCM_GL_UTIL_OVERLAY_TEXT_OUTPUT_H_INCLUDED


text:
using Novell.Directory.Ldap.Rfc2251;

namespace Novell.Directory.Ldap
{
    /// <summary>
    ///     Represents an Ldap Unbind Request.
    /// </summary>
    /// <seealso cref="LdapConnection.SendRequestAsync">
    /// </seealso>
    /*
     *       UnbindRequest ::= [APPLICATION 2] NULL
     */
    public class LdapUnbindRequest : LdapMessage
    {
        public override DebugId DebugId { get; } = DebugId.ForType<LdapUnbindRequest>();

        /// <summary>
        ///     Constructs an Ldap Unbind Request.
        /// </summary>
        /// <param name="cont">
        ///     Any controls that apply to the unbind request.
        /// </param>
        public LdapUnbindRequest(LdapControl[] cont)
            : base(UnbindRequest, new RfcUnbindRequest(), cont)
        {
        }
    }
}


text:
DateFormatter accepts two arguments: a format string and a separator.

Usage example:

```
./dateformatter "DD MMM YY" "-"
06-Apr-13
```

Supported date formatting patterns:

DD - day number (with leading zero)
MM - month number (with leading zero)
MMM - short month name (Jan, Feb, Mar, etc)
YY - two last digits of the year
YYYY - full year

Unit tests based on [CxxTest](https://github.com/CxxTest/cxxtest) also included. To run them you can run these commands:

make tests / ./runtests.sh - just run tests and print out a success rate.

make tests-verbose / ./runtests.sh -v - run tests and print out a success rate and some tracing information.

Note that CxxTest is added as git submodule, so after cloning a repo you should run these commands:

```
git submodule init
git submodule update
```

The source code of DateFormatter is distributed under [MIT License](http://en.wikipedia.org/wiki/MIT_License). See file LICENSE for more information.


text:
#ifndef QT3D_RENDER_ATTACHMENTPACK_P_H
#define QT3D_RENDER_ATTACHMENTPACK_P_H

#include <Qt3DRenderer/qrenderattachment.h>
#include <QVector>

QT_BEGIN_NAMESPACE

namespace Qt3D {

namespace Render {

struct Attachment
{
    Attachment();
    QString m_name;
    int m_mipLevel;
    int m_layer;
    QNodeId m_textureUuid;
    QRenderAttachment::RenderAttachmentType m_type;
    QRenderAttachment::CubeMapFace m_face;
};

class AttachmentPack
{
public:
    AttachmentPack();

    void addAttachment(const Attachment &attachment);
    QVector<Attachment> attachments() const;
    QList<QRenderAttachment::RenderAttachmentType> drawBuffers() const;

    void setDrawBuffers(const QList<QRenderAttachment::RenderAttachmentType> &drawBuffers);

private:
    QVector<Attachment> m_attachments;
    QList<QRenderAttachment::RenderAttachmentType> m_drawBuffers;
};

} // Render

} // Qt3D

QT_END_NAMESPACE

#endif // QT3D_RENDER_ATTACHMENTPACK_P_H


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>
JsonValueFormatVisitor (jackson-databind 2.1.0 API)
</TITLE>

<META NAME="date" CONTENT="2012-10-09">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../../stylesheet.css" TITLE="Style">

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD

com.fasterxml.jackson.databind.jsonFormatVisitors

Interface JsonValueFormatVisitor

All Known Subinterfaces:
JsonBooleanFormatVisitor, JsonIntegerFormatVisitor, JsonNumberFormatVisitor, JsonStringFormatVisitor

public interface JsonValueFormatVisitor

Method Summary

 void
enumTypes(Set<String> enums)

 void
format(JsonValueFormat format)

Method Detail

format

void format(JsonValueFormat format)

enumTypes

void enumTypes(Set<String> enums)

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD

Copyright © 2012 FasterXML. All Rights Reserved.


text:
'use strict';
/**
 * Serves the static stuff and also a 404!
 */

var express = require('express');
var http = require('http');
var path = require('path');
var compression = require('compression');
var app = express();

app.set('port', process.env.PORT || 8888);

app.use(compression());
app.use(express.static(__dirname));

app.get('*', function (req, res) {
    res.send('404 error', 404);
});

http.createServer(app).listen(app.get('port'), function () {
    console.log("Express server running on " + app.get('port'));
});


text:
/// @todo DAN
#if 0

#include <cmath>
#include <fstream>
#include <boost/math/constants/constants.hpp>
#include <Testing/Utils/SCIRunUnitTests.h>
#include <Core/Algorithms/DataIO/TextToTriSurfField.h>

#include <Core/GeometryPrimitives/Point.h>
#include <Core/Datatypes/Mesh/FieldFwd.h>
#include <Core/Datatypes/Mesh/VMesh.h>

using namespace SCIRun::Core::Algorithms::DataIO;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Geometry;

namespace
{
  boost::filesystem::path testPath = SCIRun::TestUtils::TestResources::rootDir() / "convert-examples";
}

TEST(ReadTriSurfTests, ReadFromFilePoints)
{
  TextToTriSurfFieldAlgorithm algo;
  auto filename = testPath / "simple_triangle_trisurf.pts";
  auto mesh = algo.run(filename.string());
  ASSERT_TRUE(mesh);

  VirtualMeshHandle vmesh = mesh->vmesh();
  ASSERT_TRUE(vmesh);
  ASSERT_TRUE(vmesh->is_trisurfmesh());
  /// @todo: code needs to be enabled
  //ASSERT_TRUE(vmesh->is_unstructuredmesh());
}

TEST(ReadTriSurfTests, ReadFromFileFaces)
{
  TextToTriSurfFieldAlgorithm algo;
  auto filename = testPath / "simple_triangle_trisurf.fac";
  auto mesh = algo.run(filename.string());
  ASSERT_TRUE(mesh);

  VirtualMeshHandle vmesh = mesh->vmesh();
  ASSERT_TRUE(vmesh);
  ASSERT_TRUE(vmesh->is_trisurfmesh());
  /// @todo: code needs to be enabled
  //ASSERT_TRUE(vmesh->is_unstructuredmesh());
}

TEST(ReadTriSurfTests, ReadInvalidPointsFile)
{
  TextToTriSurfFieldAlgorithm algo;
  const std::string filename("not_a_valid_file.pts");
  auto mesh = algo.run(filename);
  ASSERT_FALSE(mesh);
}

TEST(ReadTriSurfTests, ReadInvalidFacesFile)
{
  TextToTriSurfFieldAlgorithm algo;
  const std::string filename("not_a_valid_file.fac");
  auto mesh = algo.run(filename);
  ASSERT_FALSE(mesh);
}

struct MakePointsOnSphere
{
  MakePointsOnSphere(unsigned int seed = 1)
  {
    srand(seed);
  }

  Point operator()() const
  {
    const double pi = boost::math::constants::pi<double>();
    double random1 = (double)rand() / RAND_MAX;
    double phi = pi * random1;
    double random2 = (double)rand() / RAND_MAX;
    double theta = 2 * pi * random2;
    return Point(sin(phi) * cos(theta), sin(phi) * sin(theta), cos(phi));
  }
};

TEST(GenerateSphereOfPoints, DISABLED_Run)
{
  int n = 10000;

  std::vector<Point> points;
  std::generate_n(std::back_inserter(points), n, MakePointsOnSphere());

  std::ofstream filePts("C:\\Dev\\scirun_unit_test_data\\SCIRunUnitTestData\\SCIRun5\\UnitTests\\convert-examples\\sphereOfPoints.pts");
  std::for_each(points.begin(), points.end(), [&](const Point& p) { filePts << p.x() << " " << p.y() << " " << p.z() << std::endl; });
  std::ofstream fileFac("C:\\Dev\\scirun_unit_test_data\\SCIRunUnitTestData\\SCIRun5\\UnitTests\\convert-examples\\sphereOfPoints.fac");
  for (int i = 0; i < n; ++i)
  {
    fileFac << i << " " << (i + 1) << " " << (i + 2) << std::endl;
  }
}
#endif


text:
chrome.storage.sync.get({
    maxWidth: 400,
    bgColor: '#34454E'
}, function(settings) {
    $('#maxWidth').val(settings.maxWidth);
    $('#bgColor').val(settings.bgColor);
});

$('#save').click(function() {
    var maxWidth = parseInt($('#maxWidth').val());
    var bgColor = $('#bgColor').val();
    chrome.storage.sync.set({
        maxWidth: maxWidth,
        bgColor: bgColor
    }, function() {
        $('#status').fadeIn(150).css('display', 'inline');
        setTimeout(function() {
            $('#status').fadeOut(150);
        }, 1250);
    });
});

$('#restore').click(function() {
    chrome.storage.sync.set({
        maxWidth: 400,
        bgColor: '#34454E'
    }, function() {
        $('#status').fadeIn(150).css('display', 'inline').text('Default options restored.');
        setTimeout(function() {
            $('#status').fadeOut(150);
        }, 1250);
    });
    $('#maxWidth').val(400);
    $('#bgColor').val('#34454E');
});


text:
// Copyright (c) 2009-2021 The Regents of the University of Michigan
// This file is part of the HOOMD-blue project, released under the BSD 3-Clause License.

// Maintainer: jglaser

#include "ForceDistanceConstraintGPU.h"
#include "ForceDistanceConstraintGPU.cuh"

#include <hip/hip_runtime.h>

#include <string.h>
namespace py = pybind11;

/*! \file ForceDistanceConstraintGPU.cc
    \brief Contains code for the ForceDistanceConstraintGPU class
*/

/*! \param sysdef SystemDefinition containing the ParticleData to compute forces on
 */
ForceDistanceConstraintGPU::ForceDistanceConstraintGPU(std::shared_ptr<SystemDefinition> sysdef)
    : ForceDistanceConstraint(sysdef)
#ifdef CUSOLVER_AVAILABLE
      ,
      m_cusolver_rf_initialized(false), m_nnz_L_tot(0), m_nnz_U_tot(0), m_csr_val_L(m_exec_conf),
      m_csr_rowptr_L(m_exec_conf), m_csr_colind_L(m_exec_conf), m_csr_val_U(m_exec_conf),
      m_csr_rowptr_U(m_exec_conf), m_csr_colind_U(m_exec_conf), m_P(m_exec_conf), m_Q(m_exec_conf),
      m_T(m_exec_conf), m_nnz(m_exec_conf), m_nnz_tot(0)
#endif
    {
    unsigned int warp_size = m_exec_conf->dev_prop.warpSize;
    m_tuner_fill.reset(new Autotuner(warp_size,
                                     1024,
                                     warp_size,
                                     5,
                                     100000,
                                     "dist_constraint_fill_matrix_vec",
                                     this->m_exec_conf));
    m_tuner_force.reset(new Autotuner(warp_size,
                                      1024,
                                      warp_size,
                                      5,
                                      100000,
                                      "dist_constraint_force",
                                      this->m_exec_conf));

#ifdef CUSOLVER_AVAILABLE
    // initialize cuSPARSE
    cusparseCreate(&m_cusparse_handle);

    // cusparse matrix descriptor
    cusparseCreateMatDescr(&m_cusparse_mat_descr);
    cusparseSetMatType(m_cusparse_mat_descr, CUSPARSE_MATRIX_TYPE_GENERAL);
    cusparseSetMatIndexBase(m_cusparse_mat_descr, CUSPARSE_INDEX_BASE_ZERO);
    cusparseSetMatDiagType(m_cusparse_mat_descr, CUSPARSE_DIAG_TYPE_NON_UNIT);

    // L matrix
    cusparseCreateMatDescr(&m_cusparse_mat_descr_L);
    cusparseSetMatType(m_cusparse_mat_descr_L, CUSPARSE_MATRIX_TYPE_GENERAL);
    cusparseSetMatIndexBase(m_cusparse_mat_descr_L, CUSPARSE_INDEX_BASE_ZERO);
    cusparseSetMatDiagType(m_cusparse_mat_descr_L, CUSPARSE_DIAG_TYPE_UNIT);

    // U matrix
    cusparseCreateMatDescr(&m_cusparse_mat_descr_U);
    cusparseSetMatType(m_cusparse_mat_descr_U, CUSPARSE_MATRIX_TYPE_GENERAL);
    cusparseSetMatIndexBase(m_cusparse_mat_descr_U, CUSPARSE_INDEX_BASE_ZERO);
    cusparseSetMatDiagType(m_cusparse_mat_descr_U, CUSPARSE_DIAG_TYPE_NON_UNIT);

    GPUVector<int> csr_rowptr(m_exec_conf);
    m_csr_rowptr.swap(csr_rowptr);

    GPUVector<int> csr_colind(m_exec_conf);
    m_csr_colind.swap(csr_colind);
#endif

    GPUVector<double> sparse_val(m_exec_conf);
    m_sparse_val.swap(sparse_val);

    // reallocate base class array
    GPUVector<int> sparse_idxlookup(m_exec_conf);
    m_sparse_idxlookup.swap(sparse_idxlookup);
    }

//! Destructor
ForceDistanceConstraintGPU::~ForceDistanceConstraintGPU()
    {
#ifdef CUSOLVER_AVAILABLE
    // clean up cusparse
    cusparseDestroy(m_cusparse_handle);
    cusparseDestroyMatDescr(m_cusparse_mat_descr);

    if (m_cusolver_rf_initialized)
        {
        cusolverRfDestroy(m_cusolver_rf_handle);
        }

    cusparseDestroyMatDescr(m_cusparse_mat_descr_L);
    cusparseDestroyMatDescr(m_cusparse_mat_descr_U);
#endif
    }

void ForceDistanceConstraintGPU::fillMatrixVector(uint64_t timestep)
    {
    if (m_prof)
        m_prof->push(m_exec_conf, "fill matrix");

    // fill the matrix in row-major order
    unsigned int n_constraint = m_cdata->getN() + m_cdata->getNGhosts();

    if (m_constraint_reorder)
        {
        // reset flag
        m_constraint_reorder = false;

        // resize lookup matrix
        m_sparse_idxlookup.resize(n_constraint * n_constraint);

        ArrayHandle<int> h_sparse_idxlookup(m_sparse_idxlookup,
                                            access_location::host,
                                            access_mode::overwrite);

        // reset lookup matrix values to -1
        for (unsigned int i = 0; i < n_constraint * n_constraint; ++i)
            {
            h_sparse_idxlookup.data[i] = -1;
            }
        // access matrix elements
        ArrayHandle<double> d_cmatrix(m_cmatrix, access_location::device, access_mode::overwrite);
        ArrayHandle<double> d_cvec(m_cvec, access_location::device, access_mode::overwrite);

        // reset matrix elements
        hipMemset(d_cmatrix.data, 0, sizeof(double) * n_constraint * n_constraint);
        hipMemset(d_cvec.data, 0, sizeof(double) * n_constraint);
        }

        {
        // access matrix elements
        ArrayHandle<double> d_cmatrix(m_cmatrix, access_location::device, access_mode::overwrite);
        ArrayHandle<double> d_cvec(m_cvec, access_location::device, access_mode::overwrite);

        // access GPU constraint table on device
        const GPUArray<ConstraintData::members_t>& gpu_constraint_list
            = this->m_cdata->getGPUTable();
        const Index2D& gpu_table_indexer = this->m_cdata->getGPUTableIndexer();

        ArrayHandle<ConstraintData::members_t> d_gpu_clist(gpu_constraint_list,
                                                           access_location::device,
                                                           access_mode::read);
        ArrayHandle<unsigned int> d_gpu_n_constraints(this->m_cdata->getNGroupsArray(),
                                                      access_location::device,
                                                      access_mode::read);
        ArrayHandle<unsigned int> d_gpu_cpos(m_cdata->getGPUPosTable(),
                                             access_location::device,
                                             access_mode::read);
        ArrayHandle<typeval_t> d_group_typeval(m_cdata->getTypeValArray(),
                                               access_location::device,
                                               access_mode::read);

        // access particle data
        ArrayHandle<Scalar4> d_pos(m_pdata->getPositions(),
                                   access_location::device,
                                   access_mode::read);
        ArrayHandle<Scalar4> d_vel(m_pdata->getVelocities(),
                                   access_location::device,
                                   access_mode::read);
        ArrayHandle<unsigned int> d_rtag(m_pdata->getRTags(),
                                         access_location::device,
                                         access_mode::read);
        ArrayHandle<Scalar4> d_netforce(m_pdata->getNetForce(),
                                        access_location::device,
                                        access_mode::read);

        // access sparse matrix
        ArrayHandle<double> d_sparse_val(m_sparse_val,
                                         access_location::device,
                                         access_mode::overwrite);
        ArrayHandle<int> d_sparse_idxlookup(m_sparse_idxlookup,
                                            access_location::device,
                                            access_mode::read);

        // launch GPU kernel
        m_tuner_fill->begin();
        gpu_fill_matrix_vector(n_constraint,
                               m_pdata->getN() + m_pdata->getNGhosts(),
                               d_cmatrix.data,
                               d_cvec.data,
                               d_sparse_val.data,
                               d_sparse_idxlookup.data,
                               m_condition.getDeviceFlags(),
                               m_rel_tol,
                               m_constraint_violated.getDeviceFlags(),
                               d_pos.data,
                               d_vel.data,
                               d_netforce.data,
                               d_gpu_clist.data,
                               gpu_table_indexer,
                               d_gpu_n_constraints.data,
                               d_gpu_cpos.data,
                               d_group_typeval.data,
                               m_deltaT,
                               m_pdata->getBox(),
                               m_tuner_fill->getParam());

        if (m_exec_conf->isCUDAErrorCheckingEnabled())
            CHECK_CUDA_ERROR();

        m_tuner_fill->end();
        }

    if (m_prof)
        m_prof->pop(m_exec_conf);
    }

void ForceDistanceConstraintGPU::solveConstraints(uint64_t timestep)
    {
    // ==1 if the sparsity pattern of the matrix changes (in particular if connectivity changes)
    unsigned int sparsity_pattern_changed = m_condition.readFlags();

#ifndef CUSOLVER_AVAILABLE
    if (!sparsity_pattern_changed)
        {
        // copy new sparse values to host sparse matrix
        ArrayHandle<double> h_sparse_val(m_sparse_val, access_location::device, access_mode::read);
        hipMemcpy(m_sparse.valuePtr(),
                  h_sparse_val.data,
                  sizeof(double) * m_sparse.data().size(),
                  hipMemcpyDeviceToHost);
        }

    // solve on CPU
    ForceDistanceConstraint::solveConstraints(timestep);

    // a sparse matrix should have been constructed, resize values array
    m_sparse_val.resize(m_sparse.data().size());
#else

    unsigned int n_constraint = m_cdata->getN() + m_cdata->getNGhosts();

    // skip if zero constraints
    if (n_constraint == 0)
        return;

    if (m_prof)
        m_prof->push(m_exec_conf, "solve");

    // reallocate array of constraint forces
    m_lagrange.resize(n_constraint);

    // resize sparse matrix storage
    m_nnz.resize(n_constraint);

    if (sparsity_pattern_changed)
        {
        // reset flags
        m_condition.resetFlags(0);

            {
            // access matrix and vector
            ArrayHandle<double> d_cmatrix(m_cmatrix, access_location::device, access_mode::read);
            ArrayHandle<double> d_cvec(m_cvec, access_location::device, access_mode::read);

            // access sparse matrix structural data
            ArrayHandle<int> d_nnz(m_nnz, access_location::device, access_mode::overwrite);

            m_nnz_tot = 0;

            // count non zeros
            gpu_count_nnz(n_constraint,
                          d_cmatrix.data,
                          d_nnz.data,
                          m_nnz_tot,
                          m_cusparse_handle,
                          m_cusparse_mat_descr);

            if (m_exec_conf->isCUDAErrorCheckingEnabled())
                CHECK_CUDA_ERROR();
            }

        m_csr_rowptr.resize(n_constraint + 1);
        m_csr_colind.resize(m_nnz_tot);
        m_sparse_val.resize(m_nnz_tot);

            {
            // access matrix and vector
            ArrayHandle<double> d_cmatrix(m_cmatrix, access_location::device, access_mode::read);
            ArrayHandle<double> d_cvec(m_cvec, access_location::device, access_mode::read);

            // access sparse matrix structural data
            ArrayHandle<int> d_nnz(m_nnz, access_location::device, access_mode::overwrite);
            ArrayHandle<int> d_csr_colind(m_csr_colind,
                                          access_location::device,
                                          access_mode::overwrite);
            ArrayHandle<int> d_csr_rowptr(m_csr_rowptr,
                                          access_location::device,
                                          access_mode::overwrite);
            ArrayHandle<double> d_sparse_val(m_sparse_val,
                                             access_location::device,
                                             access_mode::overwrite);

            // count zeros and convert matrix
            gpu_dense2sparse(n_constraint,
                             d_cmatrix.data,
                             d_nnz.data,
                             m_cusparse_handle,
                             m_cusparse_mat_descr,
                             d_csr_rowptr.data,
                             d_csr_colind.data,
                             d_sparse_val.data);

            if (m_exec_conf->isCUDAErrorCheckingEnabled())
                CHECK_CUDA_ERROR();
            }

            {
            ArrayHandle<int> h_sparse_idxlookup(m_sparse_idxlookup,
                                                access_location::host,
                                                access_mode::overwrite);
            ArrayHandle<int> h_csr_rowptr(m_csr_rowptr, access_location::host, access_mode::read);
            ArrayHandle<int> h_csr_colind(m_csr_colind, access_location::host, access_mode::read);

            // reset lookup matrix values to -1
            for (unsigned int i = 0; i < n_constraint * n_constraint; ++i)
                {
                h_sparse_idxlookup.data[i] = -1;
                }

            // construct lookup table
            unsigned int k = 0;
            for (unsigned int i = 0; i < n_constraint; ++i)
                {
                unsigned int start_idx = h_csr_rowptr.data[i];
                unsigned int end_idx = h_csr_rowptr.data[i + 1];
                for (unsigned l = k; l < k + end_idx - start_idx; ++l)
                    {
                    // matrix is column-major
                    unsigned int j = h_csr_colind.data[l];

                    // set pointer to index in sparse_val
                    h_sparse_idxlookup.data[j * n_constraint + i] = l;
                    }

                k += end_idx - start_idx;
                }
            }

        m_exec_conf->msg->notice(6)
            << "ForceDistanceConstraintGPU: sparsity pattern changed. Solving on CPU" << std::endl;

        if (m_prof)
            m_prof->push(m_exec_conf, "CPU LU");

        /*
         * re-initialize sparse matrix solver on host
         */

        // access sparse matrix on host
        ArrayHandle<int> h_csr_colind(m_csr_colind, access_location::host, access_mode::read);
        ArrayHandle<int> h_csr_rowptr(m_csr_rowptr, access_location::host, access_mode::read);
        ArrayHandle<double> h_sparse_val(m_sparse_val, access_location::host, access_mode::read);

        // resize permutation matrix
        m_Qreorder.resize(n_constraint);

        // initialize cuSolver
        cusolverSpCreate(&m_cusolver_sp_handle);

        // determine reordering matrixQ to minimize zero fill-in
        cusolverSpXcsrsymrcmHost(m_cusolver_sp_handle,
                                 n_constraint,
                                 m_nnz_tot,
                                 m_cusparse_mat_descr,
                                 h_csr_rowptr.data,
                                 h_csr_colind.data,
                                 &m_Qreorder.front());

        // get size of scratch space for permutation B=Q*A*Q^T
        size_t size_perm = 0;
        cusolverSpXcsrperm_bufferSizeHost(m_cusolver_sp_handle,
                                          n_constraint,
                                          n_constraint,
                                          m_nnz_tot,
                                          m_cusparse_mat_descr,
                                          h_csr_rowptr.data,
                                          h_csr_colind.data,
                                          &m_Qreorder.front(),
                                          &m_Qreorder.front(),
                                          &size_perm);

        // identity mapping
        m_mapBfromA.resize(m_nnz_tot);
        for (int i = 0; i < m_nnz_tot; ++i)
            {
            m_mapBfromA[i] = i;
            }

        // allocate scratch space
        m_reorder_work.resize(size_perm);

        // resize B matrix
        m_csr_rowptr_B.resize(n_constraint + 1);
        m_csr_colind_B.resize(m_nnz_tot);
        m_csr_val_B.resize(m_nnz_tot);

        // copy over A values
        memcpy(&m_csr_rowptr_B.front(), h_csr_rowptr.data, sizeof(int) * (n_constraint + 1));
        memcpy(&m_csr_colind_B.front(), h_csr_colind.data, sizeof(int) * m_nnz_tot);

        // apply permutation
        cusolverSpXcsrpermHost(m_cusolver_sp_handle,
                               n_constraint,
                               n_constraint,
                               m_nnz_tot,
                               m_cusparse_mat_descr,
                               &m_csr_rowptr_B.front(),
                               &m_csr_colind_B.front(),
                               &m_Qreorder.front(),
                               &m_Qreorder.front(),
                               &m_mapBfromA.front(),
                               &m_reorder_work.front());

        // B = A(mapBfromA)
        for (int i = 0; i < m_nnz_tot; ++i)
            {
            m_csr_val_B[i] = h_sparse_val.data[m_mapBfromA[i]];
            }

        /*
         * solve A*x = b using LU(B)
         */

        // create data structure for LU factorization
        cusolverSpCreateCsrluInfoHost(&m_cusolver_csrlu_info);

        // analyze
        cusolverSpXcsrluAnalysisHost(m_cusolver_sp_handle,
                                     n_constraint,
                                     m_nnz_tot,
                                     m_cusparse_mat_descr,
                                     &m_csr_rowptr_B.front(),
                                     &m_csr_colind_B.front(),
                                     m_cusolver_csrlu_info);

        size_t size_internal = 0;
        size_t size_lu = 0;

        // workspace
        cusolverSpDcsrluBufferInfoHost(m_cusolver_sp_handle,
                                       n_constraint,
                                       m_nnz_tot,
                                       m_cusparse_mat_descr,
                                       &m_csr_val_B.front(),
                                       &m_csr_rowptr_B.front(),
                                       &m_csr_colind_B.front(),
                                       m_cusolver_csrlu_info,
                                       &size_internal,
                                       &size_lu);

        // reallocate
        m_lu_work.resize(size_lu);

        // solve
        const double pivot_thresh(1.0);

        cusolverSpDcsrluFactorHost(m_cusolver_sp_handle,
                                   n_constraint,
                                   m_nnz_tot,
                                   m_cusparse_mat_descr,
                                   &m_csr_val_B.front(),
                                   &m_csr_rowptr_B.front(),
                                   &m_csr_colind_B.front(),
                                   m_cusolver_csrlu_info,
                                   pivot_thresh,
                                   &m_lu_work.front());

        // check for singularity
        const double tol(1e-14);
        int singularity = 0;

        cusolverSpDcsrluZeroPivotHost(m_cusolver_sp_handle,
                                      m_cusolver_csrlu_info,
                                      tol,
                                      &singularity);

        if (0 <= singularity)
            {
            m_exec_conf->msg->error() << "Singular constraint matrix." << std::endl;
            throw std::runtime_error("Error computing constraint forces\n");
            }

        /*
         * extract P, Q, L and U from P*B*Q^T = L*U
         * L has unit diagonal
         */
        cusolverSpXcsrluNnzHost(m_cusolver_sp_handle,
                                &m_nnz_L_tot,
                                &m_nnz_U_tot,
                                m_cusolver_csrlu_info);

        // reallocate
        m_Plu.resize(n_constraint);
        m_Qlu.resize(n_constraint);

        m_csr_val_L.resize(m_nnz_L_tot);
        m_csr_rowptr_L.resize(n_constraint + 1);
        m_csr_colind_L.resize(m_nnz_L_tot);

        m_csr_val_U.resize(m_nnz_U_tot);
        m_csr_rowptr_U.resize(n_constraint + 1);
        m_csr_colind_U.resize(m_nnz_U_tot);

        // access L, U sparse matrices on host
        ArrayHandle<double> h_csr_val_L(m_csr_val_L, access_location::host, access_mode::overwrite);
        ArrayHandle<int> h_csr_rowptr_L(m_csr_rowptr_L,
                                        access_location::host,
                                        access_mode::overwrite);
        ArrayHandle<int> h_csr_colind_L(m_csr_colind_L,
                                        access_location::host,
                                        access_mode::overwrite);

        ArrayHandle<double> h_csr_val_U(m_csr_val_U, access_location::host, access_mode::overwrite);
        ArrayHandle<int> h_csr_rowptr_U(m_csr_rowptr_U,
                                        access_location::host,
                                        access_mode::overwrite);
        ArrayHandle<int> h_csr_colind_U(m_csr_colind_U,
                                        access_location::host,
                                        access_mode::overwrite);

        // extract
        cusolverSpDcsrluExtractHost(m_cusolver_sp_handle,
                                    &m_Plu.front(),
                                    &m_Qlu.front(),
                                    m_cusparse_mat_descr_L,
                                    h_csr_val_L.data,
                                    h_csr_rowptr_L.data,
                                    h_csr_colind_L.data,
                                    m_cusparse_mat_descr_U,
                                    h_csr_val_U.data,
                                    h_csr_rowptr_U.data,
                                    h_csr_colind_U.data,
                                    m_cusolver_csrlu_info,
                                    &m_lu_work.front());

        // clean up cusolverSp
        cusolverSpDestroyCsrluInfoHost(m_cusolver_csrlu_info);
        cusolverSpDestroy(m_cusolver_sp_handle);

        /* P = Plu*Qreorder
         * Q = Qlu*Qreorder
         *
         * then the factorization is complete (P*A*Q^T = L*U)
         */

        // reallocate
        m_P.resize(n_constraint);
        m_Q.resize(n_constraint);

        // access P,Q
        ArrayHandle<int> h_P(m_P, access_location::host, access_mode::overwrite);
        ArrayHandle<int> h_Q(m_Q, access_location::host, access_mode::overwrite);

        // P = Plu*Qreorder
        // Q = Qlu*Qreorder
        for (unsigned int i = 0; i < n_constraint; ++i)
            {
            h_P.data[i] = m_Qreorder[m_Plu[i]];
            h_Q.data[i] = m_Qreorder[m_Qlu[i]];
            }

        if (!m_cusolver_rf_initialized)
            {
            // initialize cusolverRF
            cusolverRfCreate(&m_cusolver_rf_handle);
            m_cusolver_rf_initialized = true;

            // set parameters
            // nzero is the value below which zero pivot is flagged.
            // nboost is the value which is substituted for zero pivot.
            double nzero = 0.0;
            double nboost = 0.0;

            cusolverRfSetNumericProperties(m_cusolver_rf_handle, nzero, nboost);

            // choose algorithm
            const cusolverRfFactorization_t fact_alg = CUSOLVERRF_FACTORIZATION_ALG0; // default
            const cusolverRfTriangularSolve_t solve_alg
                = CUSOLVERRF_TRIANGULAR_SOLVE_ALG1; // default

            cusolverRfSetAlgs(m_cusolver_rf_handle, fact_alg, solve_alg);

            // matrix mode: L and U are CSR, L has implicit unit diagonal
            cusolverRfSetMatrixFormat(m_cusolver_rf_handle,
                                      CUSOLVERRF_MATRIX_FORMAT_CSR,
                                      CUSOLVERRF_UNIT_DIAGONAL_ASSUMED_L);

            // fast mode for matrix assembling (I found it to crash on my notebook)
            // cusolverRfSetResetValuesFastMode(m_cusolver_rf_handle,
            // CUSOLVERRF_RESET_VALUES_FAST_MODE_ON);
            }

        /*
         * assemble P*A*Q = L*U
         */
        cusolverRfSetupHost(n_constraint,
                            m_nnz_tot,
                            h_csr_rowptr.data,
                            h_csr_colind.data,
                            h_sparse_val.data,
                            m_nnz_L_tot,
                            h_csr_rowptr_L.data,
                            h_csr_colind_L.data,
                            h_csr_val_L.data,
                            m_nnz_U_tot,
                            h_csr_rowptr_U.data,
                            h_csr_colind_U.data,
                            h_csr_val_U.data,
                            h_P.data,
                            h_Q.data,
                            m_cusolver_rf_handle);

        /*
         * analyze sparsity pattern
         */
        cusolverRfAnalyze(m_cusolver_rf_handle);

        if (m_prof)
            m_prof->pop(m_exec_conf);

        } // end if sparsity pattern changed

    if (m_prof)
        m_prof->push(m_exec_conf, "refactor");

    // reallocate work space for cusolverRf
    m_T.resize(n_constraint);

    // access sparse matrix structural data
    ArrayHandle<int> d_csr_colind(m_csr_colind, access_location::device, access_mode::read);
    ArrayHandle<int> d_csr_rowptr(m_csr_rowptr, access_location::device, access_mode::read);
    ArrayHandle<double> d_sparse_val(m_sparse_val, access_location::device, access_mode::read);

    // permutations
    ArrayHandle<int> d_P(m_P, access_location::device, access_mode::read);
    ArrayHandle<int> d_Q(m_Q, access_location::device, access_mode::read);

    // import matrix to cusolverRf
    cusolverRfResetValues(n_constraint,
                          m_nnz_tot,
                          d_csr_rowptr.data,
                          d_csr_colind.data,
                          d_sparse_val.data,
                          d_P.data,
                          d_Q.data,
                          m_cusolver_rf_handle);

    // refactor using updated values
    cusolverRfRefactor(m_cusolver_rf_handle);

    // solve A*x = b

    // access work space
    ArrayHandle<double> d_T(m_T, access_location::device, access_mode::readwrite);

    // access solution vector
    ArrayHandle<double> d_lagrange(m_lagrange, access_location::device, access_mode::overwrite);

    // copy RHS into solution vector
    ArrayHandle<double> d_vec(m_cvec, access_location::device, access_mode::read);
    hipMemcpy(d_lagrange.data, d_vec.data, sizeof(double) * n_constraint, hipMemcpyDeviceToDevice);

    int nrhs = 1;
    // solve
    cusolverRfSolve(m_cusolver_rf_handle,
                    d_P.data,
                    d_Q.data,
                    nrhs,
                    d_T.data,
                    n_constraint,
                    d_lagrange.data,
                    n_constraint);

    if (m_prof)
        m_prof->pop(m_exec_conf);

    if (m_prof)
        m_prof->pop(m_exec_conf);
#endif
    }

void ForceDistanceConstraintGPU::computeConstraintForces(uint64_t timestep)
    {
    if (m_prof)
        m_prof->push(m_exec_conf, "constraint forces");

    // access solution vector
    ArrayHandle<double> d_lagrange(m_lagrange, access_location::device, access_mode::read);

    // access particle data arrays
    ArrayHandle<Scalar4> d_pos(m_pdata->getPositions(), access_location::device, access_mode::read);

    // access force and virial arrays
    ArrayHandle<Scalar4> d_force(m_force, access_location::device, access_mode::overwrite);
    ArrayHandle<Scalar> d_virial(m_virial, access_location::device, access_mode::overwrite);

    // access GPU constraint table on device
    const GPUArray<ConstraintData::members_t>& gpu_constraint_list = this->m_cdata->getGPUTable();
    const Index2D& gpu_table_indexer = this->m_cdata->getGPUTableIndexer();

    ArrayHandle<ConstraintData::members_t> d_gpu_clist(gpu_constraint_list,
                                                       access_location::device,
                                                       access_mode::read);
    ArrayHandle<unsigned int> d_gpu_n_constraints(this->m_cdata->getNGroupsArray(),
                                                  access_location::device,
                                                  access_mode::read);
    ArrayHandle<unsigned int> d_gpu_cpos(m_cdata->getGPUPosTable(),
                                         access_location::device,
                                         access_mode::read);

    const BoxDim& box = m_pdata->getBox();

    unsigned int n_ptl = m_pdata->getN();

    // compute constraint forces by solving linear system of equations
    m_tuner_force->begin();
    gpu_compute_constraint_forces(d_pos.data,
                                  d_gpu_clist.data,
                                  gpu_table_indexer,
                                  d_gpu_n_constraints.data,
                                  d_gpu_cpos.data,
                                  d_force.data,
                                  d_virial.data,
                                  m_virial_pitch,
                                  box,
                                  n_ptl,
                                  m_tuner_force->getParam(),
                                  d_lagrange.data);

    if (m_exec_conf->isCUDAErrorCheckingEnabled())
        CHECK_CUDA_ERROR();

    m_tuner_force->end();

    if (m_prof)
        m_prof->pop(m_exec_conf);
    }

void export_ForceDistanceConstraintGPU(py::module& m)
    {
    py::class_<ForceDistanceConstraintGPU,
               ForceDistanceConstraint,
               std::shared_ptr<ForceDistanceConstraintGPU>>(m, "ForceDistanceConstraintGPU")
        .def(py::init<std::shared_ptr<SystemDefinition>>());
    }


text:
Supporting enumerations in Rails has up to now always been done on the application layer.

The [symbolize](https://github.com/nofxx/symbolize) gem allows storing a limited set of different string values to a field. On a database level it is still possible to store abritrary strings.

Rails 4.1 introduced [enums](http://api.rubyonrails.org/v4.1.0/classes/ActiveRecord/Enum.html) which fulfils the same purpose but stores the different types as integers. The mapping, validation is also handled on the application layer. And even worse in order to query for a specific enum it is necessary to lookup the according values for each query:

    Conversation.where(status: Conversation.statuses[:archived])

This gem takes advantage of the [PostgreSQL enum type](http://www.postgresql.org/docs/9.1/static/datatype-enum.html) that will handle all the validations:

    Conversation.where(status: :archived)

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'activerecord-real_enums'
```

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install activerecord-real_enums

## Usage

### Migrations

To be able to use PostgreSQL enums, I suggest to create the according type in a separate migration:

    class CreateConversationStatusEnum < ActiveRecord::Migration
      def up
        execute "CREATE TYPE conversation_status AS ENUM ("active", "archived");"
      end

      def down
        execute "DROP TYPE conversation_status;"
      end
    end

from then on, the type `conversation_status` can be used as a regular type:

    class AddColumnsToTeam < ActiveRecord::Migration
      def change
        add_column :conversations, :status, :conversation_status
      end
    end

### Model

To reference the type correctly (e.g. for queries) the enum needs to be added to the model:

    class Converation < ActiveRecord::Base
      real_enum :status, type: :conversation_status
    end

`real_enums` will add the necessary validations in the background.

From then on, it is possible to query all conversations by status:

    Conversation.where(status: :archived) # strings and symbols, both work

## Caveats

This is a first draft. Completely usable but not feature complete:

  - no posibility to query all available values for enum
  - currently only support for PostgreSQL (although [MySQL](http://dev.mysql.com/doc/refman/5.0/en/enum.html) also has an enum type)
  - no helper methods for migration (AFAIK not officically supported to write own migration methods (that are reversible))

## Contributing

1. Fork it ( https://github.com/[my-github-username]/activerecord-real_enums/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <title>GridFy - Flexible and Performatic Grid system</title>
  <link type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.min.css" rel="stylesheet">
  <link type="text/css" href="//fonts.googleapis.com/css?family=Roboto:400,300,500" rel="stylesheet">
  <link type="text/css" href="./dist/demo.css" rel="stylesheet">
  <link type="text/css" href="./dist/no-flexbox.css" rel="stylesheet">

GridFy

Flexible and Performatic Grid system

        No using flexbox
        Using flexbox

        Tweet

by nandomoreira.me


text:
package org.jetbrains.plugins.scala.codeInsight.unwrap

import com.intellij.codeInsight.CodeInsightBundle
import com.intellij.psi.PsiElement
import org.jetbrains.plugins.scala.lang.psi.api.expr.{ScExpression, ScIf}

import java.util

class ScalaElseUnwrapper extends ScalaElseUnwrapperBase {
  override protected def unwrapElseBranch(expr: ScExpression, ifStmt: ScIf, context: ScalaUnwrapContext): Unit = {
    val from = maxIfStmt(ifStmt)
    val branch = expr match {
      case ScIf(_, Some(thenBr), _) => thenBr
      case _ => expr
    }
    context.extractBlockOrSingleStatement(branch, from)
    context.delete(from)
  }

  override def getDescription(e: PsiElement): String = CodeInsightBundle.message("unwrap.else")

  override def collectAffectedElements(e: PsiElement, toExtract: util.List[PsiElement]): PsiElement = elseBranch(e) match {
    case Some((ifStmt: ScIf, _)) =>
      super.collectAffectedElements(e, toExtract)
      maxIfStmt(ifStmt)
    case _ => e
  }
}


text:
class CreateExportBankFileRows < ActiveRecord::Migration
  def change
    create_table :export_bank_file_rows do |t|
      t.datetime :posting_date
      t.decimal  :amount, precision: 9, scale: 2
      t.string   :bankgiro
      t.string   :plusgiro
      t.string   :clearingnumber
      t.string   :bank_account
      t.string   :ocr
      t.string   :name
      t.string   :reference
      t.datetime :bank_date
      t.string   :currency_paid
      t.string   :currency_debit
      t.integer  :organization_id
      t.integer  :export_bank_file_id
      t.timestamps
    end
  end
end