File indexing completed on 2025-01-18 09:38:22
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_ICL_INTERVAL_BASE_SET_H_JOFA_990223
0010 #define BOOST_ICL_INTERVAL_BASE_SET_H_JOFA_990223
0011
0012 #include <boost/icl/impl_config.hpp>
0013
0014 #if defined(ICL_USE_BOOST_MOVE_IMPLEMENTATION)
0015 # include <boost/container/set.hpp>
0016 #elif defined(ICL_USE_STD_IMPLEMENTATION)
0017 # include <set>
0018 #else
0019 # include <set>
0020 #endif
0021
0022 #include <limits>
0023 #include <boost/next_prior.hpp>
0024 #include <boost/icl/associative_interval_container.hpp>
0025 #include <boost/icl/type_traits/interval_type_default.hpp>
0026 #include <boost/icl/interval.hpp>
0027 #include <boost/icl/type_traits/infinity.hpp>
0028 #include <boost/icl/type_traits/is_interval_joiner.hpp>
0029 #include <boost/icl/type_traits/is_interval_separator.hpp>
0030 #include <boost/icl/type_traits/is_interval_splitter.hpp>
0031 #include <boost/icl/detail/interval_set_algo.hpp>
0032 #include <boost/icl/detail/exclusive_less_than.hpp>
0033
0034 #include <boost/icl/right_open_interval.hpp>
0035 #include <boost/icl/continuous_interval.hpp>
0036 #include <boost/icl/detail/notate.hpp>
0037 #include <boost/icl/detail/element_iterator.hpp>
0038
0039 namespace boost{namespace icl
0040 {
0041
0042
0043 template
0044 <
0045 typename SubType,
0046 typename DomainT,
0047 ICL_COMPARE Compare = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT),
0048 ICL_INTERVAL(ICL_COMPARE) Interval = ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, DomainT, Compare),
0049 ICL_ALLOC Alloc = std::allocator
0050 >
0051 class interval_base_set
0052 {
0053 public:
0054
0055
0056
0057 typedef interval_base_set<SubType,DomainT,Compare,Interval,Alloc> type;
0058
0059
0060 typedef SubType sub_type;
0061
0062
0063 typedef type overloadable_type;
0064
0065
0066
0067
0068
0069 typedef DomainT domain_type;
0070
0071 typedef DomainT codomain_type;
0072
0073
0074 typedef DomainT element_type;
0075
0076
0077 typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
0078
0079 typedef interval_type segment_type;
0080
0081
0082
0083
0084
0085 typedef typename difference_type_of<domain_type>::type difference_type;
0086
0087
0088 typedef typename size_type_of<domain_type>::type size_type;
0089
0090
0091
0092
0093
0094
0095 typedef ICL_COMPARE_DOMAIN(Compare,DomainT) domain_compare;
0096 typedef ICL_COMPARE_DOMAIN(Compare,segment_type) segment_compare;
0097
0098 typedef exclusive_less_than<interval_type> interval_compare;
0099
0100
0101 typedef exclusive_less_than<interval_type> key_compare;
0102
0103
0104
0105
0106
0107 typedef typename ICL_IMPL_SPACE::set<DomainT,domain_compare,Alloc<DomainT> > atomized_type;
0108
0109
0110
0111
0112
0113 typedef Alloc<interval_type> allocator_type;
0114
0115
0116 typedef Alloc<DomainT> domain_allocator_type;
0117
0118
0119 typedef typename ICL_IMPL_SPACE::set<interval_type,key_compare,allocator_type> ImplSetT;
0120
0121
0122 typedef typename ImplSetT::key_type key_type;
0123
0124 typedef typename ImplSetT::key_type data_type;
0125
0126 typedef typename ImplSetT::value_type value_type;
0127
0128
0129 typedef typename ImplSetT::pointer pointer;
0130
0131 typedef typename ImplSetT::const_pointer const_pointer;
0132
0133 typedef typename ImplSetT::reference reference;
0134
0135 typedef typename ImplSetT::const_reference const_reference;
0136
0137
0138 typedef typename ImplSetT::iterator iterator;
0139
0140 typedef typename ImplSetT::const_iterator const_iterator;
0141
0142 typedef typename ImplSetT::reverse_iterator reverse_iterator;
0143
0144 typedef typename ImplSetT::const_reverse_iterator const_reverse_iterator;
0145
0146
0147 typedef boost::icl::element_iterator<iterator> element_iterator;
0148
0149 typedef boost::icl::element_iterator<const_iterator> element_const_iterator;
0150
0151 typedef boost::icl::element_iterator<reverse_iterator> element_reverse_iterator;
0152
0153 typedef boost::icl::element_iterator<const_reverse_iterator> element_const_reverse_iterator;
0154
0155 BOOST_STATIC_CONSTANT(int, fineness = 0);
0156
0157 public:
0158
0159
0160
0161
0162 interval_base_set(){}
0163
0164
0165 interval_base_set(const interval_base_set& src): _set(src._set)
0166 {
0167 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0168 BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0169 }
0170
0171 # ifndef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
0172
0173
0174
0175
0176
0177 interval_base_set(interval_base_set&& src): _set(boost::move(src._set))
0178 {
0179 BOOST_CONCEPT_ASSERT((DefaultConstructibleConcept<DomainT>));
0180 BOOST_CONCEPT_ASSERT((LessThanComparableConcept<DomainT>));
0181 }
0182
0183
0184 interval_base_set& operator = (interval_base_set src)
0185 {
0186 this->_set = boost::move(src._set);
0187 return *this;
0188 }
0189
0190
0191 # else
0192
0193
0194 interval_base_set& operator = (const interval_base_set& src)
0195 {
0196 this->_set = src._set;
0197 return *this;
0198 }
0199
0200 # endif
0201
0202
0203 void swap(interval_base_set& operand) { _set.swap(operand._set); }
0204
0205
0206
0207
0208
0209 void clear() { icl::clear(*that()); }
0210
0211 bool empty()const { return icl::is_empty(*that()); }
0212
0213
0214
0215
0216
0217 size_type size()const
0218 {
0219 return icl::cardinality(*that());
0220 }
0221
0222
0223 std::size_t iterative_size()const
0224 {
0225 return _set.size();
0226 }
0227
0228
0229
0230
0231
0232
0233 const_iterator find(const element_type& key_value)const
0234 {
0235 return icl::find(*this, key_value);
0236
0237 }
0238
0239
0240 const_iterator find(const interval_type& key_interval)const
0241 {
0242 return this->_set.find(key_interval);
0243 }
0244
0245
0246
0247
0248
0249
0250 SubType& add(const element_type& key)
0251 {
0252 return icl::add(*that(), key);
0253 }
0254
0255
0256 SubType& add(const segment_type& inter_val)
0257 {
0258 _add(inter_val);
0259 return *that();
0260 }
0261
0262
0263
0264
0265 iterator add(iterator prior_, const segment_type& inter_val)
0266 {
0267 return _add(prior_, inter_val);
0268 }
0269
0270
0271
0272
0273
0274
0275 SubType& subtract(const element_type& key)
0276 {
0277 return icl::subtract(*that(), key);
0278 }
0279
0280
0281 SubType& subtract(const segment_type& inter_val);
0282
0283
0284
0285
0286
0287 SubType& insert(const element_type& key)
0288 {
0289 return add(key);
0290 }
0291
0292
0293 SubType& insert(const segment_type& inter_val)
0294 {
0295 return add(inter_val);
0296 }
0297
0298
0299
0300
0301 iterator insert(iterator prior_, const segment_type& inter_val)
0302 {
0303 return add(prior_, inter_val);
0304 }
0305
0306
0307
0308
0309
0310
0311
0312 SubType& erase(const element_type& key)
0313 {
0314 return subtract(key);
0315 }
0316
0317
0318 SubType& erase(const segment_type& inter_val)
0319 {
0320 return subtract(inter_val);
0321 }
0322
0323
0324 void erase(iterator position)
0325 {
0326 _set.erase(position);
0327 }
0328
0329
0330 void erase(iterator first, iterator past)
0331 {
0332 _set.erase(first, past);
0333 }
0334
0335
0336
0337
0338
0339 SubType& flip(const element_type& key)
0340 {
0341 return icl::flip(*that(), key);
0342 }
0343
0344
0345 SubType& flip(const segment_type& inter_val)
0346 {
0347 return icl::flip(*that(), inter_val);
0348 }
0349
0350
0351
0352
0353
0354 iterator begin() { return _set.begin(); }
0355 iterator end() { return _set.end(); }
0356 const_iterator begin()const { return _set.begin(); }
0357 const_iterator end()const { return _set.end(); }
0358 reverse_iterator rbegin() { return _set.rbegin(); }
0359 reverse_iterator rend() { return _set.rend(); }
0360 const_reverse_iterator rbegin()const { return _set.rbegin(); }
0361 const_reverse_iterator rend()const { return _set.rend(); }
0362
0363 iterator lower_bound(const value_type& interval)
0364 { return _set.lower_bound(interval); }
0365
0366 iterator upper_bound(const value_type& interval)
0367 { return _set.upper_bound(interval); }
0368
0369 const_iterator lower_bound(const value_type& interval)const
0370 { return _set.lower_bound(interval); }
0371
0372 const_iterator upper_bound(const value_type& interval)const
0373 { return _set.upper_bound(interval); }
0374
0375 std::pair<iterator,iterator> equal_range(const key_type& interval)
0376 {
0377 return std::pair<iterator,iterator>
0378 (_set.lower_bound(interval), _set.upper_bound(interval));
0379 }
0380
0381 std::pair<const_iterator,const_iterator>
0382 equal_range(const key_type& interval)const
0383 {
0384 return std::pair<const_iterator,const_iterator>
0385 (_set.lower_bound(interval), _set.upper_bound(interval));
0386 }
0387
0388 private:
0389 iterator _add(const segment_type& addend);
0390 iterator _add(iterator prior, const segment_type& addend);
0391
0392 protected:
0393 void add_front(const interval_type& inter_val, iterator& first_);
0394 void add_main(interval_type& inter_val, iterator& it_, const iterator& last_);
0395 void add_segment(const interval_type& inter_val, iterator& it_);
0396 void add_rear(const interval_type& inter_val, iterator& it_);
0397
0398 protected:
0399 sub_type* that() { return static_cast<sub_type*>(this); }
0400 const sub_type* that()const { return static_cast<const sub_type*>(this); }
0401
0402 protected:
0403 ImplSetT _set;
0404 } ;
0405
0406
0407 template <class SubType, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0408 inline void interval_base_set<SubType,DomainT,Compare,Interval,Alloc>
0409 ::add_front(const interval_type& inter_val, iterator& first_)
0410 {
0411
0412
0413
0414
0415
0416 interval_type left_resid = right_subtract(*first_, inter_val);
0417
0418 if(!icl::is_empty(left_resid))
0419 {
0420
0421 iterator prior_ = cyclic_prior(*this, first_);
0422 const_cast<interval_type&>(*first_) = left_subtract(*first_, left_resid);
0423
0424 this->_set.insert(prior_, left_resid);
0425 }
0426
0427
0428
0429
0430 }
0431
0432 template <class SubType, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0433 inline void interval_base_set<SubType,DomainT,Compare,Interval,Alloc>
0434 ::add_segment(const interval_type& inter_val, iterator& it_)
0435 {
0436 interval_type lead_gap = right_subtract(inter_val, *it_);
0437 if(!icl::is_empty(lead_gap))
0438
0439
0440 this->_set.insert(cyclic_prior(*this, it_), lead_gap);
0441
0442
0443
0444 ++it_;
0445 }
0446
0447 template <class SubType, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0448 inline void interval_base_set<SubType,DomainT,Compare,Interval,Alloc>
0449 ::add_main(interval_type& rest_interval, iterator& it_, const iterator& last_)
0450 {
0451 interval_type cur_interval;
0452 while(it_ != last_)
0453 {
0454 cur_interval = *it_ ;
0455 add_segment(rest_interval, it_);
0456
0457 rest_interval = left_subtract(rest_interval, cur_interval);
0458 }
0459 }
0460
0461 template <class SubType, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0462 inline void interval_base_set<SubType,DomainT,Compare,Interval,Alloc>
0463 ::add_rear(const interval_type& inter_val, iterator& it_)
0464 {
0465 iterator prior_ = cyclic_prior(*this, it_);
0466 interval_type cur_itv = *it_;
0467
0468 interval_type lead_gap = right_subtract(inter_val, cur_itv);
0469 if(!icl::is_empty(lead_gap))
0470
0471
0472 this->_set.insert(prior_, lead_gap);
0473
0474 interval_type end_gap = left_subtract(inter_val, cur_itv);
0475 if(!icl::is_empty(end_gap))
0476
0477
0478 it_ = this->_set.insert(it_, end_gap);
0479 else
0480 {
0481
0482 interval_type right_resid = left_subtract(cur_itv, inter_val);
0483
0484 if(!icl::is_empty(right_resid))
0485 {
0486
0487
0488 const_cast<interval_type&>(*it_) = right_subtract(*it_, right_resid);
0489 it_ = this->_set.insert(it_, right_resid);
0490 }
0491 }
0492 }
0493
0494
0495
0496
0497 template <class SubType, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0498 inline typename interval_base_set<SubType,DomainT,Compare,Interval,Alloc>::iterator
0499 interval_base_set<SubType,DomainT,Compare,Interval,Alloc>
0500 ::_add(const segment_type& addend)
0501 {
0502 typedef typename interval_base_set<SubType,DomainT,Compare,Interval,Alloc>::iterator iterator;
0503 if(icl::is_empty(addend))
0504 return this->_set.end();
0505
0506 std::pair<iterator,bool> insertion = this->_set.insert(addend);
0507
0508 if(insertion.second)
0509 return that()->handle_inserted(insertion.first);
0510 else
0511 {
0512 iterator last_ = prior(this->_set.upper_bound(addend));
0513 return that()->add_over(addend, last_);
0514 }
0515 }
0516
0517 template <class SubType, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0518 inline typename interval_base_set<SubType,DomainT,Compare,Interval,Alloc>::iterator
0519 interval_base_set<SubType,DomainT,Compare,Interval,Alloc>
0520 ::_add(iterator prior_, const segment_type& addend)
0521 {
0522 typedef typename interval_base_set<SubType,DomainT,Compare,Interval,Alloc>::iterator iterator;
0523 if(icl::is_empty(addend))
0524 return prior_;
0525
0526 iterator insertion = this->_set.insert(prior_, addend);
0527
0528 if(*insertion == addend)
0529 return that()->handle_inserted(insertion);
0530 else
0531 {
0532 iterator last_ = prior(this->_set.upper_bound(addend));
0533 return that()->add_over(addend, last_);
0534 }
0535 }
0536
0537
0538
0539
0540 template <class SubType, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0541 inline SubType& interval_base_set<SubType,DomainT,Compare,Interval,Alloc>
0542 ::subtract(const segment_type& minuend)
0543 {
0544 if(icl::is_empty(minuend))
0545 return *that();
0546
0547 std::pair<iterator, iterator> exterior = equal_range(minuend);
0548 if(exterior.first == exterior.second)
0549 return *that();
0550
0551 iterator first_ = exterior.first;
0552 iterator end_ = exterior.second;
0553 iterator last_ = prior(end_);
0554
0555 interval_type left_resid = right_subtract(*first_, minuend);
0556 interval_type right_resid;
0557 if(first_ != end_)
0558 right_resid = left_subtract(*last_ , minuend);
0559
0560 this->_set.erase(first_, end_);
0561
0562 if(!icl::is_empty(left_resid))
0563 this->_set.insert(left_resid);
0564
0565 if(!icl::is_empty(right_resid))
0566 this->_set.insert(right_resid);
0567
0568 return *that();
0569 }
0570
0571
0572
0573
0574 template<class SubType,
0575 class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0576 struct is_set<icl::interval_base_set<SubType,DomainT,Compare,Interval,Alloc> >
0577 {
0578 typedef is_set<icl::interval_base_set<SubType,DomainT,Compare,Interval,Alloc> > type;
0579 BOOST_STATIC_CONSTANT(bool, value = true);
0580 };
0581
0582 template<class SubType,
0583 class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval, ICL_ALLOC Alloc>
0584 struct is_interval_container<icl::interval_base_set<SubType,DomainT,Compare,Interval,Alloc> >
0585 {
0586 typedef is_interval_container<icl::interval_base_set<SubType,DomainT,Compare,Interval,Alloc> > type;
0587 BOOST_STATIC_CONSTANT(bool, value = true);
0588 };
0589
0590
0591
0592 }}
0593
0594 #endif