/*-----------------------------------------------------------------------------+ Copyright (c) 2008-2012: Joachim Faulhaber +------------------------------------------------------------------------------+ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENCE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +-----------------------------------------------------------------------------*/ #ifndef BOOST_ICL_INTERVAL_MAP_HPP_JOFA_080705 #define BOOST_ICL_INTERVAL_MAP_HPP_JOFA_080705 #include #include #include #include namespace boost{namespace icl { template class split_interval_map; /** \brief implements a map as a map of intervals - on insertion overlapping intervals are split and associated values are combined.*/ template < typename DomainT, typename CodomainT, class Traits = icl::partial_absorber, ICL_COMPARE Compare = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT), ICL_COMBINE Combine = ICL_COMBINE_INSTANCE(icl::inplace_plus, CodomainT), ICL_SECTION Section = ICL_SECTION_INSTANCE(icl::inter_section, CodomainT), ICL_INTERVAL(ICL_COMPARE) Interval = ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, DomainT, Compare), ICL_ALLOC Alloc = std::allocator > class interval_map: public interval_base_map, DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> { public: typedef Traits traits; typedef interval_map type; typedef split_interval_map split_type; typedef type overloadable_type; typedef type joint_type; typedef interval_base_map base_type; typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type; typedef typename base_type::iterator iterator; typedef typename base_type::value_type value_type; typedef typename base_type::element_type element_type; typedef typename base_type::segment_type segment_type; typedef typename base_type::domain_type domain_type; typedef typename base_type::codomain_type codomain_type; typedef typename base_type::domain_mapping_type domain_mapping_type; typedef typename base_type::interval_mapping_type interval_mapping_type; typedef typename base_type::ImplMapT ImplMapT; typedef typename base_type::size_type size_type; typedef typename base_type::codomain_combine codomain_combine; typedef interval_set interval_set_type; typedef interval_set_type set_type; typedef set_type key_object_type; enum { fineness = 1 }; public: //========================================================================== //= Construct, copy, destruct //========================================================================== /// Default constructor for the empty object interval_map(): base_type() {} /// Copy constructor interval_map(const interval_map& src): base_type(src) {} /// Copy constructor for base_type template explicit interval_map (const interval_base_map& src) { this->assign(src); } explicit interval_map(const domain_mapping_type& base_pair): base_type() { this->add(base_pair); } explicit interval_map(const value_type& value_pair): base_type() { this->add(value_pair); } /// Assignment from a base interval_map. template void assign(const interval_base_map& src) { typedef interval_base_map base_map_type; this->clear(); iterator prior_ = this->_map.end(); ICL_const_FORALL(typename base_map_type, it_, src) prior_ = this->add(prior_, *it_); } /// Assignment operator for base type template interval_map& operator = (const interval_base_map& src) { this->assign(src); return *this; } # ifndef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES //========================================================================== //= Move semantics //========================================================================== /// Move constructor interval_map(interval_map&& src) : base_type(boost::move(src)) {} /// Move assignment operator interval_map& operator = (interval_map src) { base_type::operator=(boost::move(src)); return *this; } //========================================================================== # else /// Assignment operator interval_map& operator = (const interval_map& src) { base_type::operator=(src); return *this; } # endif // BOOST_ICL_NO_CXX11_RVALUE_REFERENCES private: // Private functions that shall be accessible by the baseclass: friend class interval_base_map , DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>; iterator handle_inserted(iterator it_) { return segmental::join_neighbours(*this, it_); } void handle_inserted(iterator prior_, iterator it_) { if(prior_ != this->_map.end() && segmental::joinable(*this, prior_, it_)) segmental::join_on_right(*this, prior_, it_); } template void handle_left_combined(iterator it_) { if(on_absorbtion::is_absorbable((*it_).second)) this->_map.erase(it_); else segmental::join_left(*this, it_); } template void handle_combined(iterator it_) { if(on_absorbtion::is_absorbable((*it_).second)) this->_map.erase(it_); else segmental::join_neighbours(*this, it_); } template void handle_preceeded_combined(iterator prior_, iterator& it_) { if(on_absorbtion::is_absorbable((*it_).second)) { this->_map.erase(it_); it_ = prior_; } else // After a new combination (e.g. combiner=max) joining neighbours may be possible segmental::join_neighbours(*this, it_); } template void handle_succeeded_combined(iterator it_, iterator next_) { if(on_absorbtion::is_absorbable((*it_).second)) { this->_map.erase(it_); segmental::join_right(*this, next_); } else { segmental::join_left(*this, it_); segmental::join_neighbours(*this, next_); } } void handle_reinserted(iterator insertion_) { segmental::join_right(*this, insertion_); } template void gap_insert_at(iterator& it_, iterator prior_, const interval_type& end_gap, const codomain_type& co_val) { if(on_absorbtion::is_absorbable((*it_).second)) { this->_map.erase(it_); it_ = this->template gap_insert(prior_, end_gap, co_val); segmental::join_right(*this, it_); } else { segmental::join_left(*this, it_); iterator inserted_ = this->template gap_insert(it_, end_gap, co_val); it_ = segmental::join_neighbours(*this, inserted_); } } } ; //----------------------------------------------------------------------------- // type traits //----------------------------------------------------------------------------- template struct is_map > { typedef is_map > type; BOOST_STATIC_CONSTANT(bool, value = true); }; template struct has_inverse > { typedef has_inverse > type; BOOST_STATIC_CONSTANT(bool, value = (has_inverse::value)); }; template struct is_interval_container > { typedef is_interval_container > type; BOOST_STATIC_CONSTANT(bool, value = true); }; template struct absorbs_identities > { typedef absorbs_identities > type; BOOST_STATIC_CONSTANT(bool, value = (Traits::absorbs_identities)); }; template struct is_total > { typedef is_total > type; BOOST_STATIC_CONSTANT(bool, value = (Traits::is_total)); }; //----------------------------------------------------------------------------- // type representation //----------------------------------------------------------------------------- template struct type_to_string > { static std::string apply() { return "itv_map<"+ type_to_string::apply() + "," + type_to_string::apply() + "," + type_to_string::apply() + ">"; } }; }} // namespace icl boost #endif