Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:22

0001 /*-----------------------------------------------------------------------------+
0002 Copyright (c) 2007-2012: Joachim Faulhaber
0003 Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
0004 +------------------------------------------------------------------------------+
0005    Distributed under the Boost Software License, Version 1.0.
0006       (See accompanying file LICENCE.txt or copy at
0007            http://www.boost.org/LICENSE_1_0.txt)
0008 +-----------------------------------------------------------------------------*/
0009 #ifndef BOOST_ICL_INTERVAL_BASE_MAP_HPP_JOFA_990223
0010 #define BOOST_ICL_INTERVAL_BASE_MAP_HPP_JOFA_990223
0011 
0012 #include <limits>
0013 #include <boost/mpl/and.hpp>
0014 #include <boost/mpl/or.hpp>
0015 #include <boost/mpl/not.hpp>
0016 
0017 #include <boost/icl/detail/notate.hpp> 
0018 #include <boost/icl/detail/design_config.hpp>
0019 #include <boost/icl/detail/on_absorbtion.hpp>
0020 #include <boost/icl/detail/interval_map_algo.hpp>
0021 #include <boost/icl/detail/exclusive_less_than.hpp>
0022 
0023 #include <boost/icl/associative_interval_container.hpp>
0024 
0025 #include <boost/icl/type_traits/is_interval_splitter.hpp>
0026 #include <boost/icl/map.hpp>
0027 
0028 namespace boost{namespace icl
0029 {
0030 
0031 template<class DomainT, class CodomainT>
0032 struct mapping_pair
0033 {
0034     DomainT   key;
0035     CodomainT data;
0036 
0037     mapping_pair():key(), data(){}
0038 
0039     mapping_pair(const DomainT& key_value, const CodomainT& data_value)
0040         :key(key_value), data(data_value){}
0041 
0042     mapping_pair(const std::pair<DomainT,CodomainT>& std_pair)
0043         :key(std_pair.first), data(std_pair.second){}
0044 };
0045 
0046 /** \brief Implements a map as a map of intervals (base class) */
0047 template
0048 <
0049     class SubType,
0050     typename DomainT,
0051     typename CodomainT,
0052     class Traits = icl::partial_absorber,
0053     ICL_COMPARE Compare  = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT),
0054     ICL_COMBINE Combine  = ICL_COMBINE_INSTANCE(icl::inplace_plus, CodomainT),
0055     ICL_SECTION Section  = ICL_SECTION_INSTANCE(icl::inter_section, CodomainT), 
0056     ICL_INTERVAL(ICL_COMPARE) Interval = ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, DomainT, Compare),
0057     ICL_ALLOC   Alloc    = std::allocator
0058 >
0059 class interval_base_map
0060 {
0061 public:
0062     //==========================================================================
0063     //= Associated types
0064     //==========================================================================
0065     typedef interval_base_map<SubType,DomainT,CodomainT,
0066                               Traits,Compare,Combine,Section,Interval,Alloc>
0067                               type;
0068 
0069     /// The designated \e derived or \e sub_type of this base class
0070     typedef SubType sub_type;
0071 
0072     /// Auxilliary type for overloadresolution
0073     typedef type overloadable_type;
0074 
0075     /// Traits of an itl map
0076     typedef Traits traits;
0077 
0078     //--------------------------------------------------------------------------
0079     //- Associated types: Related types
0080     //--------------------------------------------------------------------------
0081     /// The atomized type representing the corresponding container of elements
0082     typedef typename icl::map<DomainT,CodomainT,
0083                               Traits,Compare,Combine,Section,Alloc> atomized_type;
0084 
0085     //--------------------------------------------------------------------------
0086     //- Associated types: Data
0087     //--------------------------------------------------------------------------
0088     /// Domain type (type of the keys) of the map
0089     typedef DomainT   domain_type;
0090     typedef typename boost::call_traits<DomainT>::param_type domain_param;
0091     /// Domain type (type of the keys) of the map
0092     typedef CodomainT codomain_type;
0093     /// Auxiliary type to help the compiler resolve ambiguities when using std::make_pair
0094     typedef mapping_pair<domain_type,codomain_type> domain_mapping_type;
0095     /// Conceptual is a map a set of elements of type \c element_type
0096     typedef domain_mapping_type element_type;
0097     /// The interval type of the map
0098     typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
0099     /// Auxiliary type for overload resolution
0100     typedef std::pair<interval_type,CodomainT> interval_mapping_type;
0101     /// Type of an interval containers segment, that is spanned by an interval
0102     typedef std::pair<interval_type,CodomainT> segment_type;
0103 
0104     //--------------------------------------------------------------------------
0105     //- Associated types: Size
0106     //--------------------------------------------------------------------------
0107     /// The difference type of an interval which is sometimes different form the domain_type
0108     typedef typename difference_type_of<domain_type>::type difference_type;
0109     /// The size type of an interval which is mostly std::size_t
0110     typedef typename size_type_of<domain_type>::type size_type;
0111 
0112     //--------------------------------------------------------------------------
0113     //- Associated types: Functors
0114     //--------------------------------------------------------------------------
0115     /// Comparison functor for domain values
0116     typedef ICL_COMPARE_DOMAIN(Compare,DomainT)      domain_compare;
0117     typedef ICL_COMPARE_DOMAIN(Compare,segment_type) segment_compare;
0118     /// Combine functor for codomain value aggregation
0119     typedef ICL_COMBINE_CODOMAIN(Combine,CodomainT)  codomain_combine;
0120     /// Inverse Combine functor for codomain value aggregation
0121     typedef typename inverse<codomain_combine>::type inverse_codomain_combine;
0122     /// Intersection functor for codomain values
0123 
0124     typedef typename mpl::if_
0125     <has_set_semantics<codomain_type>
0126     , ICL_SECTION_CODOMAIN(Section,CodomainT)     
0127     , codomain_combine
0128     >::type                                            codomain_intersect;
0129 
0130 
0131     /// Inverse Combine functor for codomain value intersection
0132     typedef typename inverse<codomain_intersect>::type inverse_codomain_intersect;
0133 
0134     /// Comparison functor for intervals which are keys as well
0135     typedef exclusive_less_than<interval_type> interval_compare;
0136 
0137     /// Comparison functor for keys
0138     typedef exclusive_less_than<interval_type> key_compare;
0139 
0140     //--------------------------------------------------------------------------
0141     //- Associated types: Implementation and stl related
0142     //--------------------------------------------------------------------------
0143     /// The allocator type of the set
0144     typedef Alloc<std::pair<const interval_type, codomain_type> > 
0145         allocator_type;
0146 
0147     /// Container type for the implementation 
0148     typedef ICL_IMPL_SPACE::map<interval_type,codomain_type,
0149                                 key_compare,allocator_type> ImplMapT;
0150 
0151     /// key type of the implementing container
0152     typedef typename ImplMapT::key_type   key_type;
0153     /// value type of the implementing container
0154     typedef typename ImplMapT::value_type value_type;
0155     /// data type of the implementing container
0156     typedef typename ImplMapT::value_type::second_type data_type;
0157 
0158     /// pointer type
0159     typedef typename ImplMapT::pointer         pointer;
0160     /// const pointer type
0161     typedef typename ImplMapT::const_pointer   const_pointer;
0162     /// reference type
0163     typedef typename ImplMapT::reference       reference;
0164     /// const reference type
0165     typedef typename ImplMapT::const_reference const_reference;
0166 
0167     /// iterator for iteration over intervals
0168     typedef typename ImplMapT::iterator iterator;
0169     /// const_iterator for iteration over intervals
0170     typedef typename ImplMapT::const_iterator const_iterator;
0171     /// iterator for reverse iteration over intervals
0172     typedef typename ImplMapT::reverse_iterator reverse_iterator;
0173     /// const_iterator for iteration over intervals
0174     typedef typename ImplMapT::const_reverse_iterator const_reverse_iterator;
0175 
0176     /// element iterator: Depreciated, see documentation.
0177     typedef boost::icl::element_iterator<iterator> element_iterator; 
0178     /// const element iterator: Depreciated, see documentation.
0179     typedef boost::icl::element_iterator<const_iterator> element_const_iterator; 
0180     /// element reverse iterator: Depreciated, see documentation.
0181     typedef boost::icl::element_iterator<reverse_iterator> element_reverse_iterator; 
0182     /// element const reverse iterator: Depreciated, see documentation.
0183     typedef boost::icl::element_iterator<const_reverse_iterator> element_const_reverse_iterator; 
0184     
0185     typedef typename on_absorbtion<type, codomain_combine, 
0186                                 Traits::absorbs_identities>::type on_codomain_absorbtion;
0187 
0188 public:
0189     BOOST_STATIC_CONSTANT(bool, 
0190         is_total_invertible = (   Traits::is_total 
0191                                && has_inverse<codomain_type>::value));
0192 
0193     BOOST_STATIC_CONSTANT(int, fineness = 0); 
0194 
0195 public:
0196 
0197     //==========================================================================
0198     //= Construct, copy, destruct
0199     //==========================================================================
0200     /** Default constructor for the empty object */
0201     interval_base_map()
0202     {
0203         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0204         BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0205         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
0206         BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
0207     }
0208 
0209     /** Copy constructor */
0210     interval_base_map(const interval_base_map& src): _map(src._map)
0211     {
0212         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0213         BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0214         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
0215         BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
0216     }
0217 
0218 #   ifndef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
0219     //==========================================================================
0220     //= Move semantics
0221     //==========================================================================
0222 
0223     /** Move constructor */
0224     interval_base_map(interval_base_map&& src): _map(boost::move(src._map))
0225     {
0226         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0227         BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0228         BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<CodomainT>));
0229         BOOST_CONCEPT_ASSERT((EqualComparableConcept<CodomainT>));
0230     }
0231 
0232     /** Move assignment operator */
0233     interval_base_map& operator = (interval_base_map src) 
0234     {                           //call by value sice 'src' is a "sink value" 
0235         this->_map = boost::move(src._map);
0236         return *this; 
0237     }
0238 
0239     //==========================================================================
0240 #   else 
0241 
0242     /** Copy assignment operator */
0243     interval_base_map& operator = (const interval_base_map& src) 
0244     { 
0245         this->_map = src._map;
0246         return *this; 
0247     }
0248 
0249 #   endif // BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
0250 
0251     /** swap the content of containers */
0252     void swap(interval_base_map& object) { _map.swap(object._map); }
0253 
0254     //==========================================================================
0255     //= Containedness
0256     //==========================================================================
0257     /** clear the map */
0258     void clear() { icl::clear(*that()); }
0259 
0260     /** is the map empty? */
0261     bool empty()const { return icl::is_empty(*that()); }
0262 
0263     //==========================================================================
0264     //= Size
0265     //==========================================================================
0266     /** An interval map's size is it's cardinality */
0267     size_type size()const
0268     {
0269         return icl::cardinality(*that());
0270     }
0271 
0272     /** Size of the iteration over this container */
0273     std::size_t iterative_size()const 
0274     { 
0275         return _map.size(); 
0276     }
0277 
0278     //==========================================================================
0279     //= Selection
0280     //==========================================================================
0281 
0282     /** Find the interval value pair, that contains \c key */
0283     const_iterator find(const domain_type& key_value)const
0284     { 
0285         return icl::find(*this, key_value);
0286     }
0287 
0288     /** Find the first interval value pair, that collides with interval 
0289         \c key_interval */
0290     const_iterator find(const interval_type& key_interval)const
0291     { 
0292         return _map.find(key_interval); 
0293     }
0294 
0295     /** Total select function. */
0296     codomain_type operator()(const domain_type& key_value)const
0297     {
0298         const_iterator it_ = icl::find(*this, key_value);
0299         return it_==end() ? identity_element<codomain_type>::value()
0300                           : (*it_).second;
0301     }
0302 
0303     //==========================================================================
0304     //= Addition
0305     //==========================================================================
0306 
0307     /** Addition of a key value pair to the map */
0308     SubType& add(const element_type& key_value_pair) 
0309     {
0310         return icl::add(*that(), key_value_pair);
0311     }
0312 
0313     /** Addition of an interval value pair to the map. */
0314     SubType& add(const segment_type& interval_value_pair) 
0315     {
0316         this->template _add<codomain_combine>(interval_value_pair);
0317         return *that();
0318     }
0319 
0320     /** Addition of an interval value pair \c interval_value_pair to the map. 
0321         Iterator \c prior_ is a hint to the position \c interval_value_pair can be 
0322         inserted after. */
0323     iterator add(iterator prior_, const segment_type& interval_value_pair) 
0324     {
0325         return this->template _add<codomain_combine>(prior_, interval_value_pair);
0326     }
0327 
0328     //==========================================================================
0329     //= Subtraction
0330     //==========================================================================
0331     /** Subtraction of a key value pair from the map */
0332     SubType& subtract(const element_type& key_value_pair)
0333     { 
0334         return icl::subtract(*that(), key_value_pair);
0335     }
0336 
0337     /** Subtraction of an interval value pair from the map. */
0338     SubType& subtract(const segment_type& interval_value_pair)
0339     {
0340         on_invertible<type, is_total_invertible>
0341             ::subtract(*that(), interval_value_pair);
0342         return *that();
0343     }
0344 
0345     //==========================================================================
0346     //= Insertion
0347     //==========================================================================
0348     /** Insertion of a \c key_value_pair into the map. */
0349     SubType& insert(const element_type& key_value_pair) 
0350     {
0351         return icl::insert(*that(), key_value_pair);
0352     }
0353 
0354     /** Insertion of an \c interval_value_pair into the map. */
0355     SubType& insert(const segment_type& interval_value_pair)
0356     { 
0357         _insert(interval_value_pair); 
0358         return *that();
0359     }
0360 
0361     /** Insertion of an \c interval_value_pair into the map. Iterator \c prior_. 
0362         serves as a hint to insert after the element \c prior point to. */
0363     iterator insert(iterator prior, const segment_type& interval_value_pair)
0364     { 
0365         return _insert(prior, interval_value_pair);
0366     }
0367 
0368     /** With <tt>key_value_pair = (k,v)</tt> set value \c v for key \c k */
0369     SubType& set(const element_type& key_value_pair) 
0370     { 
0371         return icl::set_at(*that(), key_value_pair);
0372     }
0373 
0374     /** With <tt>interval_value_pair = (I,v)</tt> set value \c v 
0375         for all keys in interval \c I in the map. */
0376     SubType& set(const segment_type& interval_value_pair)
0377     { 
0378         return icl::set_at(*that(), interval_value_pair);
0379     }
0380 
0381     //==========================================================================
0382     //= Erasure
0383     //==========================================================================
0384     /** Erase a \c key_value_pair from the map. */
0385     SubType& erase(const element_type& key_value_pair) 
0386     { 
0387         icl::erase(*that(), key_value_pair);
0388         return *that();
0389     }
0390 
0391     /** Erase an \c interval_value_pair from the map. */
0392     SubType& erase(const segment_type& interval_value_pair);
0393 
0394     /** Erase a key value pair for \c key. */
0395     SubType& erase(const domain_type& key) 
0396     { 
0397         return icl::erase(*that(), key); 
0398     }
0399 
0400     /** Erase all value pairs within the range of the 
0401         interval <tt>inter_val</tt> from the map.   */
0402     SubType& erase(const interval_type& inter_val);
0403 
0404 
0405     /** Erase all value pairs within the range of the interval that iterator 
0406         \c position points to. */
0407     void erase(iterator position){ this->_map.erase(position); }
0408 
0409     /** Erase all value pairs for a range of iterators <tt>[first,past)</tt>. */
0410     void erase(iterator first, iterator past){ this->_map.erase(first, past); }
0411 
0412     //==========================================================================
0413     //= Intersection
0414     //==========================================================================
0415     /** The intersection of \c interval_value_pair and \c *this map is added to \c section. */
0416     void add_intersection(SubType& section, const segment_type& interval_value_pair)const
0417     {
0418         on_definedness<SubType, Traits::is_total>
0419             ::add_intersection(section, *that(), interval_value_pair);
0420     }
0421 
0422     //==========================================================================
0423     //= Symmetric difference
0424     //==========================================================================
0425     /** If \c *this map contains \c key_value_pair it is erased, otherwise it is added. */
0426     SubType& flip(const element_type& key_value_pair)
0427     { 
0428         return icl::flip(*that(), key_value_pair); 
0429     }
0430 
0431     /** If \c *this map contains \c interval_value_pair it is erased, otherwise it is added. */
0432     SubType& flip(const segment_type& interval_value_pair)
0433     {
0434         on_total_absorbable<SubType, Traits::is_total, Traits::absorbs_identities>
0435             ::flip(*that(), interval_value_pair);
0436         return *that();
0437     }
0438 
0439     //==========================================================================
0440     //= Iterator related
0441     //==========================================================================
0442 
0443     iterator lower_bound(const key_type& interval)
0444     { return _map.lower_bound(interval); }
0445 
0446     iterator upper_bound(const key_type& interval)
0447     { return _map.upper_bound(interval); }
0448 
0449     const_iterator lower_bound(const key_type& interval)const
0450     { return _map.lower_bound(interval); }
0451 
0452     const_iterator upper_bound(const key_type& interval)const
0453     { return _map.upper_bound(interval); }
0454 
0455     std::pair<iterator,iterator> equal_range(const key_type& interval)
0456     { 
0457         return std::pair<iterator,iterator>
0458                (lower_bound(interval), upper_bound(interval)); 
0459     }
0460 
0461     std::pair<const_iterator,const_iterator> 
0462         equal_range(const key_type& interval)const
0463     { 
0464         return std::pair<const_iterator,const_iterator>
0465                (lower_bound(interval), upper_bound(interval)); 
0466     }
0467 
0468     iterator begin() { return _map.begin(); }
0469     iterator end()   { return _map.end(); }
0470     const_iterator begin()const { return _map.begin(); }
0471     const_iterator end()const   { return _map.end(); }
0472     reverse_iterator rbegin() { return _map.rbegin(); }
0473     reverse_iterator rend()   { return _map.rend(); }
0474     const_reverse_iterator rbegin()const { return _map.rbegin(); }
0475     const_reverse_iterator rend()const   { return _map.rend(); }
0476 
0477 private:
0478     template<class Combiner>
0479     iterator _add(const segment_type& interval_value_pair);
0480 
0481     template<class Combiner>
0482     iterator _add(iterator prior_, const segment_type& interval_value_pair);
0483 
0484     template<class Combiner>
0485     void _subtract(const segment_type& interval_value_pair);
0486 
0487     iterator _insert(const segment_type& interval_value_pair);
0488     iterator _insert(iterator prior_, const segment_type& interval_value_pair);
0489 
0490 private:
0491     template<class Combiner>
0492     void add_segment(const interval_type& inter_val, const CodomainT& co_val, iterator& it_);
0493 
0494     template<class Combiner>
0495     void add_main(interval_type& inter_val, const CodomainT& co_val, 
0496                   iterator& it_, const iterator& last_);
0497 
0498     template<class Combiner>
0499     void add_rear(const interval_type& inter_val, const CodomainT& co_val, iterator& it_);
0500 
0501     void add_front(const interval_type& inter_val, iterator& first_);
0502 
0503 private:
0504     void subtract_front(const interval_type& inter_val, iterator& first_);
0505 
0506     template<class Combiner>
0507     void subtract_main(const CodomainT& co_val, iterator& it_, const iterator& last_);
0508 
0509     template<class Combiner>
0510     void subtract_rear(interval_type& inter_val, const CodomainT& co_val, iterator& it_);
0511 
0512 private:
0513     void insert_main(const interval_type&, const CodomainT&, iterator&, const iterator&);
0514     void erase_rest (      interval_type&, const CodomainT&, iterator&, const iterator&);
0515 
0516     template<class FragmentT>
0517     void total_add_intersection(SubType& section, const FragmentT& fragment)const
0518     {
0519         section += *that();
0520         section.add(fragment);
0521     }
0522 
0523     void partial_add_intersection(SubType& section, const segment_type& operand)const
0524     {
0525         interval_type inter_val = operand.first;
0526         if(icl::is_empty(inter_val)) 
0527             return;
0528 
0529         std::pair<const_iterator, const_iterator> exterior = equal_range(inter_val);
0530         if(exterior.first == exterior.second)
0531             return;
0532 
0533         for(const_iterator it_=exterior.first; it_ != exterior.second; it_++) 
0534         {
0535             interval_type common_interval = (*it_).first & inter_val; 
0536             if(!icl::is_empty(common_interval))
0537             {
0538                 section.template _add<codomain_combine>  (value_type(common_interval, (*it_).second) );
0539                 section.template _add<codomain_intersect>(value_type(common_interval, operand.second));
0540             }
0541         }
0542     }
0543 
0544     void partial_add_intersection(SubType& section, const element_type& operand)const
0545     {
0546         partial_add_intersection(section, make_segment<type>(operand));
0547     }
0548 
0549 
0550 protected:
0551 
0552     template <class Combiner>
0553     iterator gap_insert(iterator prior_, const interval_type& inter_val, 
0554                                          const codomain_type& co_val   )
0555     {
0556         // inter_val is not conained in this map. Insertion will be successful
0557         BOOST_ASSERT(this->_map.find(inter_val) == this->_map.end());
0558         BOOST_ASSERT((!on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val)));
0559         return this->_map.insert(prior_, value_type(inter_val, version<Combiner>()(co_val)));
0560     }
0561 
0562     template <class Combiner>
0563     std::pair<iterator, bool>
0564     add_at(const iterator& prior_, const interval_type& inter_val, 
0565                                    const codomain_type& co_val   )
0566     {
0567         // Never try to insert an identity element into an identity element absorber here:
0568         BOOST_ASSERT((!(on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val))));
0569 
0570         iterator inserted_ 
0571             = this->_map.insert(prior_, value_type(inter_val, Combiner::identity_element()));
0572 
0573         if((*inserted_).first == inter_val && (*inserted_).second == Combiner::identity_element())
0574         {
0575             Combiner()((*inserted_).second, co_val);
0576             return std::pair<iterator,bool>(inserted_, true);
0577         }
0578         else
0579             return std::pair<iterator,bool>(inserted_, false);
0580     }
0581 
0582     std::pair<iterator, bool>
0583     insert_at(const iterator& prior_, const interval_type& inter_val, 
0584                                       const codomain_type& co_val   )
0585     {
0586         iterator inserted_
0587             = this->_map.insert(prior_, value_type(inter_val, co_val));
0588 
0589         if(inserted_ == prior_)
0590             return std::pair<iterator,bool>(inserted_, false);
0591         else if((*inserted_).first == inter_val)
0592             return std::pair<iterator,bool>(inserted_, true);
0593         else
0594             return std::pair<iterator,bool>(inserted_, false);
0595     }
0596 
0597 
0598 protected:
0599     sub_type* that() { return static_cast<sub_type*>(this); }
0600     const sub_type* that()const { return static_cast<const sub_type*>(this); }
0601 
0602 protected:
0603     ImplMapT _map;
0604 
0605 
0606 private:
0607     //--------------------------------------------------------------------------
0608     template<class Type, bool is_total_invertible>
0609     struct on_invertible;
0610 
0611     template<class Type>
0612     struct on_invertible<Type, true>
0613     {
0614         typedef typename Type::segment_type segment_type;
0615         typedef typename Type::inverse_codomain_combine inverse_codomain_combine;
0616 
0617         static void subtract(Type& object, const segment_type& operand)
0618         { object.template _add<inverse_codomain_combine>(operand); }
0619     };
0620 
0621     template<class Type>
0622     struct on_invertible<Type, false>
0623     {
0624         typedef typename Type::segment_type segment_type;
0625         typedef typename Type::inverse_codomain_combine inverse_codomain_combine;
0626 
0627         static void subtract(Type& object, const segment_type& operand)
0628         { object.template _subtract<inverse_codomain_combine>(operand); }
0629     };
0630 
0631     friend struct on_invertible<type, true>;
0632     friend struct on_invertible<type, false>;
0633     //--------------------------------------------------------------------------
0634 
0635     //--------------------------------------------------------------------------
0636     template<class Type, bool is_total>
0637     struct on_definedness;
0638 
0639     template<class Type>
0640     struct on_definedness<Type, true>
0641     {
0642         static void add_intersection(Type& section, const Type& object, 
0643                                      const segment_type& operand)
0644         { object.total_add_intersection(section, operand); }
0645     };
0646 
0647     template<class Type>
0648     struct on_definedness<Type, false>
0649     {
0650         static void add_intersection(Type& section, const Type& object, 
0651                                      const segment_type& operand)
0652         { object.partial_add_intersection(section, operand); }
0653     };
0654 
0655     friend struct on_definedness<type, true>;
0656     friend struct on_definedness<type, false>;
0657     //--------------------------------------------------------------------------
0658 
0659     //--------------------------------------------------------------------------
0660     template<class Type, bool has_set_semantics> 
0661     struct on_codomain_model;
0662 
0663     template<class Type>
0664     struct on_codomain_model<Type, true>
0665     {
0666         typedef typename Type::interval_type interval_type;
0667         typedef typename Type::codomain_type codomain_type;
0668         typedef typename Type::segment_type  segment_type;
0669         typedef typename Type::codomain_combine codomain_combine;
0670         typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
0671 
0672         static void add(Type& intersection, interval_type& common_interval, 
0673                         const codomain_type& flip_value, const codomain_type& co_value)
0674         {
0675             codomain_type common_value = flip_value;
0676             inverse_codomain_intersect()(common_value, co_value);
0677             intersection.template 
0678                 _add<codomain_combine>(segment_type(common_interval, common_value));
0679         }
0680     };
0681 
0682     template<class Type>
0683     struct on_codomain_model<Type, false>
0684     {
0685         typedef typename Type::interval_type interval_type;
0686         typedef typename Type::codomain_type codomain_type;
0687         typedef typename Type::segment_type  segment_type;
0688         typedef typename Type::codomain_combine codomain_combine;
0689 
0690         static void add(Type& intersection, interval_type& common_interval, 
0691                         const codomain_type&, const codomain_type&)
0692         {
0693             intersection.template 
0694               _add<codomain_combine>(segment_type(common_interval, 
0695                                                   identity_element<codomain_type>::value()));
0696         }
0697     };
0698 
0699     friend struct on_codomain_model<type, true>;
0700     friend struct on_codomain_model<type, false>;
0701     //--------------------------------------------------------------------------
0702 
0703 
0704     //--------------------------------------------------------------------------
0705     template<class Type, bool is_total, bool absorbs_identities>
0706     struct on_total_absorbable;
0707 
0708     template<class Type>
0709     struct on_total_absorbable<Type, true, true>
0710     {
0711         static void flip(Type& object, const typename Type::segment_type&)
0712         { icl::clear(object); }
0713     };
0714 
0715 #ifdef BOOST_MSVC 
0716 #pragma warning(push)
0717 #pragma warning(disable:4127) // conditional expression is constant
0718 #endif                        
0719 
0720     template<class Type>
0721     struct on_total_absorbable<Type, true, false>
0722     {
0723         typedef typename Type::segment_type  segment_type;
0724         typedef typename Type::codomain_type codomain_type;
0725 
0726         static void flip(Type& object, const segment_type& operand)
0727         { 
0728             object += operand;
0729             ICL_FORALL(typename Type, it_, object)
0730                 (*it_).second = identity_element<codomain_type>::value();
0731 
0732             if(mpl::not_<is_interval_splitter<Type> >::value)
0733                 icl::join(object);
0734         }
0735     };
0736 
0737 #ifdef BOOST_MSVC
0738 #pragma warning(pop)
0739 #endif
0740 
0741     template<class Type, bool absorbs_identities>
0742     struct on_total_absorbable<Type, false, absorbs_identities>
0743     {
0744         typedef typename Type::segment_type   segment_type;
0745         typedef typename Type::codomain_type  codomain_type;
0746         typedef typename Type::interval_type  interval_type;
0747         typedef typename Type::value_type     value_type;
0748         typedef typename Type::const_iterator const_iterator;
0749         typedef typename Type::set_type       set_type;
0750         typedef typename Type::inverse_codomain_intersect inverse_codomain_intersect;
0751 
0752         static void flip(Type& object, const segment_type& interval_value_pair)
0753         {
0754             // That which is common shall be subtracted
0755             // That which is not shall be added
0756             // So interval_value_pair has to be 'complementary added' or flipped
0757             interval_type span = interval_value_pair.first;
0758             std::pair<const_iterator, const_iterator> exterior 
0759                 = object.equal_range(span);
0760 
0761             const_iterator first_ = exterior.first;
0762             const_iterator end_   = exterior.second;
0763 
0764             interval_type covered, left_over, common_interval;
0765             const codomain_type& x_value = interval_value_pair.second;
0766             const_iterator it_ = first_;
0767 
0768             set_type eraser;
0769             Type     intersection;
0770 
0771             while(it_ != end_  ) 
0772             {
0773                 const codomain_type& co_value = (*it_).second;
0774                 covered = (*it_++).first;
0775                 //[a      ...  : span
0776                 //     [b ...  : covered
0777                 //[a  b)       : left_over
0778                 left_over = right_subtract(span, covered);
0779 
0780                 //That which is common ...
0781                 common_interval = span & covered;
0782                 if(!icl::is_empty(common_interval))
0783                 {
0784                     // ... shall be subtracted
0785                     icl::add(eraser, common_interval);
0786 
0787                     on_codomain_model<Type, has_set_semantics<codomain_type>::value>
0788                         ::add(intersection, common_interval, x_value, co_value);
0789                 }
0790 
0791                 icl::add(object, value_type(left_over, x_value)); //That which is not shall be added
0792                 // Because this is a collision free addition I don't have to distinguish codomain_types.
0793 
0794                 //...      d) : span
0795                 //... c)      : covered
0796                 //     [c  d) : span'
0797                 span = left_subtract(span, covered);
0798             }
0799 
0800             //If span is not empty here, it is not in the set so it shall be added
0801             icl::add(object, value_type(span, x_value));
0802 
0803             //finally rewrite the common segments
0804             icl::erase(object, eraser);
0805             object += intersection;
0806         }
0807     };
0808     //--------------------------------------------------------------------------
0809 } ;
0810 
0811 
0812 //==============================================================================
0813 //= Addition detail
0814 //==============================================================================
0815 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0816 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
0817     ::add_front(const interval_type& inter_val, iterator& first_)
0818 {
0819     // If the collision sequence has a left residual 'left_resid' it will
0820     // be split, to provide a standardized start of algorithms:
0821     // The addend interval 'inter_val' covers the beginning of the collision sequence.
0822 
0823     // only for the first there can be a left_resid: a part of *first_ left of inter_val
0824     interval_type left_resid = right_subtract((*first_).first, inter_val);
0825 
0826     if(!icl::is_empty(left_resid))
0827     {   //            [------------ . . .
0828         // [left_resid---first_ --- . . .
0829         iterator prior_ = cyclic_prior(*this, first_);
0830         const_cast<interval_type&>((*first_).first) 
0831             = left_subtract((*first_).first, left_resid);
0832         //NOTE: Only splitting
0833         this->_map.insert(prior_, segment_type(left_resid, (*first_).second));
0834     }
0835     //POST:
0836     // [----- inter_val ---- . . .
0837     // ...[-- first_ --...
0838 }
0839 
0840 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0841     template<class Combiner>
0842 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
0843     ::add_segment(const interval_type& inter_val, const CodomainT& co_val, iterator& it_)
0844 {
0845     interval_type lead_gap = right_subtract(inter_val, (*it_).first);
0846     if(!icl::is_empty(lead_gap))
0847     {
0848         // [lead_gap--- . . .
0849         //          [-- it_ ...
0850         iterator prior_ = it_==this->_map.begin()? it_ : prior(it_); 
0851         iterator inserted_ = this->template gap_insert<Combiner>(prior_, lead_gap, co_val);
0852         that()->handle_inserted(prior_, inserted_);
0853     }
0854 
0855     // . . . --------- . . . addend interval
0856     //      [-- it_ --)      has a common part with the first overval
0857     Combiner()((*it_).second, co_val);
0858     that()->template handle_left_combined<Combiner>(it_++);
0859 }
0860 
0861 
0862 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0863     template<class Combiner>
0864 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
0865     ::add_main(interval_type& inter_val, const CodomainT& co_val, 
0866                iterator& it_, const iterator& last_)
0867 {
0868     interval_type cur_interval;
0869     while(it_!=last_)
0870     {
0871         cur_interval = (*it_).first ;
0872         add_segment<Combiner>(inter_val, co_val, it_);
0873         // shrink interval
0874         inter_val = left_subtract(inter_val, cur_interval);
0875     }
0876 }
0877 
0878 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0879     template<class Combiner>
0880 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
0881     ::add_rear(const interval_type& inter_val, const CodomainT& co_val, iterator& it_)
0882 {
0883     iterator prior_ = cyclic_prior(*that(), it_);
0884     interval_type cur_itv = (*it_).first ;
0885 
0886     interval_type lead_gap = right_subtract(inter_val, cur_itv);
0887     if(!icl::is_empty(lead_gap))
0888     {   //         [lead_gap--- . . .
0889         // [prior)          [-- it_ ...
0890         iterator inserted_ = this->template gap_insert<Combiner>(prior_, lead_gap, co_val);
0891         that()->handle_inserted(prior_, inserted_);
0892     }
0893 
0894     interval_type end_gap = left_subtract(inter_val, cur_itv);
0895     if(!icl::is_empty(end_gap))
0896     {
0897         // [----------------end_gap)
0898         //  . . . -- it_ --)
0899         Combiner()((*it_).second, co_val);
0900         that()->template gap_insert_at<Combiner>(it_, prior_, end_gap, co_val);
0901     }
0902     else
0903     {
0904         // only for the last there can be a right_resid: a part of *it_ right of x
0905         interval_type right_resid = left_subtract(cur_itv, inter_val);
0906 
0907         if(icl::is_empty(right_resid))
0908         {
0909             // [---------------)
0910             //      [-- it_ ---)
0911             Combiner()((*it_).second, co_val);
0912             that()->template handle_preceeded_combined<Combiner>(prior_, it_);
0913         }
0914         else
0915         {
0916             // [--------------)
0917             //      [-- it_ --right_resid)
0918             const_cast<interval_type&>((*it_).first) = right_subtract((*it_).first, right_resid);
0919 
0920             //NOTE: This is NOT an insertion that has to take care for correct application of
0921             // the Combiner functor. It only reestablished that state after splitting the
0922             // 'it_' interval value pair. Using _map_insert<Combiner> does not work here.
0923             iterator insertion_ = this->_map.insert(it_, value_type(right_resid, (*it_).second));
0924             that()->handle_reinserted(insertion_);
0925 
0926             Combiner()((*it_).second, co_val);
0927             that()->template handle_preceeded_combined<Combiner>(insertion_, it_);
0928         }
0929     }
0930 }
0931 
0932 
0933 //==============================================================================
0934 //= Addition
0935 //==============================================================================
0936 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0937     template<class Combiner>
0938 inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
0939     interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
0940     ::_add(const segment_type& addend)
0941 {
0942     typedef typename on_absorbtion<type,Combiner,
0943                                 absorbs_identities<type>::value>::type on_absorbtion_;
0944 
0945     const interval_type& inter_val = addend.first;
0946     if(icl::is_empty(inter_val)) 
0947         return this->_map.end();
0948 
0949     const codomain_type& co_val = addend.second;
0950     if(on_absorbtion_::is_absorbable(co_val))
0951         return this->_map.end();
0952 
0953     std::pair<iterator,bool> insertion 
0954         = this->_map.insert(value_type(inter_val, version<Combiner>()(co_val)));
0955 
0956     if(insertion.second)
0957         return that()->handle_inserted(insertion.first);
0958     else
0959     {
0960         // Detect the first and the end iterator of the collision sequence
0961         iterator first_ = this->_map.lower_bound(inter_val),
0962                  last_  = prior(this->_map.upper_bound(inter_val));
0963         //assert(end_ == this->_map.upper_bound(inter_val));
0964         iterator it_ = first_;
0965         interval_type rest_interval = inter_val;
0966 
0967         add_front         (rest_interval,         it_       );
0968         add_main<Combiner>(rest_interval, co_val, it_, last_);
0969         add_rear<Combiner>(rest_interval, co_val, it_       );
0970         return it_;
0971     }
0972 }
0973 
0974 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0975     template<class Combiner>
0976 inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
0977     interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
0978     ::_add(iterator prior_, const segment_type& addend)
0979 {
0980     typedef typename on_absorbtion<type,Combiner,
0981                                 absorbs_identities<type>::value>::type on_absorbtion_;
0982 
0983     const interval_type& inter_val = addend.first;
0984     if(icl::is_empty(inter_val)) 
0985         return prior_;
0986 
0987     const codomain_type& co_val = addend.second;
0988     if(on_absorbtion_::is_absorbable(co_val))
0989         return prior_;
0990 
0991     std::pair<iterator,bool> insertion 
0992         = add_at<Combiner>(prior_, inter_val, co_val);
0993 
0994     if(insertion.second)
0995         return that()->handle_inserted(insertion.first);
0996     else
0997     {
0998         // Detect the first and the end iterator of the collision sequence
0999         std::pair<iterator,iterator> overlap = equal_range(inter_val);
1000         iterator it_   = overlap.first,
1001                  last_ = prior(overlap.second);
1002         interval_type rest_interval = inter_val;
1003 
1004         add_front         (rest_interval,         it_       );
1005         add_main<Combiner>(rest_interval, co_val, it_, last_);
1006         add_rear<Combiner>(rest_interval, co_val, it_       );
1007         return it_;
1008     }
1009 }
1010 
1011 //==============================================================================
1012 //= Subtraction detail
1013 //==============================================================================
1014 
1015 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1016 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1017     ::subtract_front(const interval_type& inter_val, iterator& it_)
1018 {
1019     interval_type left_resid = right_subtract((*it_).first, inter_val);
1020 
1021     if(!icl::is_empty(left_resid)) //                     [--- inter_val ---)
1022     {                              //[prior_) [left_resid)[--- it_ . . .
1023         iterator prior_ = cyclic_prior(*this, it_); 
1024         const_cast<interval_type&>((*it_).first) = left_subtract((*it_).first, left_resid);
1025         this->_map.insert(prior_, value_type(left_resid, (*it_).second));
1026         // The segemnt *it_ is split at inter_val.first(), so as an invariant
1027         // segment *it_ is always "under" inter_val and a left_resid is empty.
1028     }
1029 }
1030 
1031 
1032 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1033     template<class Combiner>
1034 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1035     ::subtract_main(const CodomainT& co_val, iterator& it_, const iterator& last_)
1036 {
1037     while(it_ != last_)
1038     {
1039         Combiner()((*it_).second, co_val);
1040         that()->template handle_left_combined<Combiner>(it_++);
1041     }
1042 }
1043 
1044 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1045     template<class Combiner>
1046 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1047     ::subtract_rear(interval_type& inter_val, const CodomainT& co_val, iterator& it_)
1048 {
1049     interval_type right_resid = left_subtract((*it_).first, inter_val);
1050 
1051     if(icl::is_empty(right_resid))
1052     {
1053         Combiner()((*it_).second, co_val);
1054         that()->template handle_combined<Combiner>(it_);
1055     }
1056     else
1057     {
1058         const_cast<interval_type&>((*it_).first) = right_subtract((*it_).first, right_resid);
1059         iterator next_ = this->_map.insert(it_, value_type(right_resid, (*it_).second));
1060         Combiner()((*it_).second, co_val);
1061         that()->template handle_succeeded_combined<Combiner>(it_, next_);
1062     }
1063 }
1064 
1065 //==============================================================================
1066 //= Subtraction
1067 //==============================================================================
1068 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1069     template<class Combiner>
1070 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1071     ::_subtract(const segment_type& minuend)
1072 {
1073     interval_type inter_val = minuend.first;
1074     if(icl::is_empty(inter_val)) 
1075         return;
1076 
1077     const codomain_type& co_val = minuend.second;
1078     if(on_absorbtion<type,Combiner,Traits::absorbs_identities>::is_absorbable(co_val)) 
1079         return;
1080 
1081     std::pair<iterator, iterator> exterior = equal_range(inter_val);
1082     if(exterior.first == exterior.second)
1083         return;
1084 
1085     iterator last_  = prior(exterior.second);
1086     iterator it_    = exterior.first;
1087     subtract_front          (inter_val,         it_       );
1088     subtract_main <Combiner>(           co_val, it_, last_);
1089     subtract_rear <Combiner>(inter_val, co_val, it_       );
1090 }
1091 
1092 //==============================================================================
1093 //= Insertion
1094 //==============================================================================
1095 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1096 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1097     ::insert_main(const interval_type& inter_val, const CodomainT& co_val, 
1098                   iterator& it_, const iterator& last_)
1099 {
1100     iterator end_   = boost::next(last_);
1101     iterator prior_ = cyclic_prior(*this,it_), inserted_;
1102     interval_type rest_interval = inter_val, left_gap, cur_itv;
1103     interval_type last_interval = last_ ->first;
1104 
1105     while(it_ != end_  )
1106     {
1107         cur_itv = (*it_).first ;            
1108         left_gap = right_subtract(rest_interval, cur_itv);
1109 
1110         if(!icl::is_empty(left_gap))
1111         {
1112             inserted_ = this->_map.insert(prior_, value_type(left_gap, co_val));
1113             it_ = that()->handle_inserted(inserted_);
1114         }
1115 
1116         // shrink interval
1117         rest_interval = left_subtract(rest_interval, cur_itv);
1118         prior_ = it_;
1119         ++it_;
1120     }
1121 
1122     //insert_rear(rest_interval, co_val, last_):
1123     interval_type end_gap = left_subtract(rest_interval, last_interval);
1124     if(!icl::is_empty(end_gap))
1125     {
1126         inserted_ = this->_map.insert(prior_, value_type(end_gap, co_val));
1127         it_ = that()->handle_inserted(inserted_);
1128     }
1129     else
1130         it_ = prior_;
1131 }
1132 
1133 
1134 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1135 inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
1136     interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1137     ::_insert(const segment_type& addend)
1138 {
1139     interval_type inter_val = addend.first;
1140     if(icl::is_empty(inter_val)) 
1141         return this->_map.end();
1142 
1143     const codomain_type& co_val = addend.second;
1144     if(on_codomain_absorbtion::is_absorbable(co_val)) 
1145         return this->_map.end();
1146 
1147     std::pair<iterator,bool> insertion = this->_map.insert(addend);
1148 
1149     if(insertion.second)
1150         return that()->handle_inserted(insertion.first);
1151     else
1152     {
1153         // Detect the first and the end iterator of the collision sequence
1154         iterator first_ = this->_map.lower_bound(inter_val),
1155                  last_  = prior(this->_map.upper_bound(inter_val));
1156         //assert((++last_) == this->_map.upper_bound(inter_val));
1157         iterator it_ = first_;
1158         insert_main(inter_val, co_val, it_, last_);
1159         return it_;
1160     }
1161 }
1162 
1163 
1164 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1165 inline typename interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>::iterator
1166     interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1167     ::_insert(iterator prior_, const segment_type& addend)
1168 {
1169     interval_type inter_val = addend.first;
1170     if(icl::is_empty(inter_val)) 
1171         return prior_;
1172 
1173     const codomain_type& co_val = addend.second;
1174     if(on_codomain_absorbtion::is_absorbable(co_val)) 
1175         return prior_;
1176 
1177     std::pair<iterator,bool> insertion = insert_at(prior_, inter_val, co_val);
1178 
1179     if(insertion.second)
1180         return that()->handle_inserted(insertion.first);
1181     {
1182         // Detect the first and the end iterator of the collision sequence
1183         std::pair<iterator,iterator> overlap = equal_range(inter_val);
1184         iterator it_    = overlap.first,
1185                  last_  = prior(overlap.second);
1186         insert_main(inter_val, co_val, it_, last_);
1187         return it_;
1188     }
1189 }
1190 
1191 //==============================================================================
1192 //= Erasure segment_type
1193 //==============================================================================
1194 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1195 inline void interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1196     ::erase_rest(interval_type& inter_val, const CodomainT& co_val, 
1197                  iterator& it_, const iterator& last_)
1198 {
1199     // For all intervals within loop: (*it_).first are contained_in inter_val
1200     while(it_ != last_)
1201         if((*it_).second == co_val)
1202             this->_map.erase(it_++); 
1203         else it_++;
1204 
1205     //erase_rear:
1206     if((*it_).second == co_val)
1207     {
1208         interval_type right_resid = left_subtract((*it_).first, inter_val);
1209         if(icl::is_empty(right_resid))
1210             this->_map.erase(it_);
1211         else
1212             const_cast<interval_type&>((*it_).first) = right_resid;
1213     }
1214 }
1215 
1216 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1217 inline SubType& interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1218     ::erase(const segment_type& minuend)
1219 {
1220     interval_type inter_val = minuend.first;
1221     if(icl::is_empty(inter_val)) 
1222         return *that();
1223 
1224     const codomain_type& co_val = minuend.second;
1225     if(on_codomain_absorbtion::is_absorbable(co_val))
1226         return *that();
1227 
1228     std::pair<iterator,iterator> exterior = equal_range(inter_val);
1229     if(exterior.first == exterior.second)
1230         return *that();
1231 
1232     iterator first_ = exterior.first, end_ = exterior.second, 
1233              last_  = cyclic_prior(*this, end_);
1234     iterator second_= first_; ++second_;
1235 
1236     if(first_ == last_) 
1237     {   //     [----inter_val----)
1238         //   .....first_==last_.....
1239         // only for the last there can be a right_resid: a part of *it_ right of minuend
1240         interval_type right_resid = left_subtract((*first_).first, inter_val);
1241 
1242         if((*first_).second == co_val)
1243         {   
1244             interval_type left_resid = right_subtract((*first_).first, inter_val);
1245             if(!icl::is_empty(left_resid)) //            [----inter_val----)
1246             {                              // [left_resid)..first_==last_......
1247                 const_cast<interval_type&>((*first_).first) = left_resid;
1248                 if(!icl::is_empty(right_resid))
1249                     this->_map.insert(first_, value_type(right_resid, co_val));
1250             }
1251             else if(!icl::is_empty(right_resid))
1252                 const_cast<interval_type&>((*first_).first) = right_resid;
1253             else
1254                 this->_map.erase(first_);
1255         }
1256     }
1257     else
1258     {
1259         // first AND NOT last
1260         if((*first_).second == co_val)
1261         {
1262             interval_type left_resid = right_subtract((*first_).first, inter_val);
1263             if(icl::is_empty(left_resid))
1264                 this->_map.erase(first_);
1265             else
1266                 const_cast<interval_type&>((*first_).first) = left_resid;
1267         }
1268 
1269         erase_rest(inter_val, co_val, second_, last_);
1270     }
1271 
1272      return *that();
1273 }
1274 
1275 //==============================================================================
1276 //= Erasure key_type
1277 //==============================================================================
1278 template <class SubType, class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
1279 inline SubType& interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc>
1280     ::erase(const interval_type& minuend)
1281 {
1282     if(icl::is_empty(minuend)) 
1283         return *that();
1284 
1285     std::pair<iterator, iterator> exterior = equal_range(minuend);
1286     if(exterior.first == exterior.second)
1287         return *that();
1288 
1289     iterator first_ = exterior.first,
1290              end_   = exterior.second,
1291              last_  = prior(end_);
1292 
1293     interval_type left_resid  = right_subtract((*first_).first, minuend);
1294     interval_type right_resid =  left_subtract(last_ ->first, minuend);
1295 
1296     if(first_ == last_ )
1297         if(!icl::is_empty(left_resid))
1298         {
1299             const_cast<interval_type&>((*first_).first) = left_resid;
1300             if(!icl::is_empty(right_resid))
1301                 this->_map.insert(first_, value_type(right_resid, (*first_).second));
1302         }
1303         else if(!icl::is_empty(right_resid))
1304             const_cast<interval_type&>((*first_).first) = left_subtract((*first_).first, minuend);
1305         else
1306             this->_map.erase(first_);
1307     else
1308     {   //            [-------- minuend ---------)
1309         // [left_resid   fst)   . . . .    [lst  right_resid)
1310         iterator second_= first_; ++second_;
1311 
1312         iterator start_ = icl::is_empty(left_resid)? first_: second_;
1313         iterator stop_  = icl::is_empty(right_resid)? end_  : last_ ;
1314         this->_map.erase(start_, stop_); //erase [start_, stop_)
1315 
1316         if(!icl::is_empty(left_resid))
1317             const_cast<interval_type&>((*first_).first) = left_resid;
1318 
1319         if(!icl::is_empty(right_resid))
1320             const_cast<interval_type&>(last_ ->first) = right_resid;
1321     }
1322 
1323     return *that();
1324 }
1325 
1326 //-----------------------------------------------------------------------------
1327 // type traits
1328 //-----------------------------------------------------------------------------
1329 template 
1330 <
1331     class SubType,
1332     class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
1333 >
1334 struct is_map<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
1335 { 
1336     typedef is_map<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
1337     BOOST_STATIC_CONSTANT(bool, value = true); 
1338 };
1339 
1340 template 
1341 <
1342     class SubType,
1343     class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
1344 >
1345 struct has_inverse<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
1346 { 
1347     typedef has_inverse<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
1348     BOOST_STATIC_CONSTANT(bool, value = (has_inverse<CodomainT>::value)); 
1349 };
1350 
1351 template 
1352 <
1353     class SubType,
1354     class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
1355 >
1356 struct is_interval_container<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
1357 { 
1358     typedef is_interval_container<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
1359     BOOST_STATIC_CONSTANT(bool, value = true); 
1360 };
1361 
1362 template 
1363 <
1364     class SubType,
1365     class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc
1366 >
1367 struct absorbs_identities<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
1368 {
1369     typedef absorbs_identities<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
1370     BOOST_STATIC_CONSTANT(bool, value = (Traits::absorbs_identities)); 
1371 };
1372 
1373 template 
1374 <
1375     class SubType,
1376     class DomainT, class CodomainT, class Traits, ICL_COMPARE Compare, ICL_COMBINE Combine, ICL_SECTION Section, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc
1377 >
1378 struct is_total<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> >
1379 {
1380     typedef is_total<icl::interval_base_map<SubType,DomainT,CodomainT,Traits,Compare,Combine,Section,Interval,Alloc> > type;
1381     BOOST_STATIC_CONSTANT(bool, value = (Traits::is_total)); 
1382 };
1383 
1384 
1385 
1386 }} // namespace icl boost
1387 
1388 #endif
1389 
1390