File indexing completed on 2025-01-18 09:38:22
0001
0002
0003
0004
0005
0006
0007
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
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
0064
0065 typedef interval_base_map<SubType,DomainT,CodomainT,
0066 Traits,Compare,Combine,Section,Interval,Alloc>
0067 type;
0068
0069
0070 typedef SubType sub_type;
0071
0072
0073 typedef type overloadable_type;
0074
0075
0076 typedef Traits traits;
0077
0078
0079
0080
0081
0082 typedef typename icl::map<DomainT,CodomainT,
0083 Traits,Compare,Combine,Section,Alloc> atomized_type;
0084
0085
0086
0087
0088
0089 typedef DomainT domain_type;
0090 typedef typename boost::call_traits<DomainT>::param_type domain_param;
0091
0092 typedef CodomainT codomain_type;
0093
0094 typedef mapping_pair<domain_type,codomain_type> domain_mapping_type;
0095
0096 typedef domain_mapping_type element_type;
0097
0098 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
0099
0100 typedef std::pair<interval_type,CodomainT> interval_mapping_type;
0101
0102 typedef std::pair<interval_type,CodomainT> segment_type;
0103
0104
0105
0106
0107
0108 typedef typename difference_type_of<domain_type>::type difference_type;
0109
0110 typedef typename size_type_of<domain_type>::type size_type;
0111
0112
0113
0114
0115
0116 typedef ICL_COMPARE_DOMAIN(Compare,DomainT) domain_compare;
0117 typedef ICL_COMPARE_DOMAIN(Compare,segment_type) segment_compare;
0118
0119 typedef ICL_COMBINE_CODOMAIN(Combine,CodomainT) codomain_combine;
0120
0121 typedef typename inverse<codomain_combine>::type inverse_codomain_combine;
0122
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
0132 typedef typename inverse<codomain_intersect>::type inverse_codomain_intersect;
0133
0134
0135 typedef exclusive_less_than<interval_type> interval_compare;
0136
0137
0138 typedef exclusive_less_than<interval_type> key_compare;
0139
0140
0141
0142
0143
0144 typedef Alloc<std::pair<const interval_type, codomain_type> >
0145 allocator_type;
0146
0147
0148 typedef ICL_IMPL_SPACE::map<interval_type,codomain_type,
0149 key_compare,allocator_type> ImplMapT;
0150
0151
0152 typedef typename ImplMapT::key_type key_type;
0153
0154 typedef typename ImplMapT::value_type value_type;
0155
0156 typedef typename ImplMapT::value_type::second_type data_type;
0157
0158
0159 typedef typename ImplMapT::pointer pointer;
0160
0161 typedef typename ImplMapT::const_pointer const_pointer;
0162
0163 typedef typename ImplMapT::reference reference;
0164
0165 typedef typename ImplMapT::const_reference const_reference;
0166
0167
0168 typedef typename ImplMapT::iterator iterator;
0169
0170 typedef typename ImplMapT::const_iterator const_iterator;
0171
0172 typedef typename ImplMapT::reverse_iterator reverse_iterator;
0173
0174 typedef typename ImplMapT::const_reverse_iterator const_reverse_iterator;
0175
0176
0177 typedef boost::icl::element_iterator<iterator> element_iterator;
0178
0179 typedef boost::icl::element_iterator<const_iterator> element_const_iterator;
0180
0181 typedef boost::icl::element_iterator<reverse_iterator> element_reverse_iterator;
0182
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
0199
0200
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
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
0221
0222
0223
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
0233 interval_base_map& operator = (interval_base_map src)
0234 {
0235 this->_map = boost::move(src._map);
0236 return *this;
0237 }
0238
0239
0240 # else
0241
0242
0243 interval_base_map& operator = (const interval_base_map& src)
0244 {
0245 this->_map = src._map;
0246 return *this;
0247 }
0248
0249 # endif
0250
0251
0252 void swap(interval_base_map& object) { _map.swap(object._map); }
0253
0254
0255
0256
0257
0258 void clear() { icl::clear(*that()); }
0259
0260
0261 bool empty()const { return icl::is_empty(*that()); }
0262
0263
0264
0265
0266
0267 size_type size()const
0268 {
0269 return icl::cardinality(*that());
0270 }
0271
0272
0273 std::size_t iterative_size()const
0274 {
0275 return _map.size();
0276 }
0277
0278
0279
0280
0281
0282
0283 const_iterator find(const domain_type& key_value)const
0284 {
0285 return icl::find(*this, key_value);
0286 }
0287
0288
0289
0290 const_iterator find(const interval_type& key_interval)const
0291 {
0292 return _map.find(key_interval);
0293 }
0294
0295
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
0305
0306
0307
0308 SubType& add(const element_type& key_value_pair)
0309 {
0310 return icl::add(*that(), key_value_pair);
0311 }
0312
0313
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
0321
0322
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
0330
0331
0332 SubType& subtract(const element_type& key_value_pair)
0333 {
0334 return icl::subtract(*that(), key_value_pair);
0335 }
0336
0337
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
0347
0348
0349 SubType& insert(const element_type& key_value_pair)
0350 {
0351 return icl::insert(*that(), key_value_pair);
0352 }
0353
0354
0355 SubType& insert(const segment_type& interval_value_pair)
0356 {
0357 _insert(interval_value_pair);
0358 return *that();
0359 }
0360
0361
0362
0363 iterator insert(iterator prior, const segment_type& interval_value_pair)
0364 {
0365 return _insert(prior, interval_value_pair);
0366 }
0367
0368
0369 SubType& set(const element_type& key_value_pair)
0370 {
0371 return icl::set_at(*that(), key_value_pair);
0372 }
0373
0374
0375
0376 SubType& set(const segment_type& interval_value_pair)
0377 {
0378 return icl::set_at(*that(), interval_value_pair);
0379 }
0380
0381
0382
0383
0384
0385 SubType& erase(const element_type& key_value_pair)
0386 {
0387 icl::erase(*that(), key_value_pair);
0388 return *that();
0389 }
0390
0391
0392 SubType& erase(const segment_type& interval_value_pair);
0393
0394
0395 SubType& erase(const domain_type& key)
0396 {
0397 return icl::erase(*that(), key);
0398 }
0399
0400
0401
0402 SubType& erase(const interval_type& inter_val);
0403
0404
0405
0406
0407 void erase(iterator position){ this->_map.erase(position); }
0408
0409
0410 void erase(iterator first, iterator past){ this->_map.erase(first, past); }
0411
0412
0413
0414
0415
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
0424
0425
0426 SubType& flip(const element_type& key_value_pair)
0427 {
0428 return icl::flip(*that(), key_value_pair);
0429 }
0430
0431
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
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
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
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)
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
0755
0756
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
0776
0777
0778 left_over = right_subtract(span, covered);
0779
0780
0781 common_interval = span & covered;
0782 if(!icl::is_empty(common_interval))
0783 {
0784
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));
0792
0793
0794
0795
0796
0797 span = left_subtract(span, covered);
0798 }
0799
0800
0801 icl::add(object, value_type(span, x_value));
0802
0803
0804 icl::erase(object, eraser);
0805 object += intersection;
0806 }
0807 };
0808
0809 } ;
0810
0811
0812
0813
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
0820
0821
0822
0823
0824 interval_type left_resid = right_subtract((*first_).first, inter_val);
0825
0826 if(!icl::is_empty(left_resid))
0827 {
0828
0829 iterator prior_ = cyclic_prior(*this, first_);
0830 const_cast<interval_type&>((*first_).first)
0831 = left_subtract((*first_).first, left_resid);
0832
0833 this->_map.insert(prior_, segment_type(left_resid, (*first_).second));
0834 }
0835
0836
0837
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
0849
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
0856
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
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 {
0889
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
0898
0899 Combiner()((*it_).second, co_val);
0900 that()->template gap_insert_at<Combiner>(it_, prior_, end_gap, co_val);
0901 }
0902 else
0903 {
0904
0905 interval_type right_resid = left_subtract(cur_itv, inter_val);
0906
0907 if(icl::is_empty(right_resid))
0908 {
0909
0910
0911 Combiner()((*it_).second, co_val);
0912 that()->template handle_preceeded_combined<Combiner>(prior_, it_);
0913 }
0914 else
0915 {
0916
0917
0918 const_cast<interval_type&>((*it_).first) = right_subtract((*it_).first, right_resid);
0919
0920
0921
0922
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
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
0961 iterator first_ = this->_map.lower_bound(inter_val),
0962 last_ = prior(this->_map.upper_bound(inter_val));
0963
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
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
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))
1022 {
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
1027
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
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
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
1117 rest_interval = left_subtract(rest_interval, cur_itv);
1118 prior_ = it_;
1119 ++it_;
1120 }
1121
1122
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
1154 iterator first_ = this->_map.lower_bound(inter_val),
1155 last_ = prior(this->_map.upper_bound(inter_val));
1156
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
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
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
1200 while(it_ != last_)
1201 if((*it_).second == co_val)
1202 this->_map.erase(it_++);
1203 else it_++;
1204
1205
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 {
1238
1239
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))
1246 {
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
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
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 {
1309
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_);
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
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 }}
1387
1388 #endif
1389
1390