Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /*-----------------------------------------------------------------------------+    
0002 Copyright (c) 2010-2010: Joachim Faulhaber
0003 +------------------------------------------------------------------------------+
0004    Distributed under the Boost Software License, Version 1.0.
0005       (See accompanying file LICENCE.txt or copy at
0006            http://www.boost.org/LICENSE_1_0.txt)
0007 +-----------------------------------------------------------------------------*/
0008 #ifndef BOOST_ICL_CONCEPT_INTERVAL_MAP_HPP_JOFA_100920
0009 #define BOOST_ICL_CONCEPT_INTERVAL_MAP_HPP_JOFA_100920
0010 
0011 #include <boost/icl/type_traits/element_type_of.hpp>
0012 #include <boost/icl/type_traits/segment_type_of.hpp>
0013 #include <boost/icl/type_traits/absorbs_identities.hpp>
0014 #include <boost/icl/type_traits/is_combinable.hpp>
0015 #include <boost/icl/type_traits/is_interval_splitter.hpp>
0016 
0017 #include <boost/icl/detail/set_algo.hpp>
0018 #include <boost/icl/detail/interval_map_algo.hpp>
0019 #include <boost/icl/concept/interval.hpp>
0020 #include <boost/icl/concept/joinable.hpp>
0021 
0022 namespace boost{ namespace icl
0023 {
0024 
0025 template<class Type>
0026 inline typename enable_if<is_interval_map<Type>, typename Type::segment_type>::type
0027 make_segment(const typename Type::element_type& element)
0028 {
0029     typedef typename Type::interval_type interval_type;
0030     typedef typename Type::segment_type  segment_type;
0031     return segment_type(icl::singleton<interval_type>(element.key), element.data);
0032 }
0033 
0034 
0035 //==============================================================================
0036 //= Containedness<IntervalMap>
0037 //==============================================================================
0038 //------------------------------------------------------------------------------
0039 //- bool contains(c T&, c P&) T:{M} P:{b p M} fragment_types
0040 //------------------------------------------------------------------------------
0041 template<class Type>
0042 typename enable_if<is_interval_map<Type>, bool>::type
0043 contains(const Type& super, const typename Type::element_type& key_value_pair)
0044 {
0045     typedef typename Type::const_iterator const_iterator;
0046     const_iterator it_ = icl::find(super, key_value_pair.key);
0047     return it_ != super.end() && (*it_).second == key_value_pair.data;
0048 }
0049 
0050 template<class Type>
0051 typename enable_if<is_interval_map<Type>, bool>::type
0052 contains(const Type& super, const typename Type::segment_type& sub_segment)
0053 {
0054     typedef typename Type::interval_type  interval_type;
0055     typedef typename Type::const_iterator const_iterator;
0056 
0057     interval_type sub_interval = sub_segment.first;
0058     if(icl::is_empty(sub_interval)) 
0059         return true;
0060 
0061     std::pair<const_iterator, const_iterator> exterior = super.equal_range(sub_interval);
0062     if(exterior.first == exterior.second)
0063         return false;
0064 
0065     const_iterator last_overlap = prior(exterior.second);
0066 
0067     if(!(sub_segment.second == exterior.first->second) )
0068         return false;
0069 
0070     return
0071           icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
0072       &&  Interval_Map::is_joinable(super, exterior.first, last_overlap);
0073 }
0074 
0075 template<class Type, class CoType>
0076 typename enable_if<is_concept_compatible<is_interval_map, Type, CoType>, bool>::type
0077 contains(const Type& super, const CoType& sub)
0078 {
0079     return Interval_Set::within(sub, super);
0080 }
0081 
0082 
0083 //------------------------------------------------------------------------------
0084 //- bool contains(c T&, c P&) T:{M} P:{e i S} key_types : total
0085 //------------------------------------------------------------------------------
0086 template<class Type, class CoType>
0087 typename enable_if< mpl::and_< is_interval_map<Type>
0088                              , is_total<Type> 
0089                              , is_cross_derivative<Type, CoType> >
0090             , bool>::type
0091 contains(const Type&, const CoType&)
0092 {
0093     return true;
0094 }
0095 
0096 //------------------------------------------------------------------------------
0097 //- bool contains(c T&, c P&) T:{M} P:{e i S} key_types : partial
0098 //------------------------------------------------------------------------------
0099 template<class Type>
0100 typename enable_if< mpl::and_< is_interval_map<Type>
0101                              , mpl::not_<is_total<Type> > >
0102             , bool>::type
0103 contains(const Type& super, const typename Type::domain_type& key)    
0104 {
0105     return icl::find(super, key) != super.end();
0106 }
0107 
0108 template<class Type>
0109 typename enable_if< mpl::and_< is_interval_map<Type>
0110                              , mpl::not_<is_total<Type> > >
0111             , bool>::type
0112 contains(const Type& super, const typename Type::interval_type& sub_interval)
0113 {
0114     typedef typename Type::const_iterator const_iterator;
0115 
0116     if(icl::is_empty(sub_interval)) 
0117         return true;
0118 
0119     std::pair<const_iterator, const_iterator> exterior = super.equal_range(sub_interval);
0120     if(exterior.first == exterior.second)
0121         return false;
0122 
0123     const_iterator last_overlap = prior(exterior.second);
0124 
0125     return
0126           icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
0127       &&  Interval_Set::is_joinable(super, exterior.first, last_overlap);
0128 }
0129 
0130 template<class Type, class KeyT>
0131 typename enable_if< mpl::and_< is_concept_combinable<is_interval_map, is_interval_set, Type, KeyT>
0132                              , mpl::not_<is_total<Type> > >
0133             , bool>::type
0134 contains(const Type& super, const KeyT& sub)
0135 {
0136     return Interval_Set::within(sub, super);
0137 }
0138 
0139 //==============================================================================
0140 //= Addition<IntervalMap>
0141 //==============================================================================
0142 //------------------------------------------------------------------------------
0143 //- T& add(T&, c P&) T:{M} P:{b p} fragment_types
0144 //------------------------------------------------------------------------------
0145 template<class Type>
0146 typename enable_if<is_interval_map<Type>, Type>::type&
0147 add(Type& object, const typename Type::segment_type& operand)
0148 {
0149     return object.add(operand);
0150 }
0151 
0152 template<class Type>
0153 typename enable_if<is_interval_map<Type>, Type>::type&
0154 add(Type& object, const typename Type::element_type& operand)
0155 {
0156     return icl::add(object, make_segment<Type>(operand));
0157 }
0158 
0159 //------------------------------------------------------------------------------
0160 //- T& add(T&, J, c P&) T:{M} P:{p} segment_type
0161 //------------------------------------------------------------------------------
0162 template<class Type>
0163 typename enable_if<is_interval_map<Type>, typename Type::iterator >::type
0164 add(Type& object, typename Type::iterator      prior_,
0165             const typename Type::segment_type& operand)
0166 {
0167     return object.add(prior_, operand);
0168 }
0169 
0170 //==============================================================================
0171 //= Insertion<IntervalMap>
0172 //==============================================================================
0173 //------------------------------------------------------------------------------
0174 //- T& insert(T&, c P&) T:{M} P:{b p} fragment_types
0175 //------------------------------------------------------------------------------
0176 template<class Type>
0177 typename enable_if<is_interval_map<Type>, Type>::type&
0178 insert(Type& object, const typename Type::segment_type& operand)
0179 {
0180     return object.insert(operand);
0181 }
0182 
0183 template<class Type>
0184 inline typename enable_if<is_interval_map<Type>, Type>::type&
0185 insert(Type& object, const typename Type::element_type& operand)
0186 {
0187     return icl::insert(object, make_segment<Type>(operand));
0188 }
0189 
0190 //------------------------------------------------------------------------------
0191 //- T& insert(T&, J, c P&) T:{M} P:{p} with hint
0192 //------------------------------------------------------------------------------
0193 template<class Type>
0194 typename enable_if<is_interval_map<Type>, typename Type::iterator>::type
0195 insert(Type& object, typename Type::iterator      prior,
0196                const typename Type::segment_type& operand)
0197 {
0198     return object.insert(prior, operand);
0199 }
0200 
0201 
0202 //==============================================================================
0203 //= Erasure<IntervalMap>
0204 //==============================================================================
0205 //------------------------------------------------------------------------------
0206 //- T& erase(T&, c P&) T:{M} P:{e i} key_types
0207 //------------------------------------------------------------------------------
0208 template<class Type>
0209 typename enable_if<is_interval_map<Type>, Type>::type&
0210 erase(Type& object, const typename Type::interval_type& operand)
0211 {
0212     return object.erase(operand);
0213 }
0214 
0215 template<class Type>
0216 typename enable_if<is_interval_map<Type>, Type>::type&
0217 erase(Type& object, const typename Type::domain_type& operand)
0218 {
0219     typedef typename Type::interval_type interval_type;
0220     return icl::erase(object, icl::singleton<interval_type>(operand));
0221 }
0222 
0223 //------------------------------------------------------------------------------
0224 //- T& erase(T&, c P&) T:{M} P:{b p} fragment_types
0225 //------------------------------------------------------------------------------
0226 template<class Type>
0227 typename enable_if<is_interval_map<Type>, Type>::type&
0228 erase(Type& object, const typename Type::segment_type& operand)
0229 {
0230     return object.erase(operand);
0231 }
0232 
0233 template<class Type>
0234 inline typename enable_if<is_interval_map<Type>, Type>::type&
0235 erase(Type& object, const typename Type::element_type& operand)
0236 {
0237     return icl::erase(object, make_segment<Type>(operand));
0238 }
0239 
0240 //==============================================================================
0241 //= Subtraction<IntervalMap>
0242 //==============================================================================
0243 //------------------------------------------------------------------------------
0244 //- T& subtract(T&, c P&) T:{M} P:{b p} fragment_types
0245 //------------------------------------------------------------------------------
0246 template<class Type>
0247 typename enable_if<is_interval_map<Type>, Type>::type& 
0248 subtract(Type& object, const typename Type::segment_type& operand)
0249 {
0250     return object.subtract(operand);
0251 }
0252 
0253 template<class Type>
0254 typename enable_if<is_interval_map<Type>, Type>::type&
0255 subtract(Type& object, const typename Type::element_type& operand)
0256 {
0257     return icl::subtract(object, make_segment<Type>(operand));
0258 }
0259 
0260 //------------------------------------------------------------------------------
0261 //- T& subtract(T&, c P&) T:{M} P:{e i} key_types
0262 //------------------------------------------------------------------------------
0263 template<class Type>
0264 typename enable_if<is_interval_map<Type>, Type>::type&
0265 subtract(Type& object, const typename Type::domain_type& operand)
0266 {
0267     return object.erase(operand);
0268 }
0269 
0270 template<class Type>
0271 typename enable_if<is_interval_map<Type>, Type>::type&
0272 subtract(Type& object, const typename Type::interval_type& operand)
0273 {
0274     return object.erase(operand);
0275 }
0276 
0277 //==============================================================================
0278 //= Selective Update<IntervalMap>
0279 //==============================================================================
0280 //------------------------------------------------------------------------------
0281 //- T& set_at(T&, c P&) T:{M} P:{e i}
0282 //------------------------------------------------------------------------------
0283 template<class Type>
0284 typename enable_if<is_interval_map<Type>, Type>::type&
0285 set_at(Type& object, const typename Type::segment_type& operand)
0286 {
0287     icl::erase(object, operand.first); 
0288     return icl::insert(object, operand); 
0289 }
0290 
0291 template<class Type>
0292 typename enable_if<is_interval_map<Type>, Type>::type&
0293 set_at(Type& object, const typename Type::element_type& operand)
0294 {
0295     return icl::set_at(object, make_segment<Type>(operand));
0296 }
0297 
0298 //==============================================================================
0299 //= Intersection<IntervalMap>
0300 //==============================================================================
0301 //------------------------------------------------------------------------------
0302 //- T& subtract(T&, c P&) T:{M} P:{b p} fragment_type
0303 //------------------------------------------------------------------------------
0304 template<class Type>
0305 typename enable_if<is_interval_map<Type>, void>::type
0306 add_intersection(Type& section, const Type& object, 
0307                  const typename Type::element_type& operand)
0308 {
0309     //CL typedef typename Type::segment_type segment_type;
0310     object.add_intersection(section, make_segment<Type>(operand));
0311 }
0312 
0313 template<class Type>
0314 typename enable_if<is_interval_map<Type>, void>::type
0315 add_intersection(Type& section, const Type& object, 
0316                  const typename Type::segment_type& operand)
0317 {
0318     object.add_intersection(section, operand);
0319 }
0320 
0321 //------------------------------------------------------------------------------
0322 //- T& subtract(T&, c P&) T:{M} P:{M'} map fragment_type total
0323 //------------------------------------------------------------------------------
0324 template<class Type, class MapT>
0325 typename enable_if
0326 <
0327     mpl::and_< is_total<Type>
0328              , is_concept_compatible<is_interval_map, Type, MapT> >
0329   , void
0330 >::type
0331 add_intersection(Type& section, const Type& object, const MapT& operand)
0332 {
0333     section += object;
0334     section += operand;
0335 }
0336 
0337 //------------------------------------------------------------------------------
0338 //- T& subtract(T&, c P&) T:{M} P:{M'} map fragment_type partial
0339 //------------------------------------------------------------------------------
0340 template<class Type, class MapT>
0341 typename enable_if
0342 <
0343     mpl::and_< mpl::not_<is_total<Type> >
0344              , is_concept_compatible<is_interval_map, Type, MapT> >
0345   , void
0346 >::type
0347 add_intersection(Type& section, const Type& object, const MapT& operand)
0348 {
0349     //CL typedef typename Type::segment_type   segment_type;
0350     //CL typedef typename Type::interval_type  interval_type;
0351     typedef typename MapT::const_iterator const_iterator;
0352 
0353     if(operand.empty()) 
0354         return;
0355     const_iterator common_lwb, common_upb;
0356     if(!Set::common_range(common_lwb, common_upb, operand, object))
0357         return;
0358     const_iterator it_ = common_lwb;
0359     while(it_ != common_upb)
0360         add_intersection(section, object, *it_++);
0361 }
0362 
0363 //------------------------------------------------------------------------------
0364 //- T& subtract(T&, c P&) T:{M} P:{e i S} key_type
0365 //------------------------------------------------------------------------------
0366 template<class Type>
0367 typename enable_if<is_interval_map<Type>, void>::type
0368 add_intersection(Type& section, const Type& object, 
0369                  const typename Type::domain_type& key_value)
0370 {
0371     typedef typename Type::interval_type  interval_type;
0372     typedef typename Type::segment_type   segment_type;
0373     typedef typename Type::const_iterator const_iterator;
0374 
0375     const_iterator it_ = icl::find(object, key_value);
0376     if(it_ != object.end())
0377         add(section, segment_type(interval_type(key_value),(*it_).second));
0378 }
0379 
0380 template<class Type>
0381 typename enable_if<is_interval_map<Type>, void>::type
0382 add_intersection(Type& section, const Type& object, 
0383                  const typename Type::interval_type& inter_val)
0384 {
0385     typedef typename Type::interval_type  interval_type;
0386     typedef typename Type::value_type     value_type;
0387     typedef typename Type::const_iterator const_iterator;
0388     typedef typename Type::iterator       iterator;
0389 
0390     if(icl::is_empty(inter_val)) 
0391         return;
0392 
0393     std::pair<const_iterator, const_iterator> exterior 
0394         = object.equal_range(inter_val);
0395     if(exterior.first == exterior.second)
0396         return;
0397 
0398     iterator prior_ = section.end();
0399     for(const_iterator it_=exterior.first; it_ != exterior.second; it_++) 
0400     {
0401         interval_type common_interval = (*it_).first & inter_val; 
0402         if(!icl::is_empty(common_interval))
0403             prior_ = add(section, prior_, 
0404                          value_type(common_interval, (*it_).second) );
0405     }
0406 }
0407 
0408 template<class Type, class KeySetT>
0409 typename enable_if<is_concept_combinable<is_interval_map, is_interval_set, Type, KeySetT>, void>::type
0410 add_intersection(Type& section, const Type& object, const KeySetT& key_set)
0411 {
0412     typedef typename KeySetT::const_iterator const_iterator;
0413 
0414     if(icl::is_empty(key_set)) 
0415         return;
0416 
0417     const_iterator common_lwb, common_upb;
0418     if(!Set::common_range(common_lwb, common_upb, key_set, object))
0419         return;
0420 
0421     const_iterator it_ = common_lwb;
0422     while(it_ != common_upb)
0423         add_intersection(section, object, *it_++);
0424 }
0425 
0426 //------------------------------------------------------------------------------
0427 //- intersects<IntervalMaps> fragment_types
0428 //------------------------------------------------------------------------------
0429 template<class Type, class OperandT>
0430 typename enable_if<mpl::and_< is_interval_map<Type>
0431                             , is_total<Type>
0432                             , boost::is_same< OperandT
0433                                             , typename segment_type_of<Type>::type> >, 
0434                    bool>::type
0435 intersects(const Type&, const OperandT&)
0436 {
0437     return true;
0438 }
0439 
0440 template<class Type, class OperandT>
0441 typename enable_if<mpl::and_< is_interval_map<Type>
0442                             , mpl::not_<is_total<Type> >
0443                             , boost::is_same<OperandT, typename segment_type_of<Type>::type> >, 
0444                    bool>::type
0445 intersects(const Type& object, const OperandT& operand)
0446 {
0447     Type intersection;
0448     icl::add_intersection(intersection, object, operand);
0449     return !icl::is_empty(intersection); 
0450 }
0451 
0452 template<class Type, class OperandT>
0453 typename enable_if<mpl::and_< is_interval_map<Type>
0454                             , boost::is_same<OperandT, typename element_type_of<Type>::type> >, 
0455                    bool>::type
0456 intersects(const Type& object, const OperandT& operand)
0457 {
0458     return icl::intersects(object, make_segment<Type>(operand)); 
0459 }
0460 
0461 //==============================================================================
0462 //= Symmetric difference<IntervalMap>
0463 //==============================================================================
0464 //------------------------------------------------------------------------------
0465 //- T& flip(T&, c P&) T:{M} P:{b p} fragment_types
0466 //------------------------------------------------------------------------------
0467 template<class Type>
0468 typename enable_if<is_interval_map<Type>, Type>::type&
0469 flip(Type& object, const typename Type::segment_type& operand)
0470 {
0471     return object.flip(operand);
0472 }
0473 
0474 template<class Type>
0475 inline typename enable_if<is_interval_map<Type>, Type>::type&
0476 flip(Type& object, const typename Type::element_type& operand)
0477 {
0478     return icl::flip(object, make_segment<Type>(operand));
0479 }
0480 
0481 //------------------------------------------------------------------------------
0482 //- T& flip(T&, c P&) T:{M} P:{M'} total absorber 
0483 //------------------------------------------------------------------------------
0484 template<class Type, class OperandT>
0485 typename enable_if< mpl::and_< is_total<Type>
0486                              , absorbs_identities<Type>
0487                              , is_concept_compatible<is_interval_map, 
0488                                                      Type, OperandT >
0489                              >
0490                   , Type>::type&
0491 flip(Type& object, const OperandT&)
0492 {
0493     object.clear();
0494     return object;
0495 }
0496 
0497 //------------------------------------------------------------------------------
0498 //- T& flip(T&, c P&) T:{M} P:{M'} total enricher 
0499 //------------------------------------------------------------------------------
0500 #ifdef BOOST_MSVC 
0501 #pragma warning(push)
0502 #pragma warning(disable:4127) // conditional expression is constant
0503 #endif                        
0504 template<class Type, class OperandT>
0505 typename enable_if< mpl::and_< is_total<Type>
0506                              , mpl::not_<absorbs_identities<Type> >
0507                              , is_concept_compatible<is_interval_map, 
0508                                                      Type, OperandT >
0509                              >
0510                   , Type>::type&
0511 flip(Type& object, const OperandT& operand)
0512 {
0513     typedef typename Type::codomain_type  codomain_type;
0514 
0515     object += operand;
0516     ICL_FORALL(typename Type, it_, object)
0517         (*it_).second = identity_element<codomain_type>::value();
0518 
0519     if(mpl::not_<is_interval_splitter<Type> >::value)
0520         icl::join(object);
0521 
0522     return object;
0523 }
0524 #ifdef BOOST_MSVC
0525 #pragma warning(pop)
0526 #endif
0527 
0528 
0529 //------------------------------------------------------------------------------
0530 //- T& flip(T&, c P&) T:{M} P:{M'} partial 
0531 //------------------------------------------------------------------------------
0532 template<class Type, class OperandT>
0533 typename enable_if< mpl::and_< mpl::not_<is_total<Type> > 
0534                              , is_concept_compatible<is_interval_map, 
0535                                                      Type, OperandT >
0536                              >
0537                   , Type>::type&
0538 flip(Type& object, const OperandT& operand)
0539 {
0540     typedef typename OperandT::const_iterator const_iterator;
0541     //CL typedef typename Type::codomain_type  codomain_type;
0542 
0543     const_iterator common_lwb, common_upb;
0544 
0545     if(!Set::common_range(common_lwb, common_upb, operand, object))
0546         return object += operand;
0547 
0548     const_iterator it_ = operand.begin();
0549 
0550     // All elements of operand left of the common range are added
0551     while(it_ != common_lwb)
0552         icl::add(object, *it_++);
0553     // All elements of operand in the common range are symmetrically subtracted
0554     while(it_ != common_upb)
0555         icl::flip(object, *it_++);
0556     // All elements of operand right of the common range are added
0557     while(it_ != operand.end())
0558         icl::add(object, *it_++);
0559 
0560     return object;
0561 }
0562 
0563 //==============================================================================
0564 //= Set selection
0565 //==============================================================================
0566 template<class Type, class SetT>
0567 typename enable_if<is_concept_combinable<is_interval_set, is_interval_map, 
0568                                          SetT, Type>, SetT>::type&
0569 domain(SetT& result, const Type& object)
0570 {
0571     typedef typename SetT::iterator set_iterator;
0572     result.clear(); 
0573     set_iterator prior_ = result.end();
0574     ICL_const_FORALL(typename Type, it_, object) 
0575         prior_ = icl::insert(result, prior_, (*it_).first); 
0576     
0577     return result;
0578 }
0579 
0580 template<class Type, class SetT>
0581 typename enable_if<is_concept_combinable<is_interval_set, is_interval_map, 
0582                                          SetT, Type>, SetT>::type&
0583 between(SetT& in_between, const Type& object)
0584 {
0585     typedef typename Type::const_iterator const_iterator;
0586     typedef typename SetT::iterator       set_iterator;
0587     in_between.clear();
0588     const_iterator it_ = object.begin(), pred_;
0589     set_iterator   prior_ = in_between.end();
0590 
0591     if(it_ != object.end())
0592         pred_ = it_++;
0593 
0594     while(it_ != object.end())
0595         prior_ = icl::insert(in_between, prior_, 
0596                              between((*pred_++).first, (*it_++).first));
0597     
0598     return in_between;
0599 }
0600 
0601 //==============================================================================
0602 //= Manipulation by predicates
0603 //==============================================================================
0604 template<class MapT, class Predicate>
0605 typename enable_if<is_interval_map<MapT>, MapT>::type&
0606 erase_if(const Predicate& pred, MapT& object)
0607 {
0608     typename MapT::iterator it_ = object.begin();
0609     while(it_ != object.end())
0610         if(pred(*it_))
0611             object.erase(it_++); 
0612         else ++it_;
0613     return object;
0614 }
0615 
0616 template<class MapT, class Predicate>
0617 inline typename enable_if<is_interval_map<MapT>, MapT>::type&
0618 add_if(const Predicate& pred, MapT& object, const MapT& src)
0619 {
0620     typename MapT::const_iterator it_ = src.begin();
0621     while(it_ != src.end())
0622         if(pred(*it_)) 
0623             icl::add(object, *it_++); 
0624     
0625     return object;
0626 }
0627 
0628 template<class MapT, class Predicate>
0629 inline typename enable_if<is_interval_map<MapT>, MapT>::type&
0630 assign_if(const Predicate& pred, MapT& object, const MapT& src)
0631 {
0632     icl::clear(object);
0633     return add_if(object, src, pred);
0634 }
0635 
0636 
0637 //==============================================================================
0638 //= Morphisms
0639 //==============================================================================
0640 template<class Type>
0641 typename enable_if<mpl::and_< is_interval_map<Type>
0642                             , absorbs_identities<Type> >, Type>::type&
0643 absorb_identities(Type& object)
0644 {
0645     return object;
0646 }
0647 
0648 template<class Type>
0649 typename enable_if<mpl::and_< is_interval_map<Type>
0650                             , mpl::not_<absorbs_identities<Type> > >, Type>::type&
0651 absorb_identities(Type& object)
0652 {
0653     typedef typename Type::segment_type segment_type;
0654     return icl::erase_if(content_is_identity_element<segment_type>(), object);
0655 }
0656 
0657 //==============================================================================
0658 //= Streaming
0659 //==============================================================================
0660 template<class CharType, class CharTraits, class Type>
0661 typename enable_if<is_interval_map<Type>, 
0662                    std::basic_ostream<CharType, CharTraits> >::type& 
0663 operator << (std::basic_ostream<CharType, CharTraits>& stream, const Type& object)
0664 {
0665     stream << "{";
0666     ICL_const_FORALL(typename Type, it_, object)
0667         stream << "(" << (*it_).first << "->" << (*it_).second << ")";
0668 
0669     return stream << "}";
0670 }
0671 
0672 
0673 }} // namespace boost icl
0674 
0675 #endif
0676 
0677