/** * \file internal/particle_quad_helpers.h * \brief A container for Quads. * * This file is generated by a script (core/tools/make-container). * Do not edit directly. * * Copyright 2007-2010 IMP Inventors. All rights reserved. */ #ifndef IMPCORE_INTERNAL_QUAD_HELPERS_H #define IMPCORE_INTERNAL_QUAD_HELPERS_H #include "../core_config.h" #include #include #include #include #include #include IMP_BEGIN_INTERNAL_NAMESPACE template struct SimpleRestraintParentTraits >::type> { typedef IMP::QuadScoreRestraint SimpleRestraint; typedef IMP::QuadsScoreRestraint SimplesRestraint; }; IMP_END_INTERNAL_NAMESPACE IMPCORE_BEGIN_INTERNAL_NAMESPACE class IMPCOREEXPORT ListLikeQuadContainer: public QuadContainer { private: ParticleQuads data_; mutable ParticleQuadsTemp index_; void update_index() const { if (index_.size()==data_.size()) return; unsigned int osize=index_.size(); index_.insert(index_.end(), data_.begin()+osize, data_.end()); std::sort(index_.begin()+osize, index_.end()); std::inplace_merge(index_.begin(), index_.begin()+osize, index_.end()); } protected: ListLikeQuadContainer *get_added() const { if (get_has_added_and_removed_containers()) { return dynamic_cast (get_added_container()); } else { return NULL; } } ListLikeQuadContainer *get_removed() const { return dynamic_cast (get_removed_container()); } ListLikeQuadContainer(){} void update_list(ParticleQuadsTemp &cur) { index_.clear(); IMP_IF_CHECK(USAGE) { for (unsigned int i=0; i< cur.size(); ++i) { IMP_USAGE_CHECK( IMP::internal::is_valid(cur[i]), "Passed Quad cannot be NULL (or None)"); } } if (get_added()) { std::sort(cur.begin(), cur.end()); std::sort(data_.begin(), data_.end()); ParticleQuadsTemp added, removed; std::set_difference(cur.begin(), cur.end(), data_.begin(), data_.end(), std::back_inserter(added)); std::set_difference(data_.begin(), data_.end(), cur.begin(), cur.end(), std::back_inserter(removed)); get_added()->data_=added; get_removed()->data_=removed; } swap(data_, cur); } void add_to_list(ParticleQuadsTemp &cur) { std::sort(cur.begin(), cur.end()); ParticleQuadsTemp added; std::set_difference(cur.begin(), cur.end(), data_.begin(), data_.end(), std::back_inserter(added)); data_.insert(data_.end(), added.begin(), added.end()); if (get_added()) { ListLikeQuadContainer* ac=get_added(); ac->data_.insert(ac->data_.end(), added.begin(), added.end()); } } void remove_from_list(ParticleQuadsTemp &cur) { index_.clear(); std::sort(cur.begin(), cur.end()); ParticleQuadsTemp newlist; std::set_difference(data_.begin(), data_.end(), cur.begin(), cur.end(), std::back_inserter(newlist)); swap(data_, newlist); if (get_has_added_and_removed_containers()) { ListLikeQuadContainer* ac=get_removed(); ac->data_.insert(ac->data_.end(), cur.begin(), cur.end()); } } void add_to_list(const ParticleQuad& cur) { data_.push_back(cur); if (get_added()) { ListLikeQuadContainer* ac=get_added(); ac->data_.push_back(cur); } } ListLikeQuadContainer(Model *m, std::string name): QuadContainer(m,name){ } template void apply_to_contents(F f) const { #if BOOST_VERSION > 103500 std::for_each(data_.begin(), data_.end(), f); #else for (unsigned int i=0; i< data_.size(); ++i) { ParticleQuad v= data_[i]; f(v); } #endif } template typename F::result_type accumulate_over_contents(F f) const { typename F::result_type ret=0; for (unsigned int i=0; i< data_.size(); ++i) { #if BOOST_VERSION > 103500 ret+= f(data_[i]); #else ParticleQuad v= data_[i]; ret+=f(v); #endif } return ret; } public: template void template_apply(const SM *sm, DerivativeAccumulator &da) { apply_to_contents(boost::bind(static_cast (&QuadModifier::apply), sm, _1, da)); } template void template_apply(const SM *sm) { apply_to_contents(boost::bind(static_cast(&QuadModifier::apply), sm, _1)); } template double template_evaluate(const SS *s, DerivativeAccumulator *da) const { return accumulate_over_contents(boost::bind(static_cast (&QuadScore::evaluate), s, _1, da)); } template double template_evaluate_change(const SS *s, DerivativeAccumulator *da) const { return accumulate_over_contents(boost::bind(static_cast (&QuadScore::evaluate_change), s, _1, da)); } template double template_evaluate_prechange(const SS *s, DerivativeAccumulator *da) const { return accumulate_over_contents(boost::bind(static_cast (&QuadScore::evaluate_prechange), s, _1, da)); } void apply(const QuadModifier *sm) { sm->apply(data_); } void apply(const QuadModifier *sm, DerivativeAccumulator &da) { sm->apply(data_, da); } double evaluate(const QuadScore *s, DerivativeAccumulator *da) const { return s->evaluate(data_, da); } double evaluate_change(const QuadScore *s, DerivativeAccumulator *da) const { return s->evaluate_change(data_, da); } double evaluate_prechange(const QuadScore *s, DerivativeAccumulator *da) const { return s->evaluate_prechange(data_, da); } ParticlesTemp get_contained_particles() const; bool get_contained_particles_changed() const; QuadContainerPair get_added_and_removed_containers() const; bool get_contains_particle_quad(const ParticleQuad& p) const; unsigned int get_number_of_particle_quads() const; ParticleQuad get_particle_quad(unsigned int i) const; IMP_OBJECT(ListLikeQuadContainer); typedef ParticleQuads::const_iterator ParticleQuadIterator; ParticleQuadIterator particle_quads_begin() const { return data_.begin(); } ParticleQuadIterator particle_quads_end() const { return data_.end(); } ObjectsTemp get_input_objects() const; void do_after_evaluate() { if (get_added()) { get_added()->data_.clear(); get_removed()->data_.clear(); } } void do_before_evaluate() { std::remove_if(data_.begin(), data_.end(), IMP::internal::IsInactive()); } bool get_is_up_to_date() const {return true;} bool get_provides_access() const {return true;} const ParticleQuadsTemp& get_access() const { IMP_INTERNAL_CHECK(get_is_up_to_date(), "Container is out of date"); return data_; } }; IMPCORE_END_INTERNAL_NAMESPACE #define IMP_LISTLIKE_QUAD_CONTAINER(Name) \ IMP_OBJECT(Name) #endif /* IMPCORE_INTERNAL_QUAD_HELPERS_H */