File indexing completed on 2025-01-18 09:38:19
0001
0002
0003
0004
0005
0006
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
0037
0038
0039
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
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
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
0141
0142
0143
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
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
0172
0173
0174
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
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
0204
0205
0206
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
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
0242
0243
0244
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
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
0279
0280
0281
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
0300
0301
0302
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
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
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
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
0350
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
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
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
0463
0464
0465
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
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
0499
0500 #ifdef BOOST_MSVC
0501 #pragma warning(push)
0502 #pragma warning(disable:4127)
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
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
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
0551 while(it_ != common_lwb)
0552 icl::add(object, *it_++);
0553
0554 while(it_ != common_upb)
0555 icl::flip(object, *it_++);
0556
0557 while(it_ != operand.end())
0558 icl::add(object, *it_++);
0559
0560 return object;
0561 }
0562
0563
0564
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
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
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
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 }}
0674
0675 #endif
0676
0677