File indexing completed on 2025-01-18 09:38:19
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ICL_CONCEPT_INTERVAL_SET_HPP_JOFA_100920
0009 #define BOOST_ICL_CONCEPT_INTERVAL_SET_HPP_JOFA_100920
0010
0011 #include <boost/icl/type_traits/is_combinable.hpp>
0012 #include <boost/icl/type_traits/interval_type_of.hpp>
0013 #include <boost/icl/detail/set_algo.hpp>
0014 #include <boost/icl/detail/interval_set_algo.hpp>
0015 #include <boost/icl/concept/interval.hpp>
0016
0017 namespace boost{ namespace icl
0018 {
0019
0020
0021
0022
0023
0024
0025
0026 template<class Type>
0027 typename enable_if<is_interval_set<Type>, bool>::type
0028 contains(const Type& super, const typename Type::element_type& element)
0029 {
0030 return !(icl::find(super, element) == super.end());
0031 }
0032
0033 template<class Type>
0034 typename enable_if<is_interval_set<Type>, bool>::type
0035 contains(const Type& super, const typename Type::segment_type& inter_val)
0036 {
0037 typedef typename Type::const_iterator const_iterator;
0038 if(icl::is_empty(inter_val))
0039 return true;
0040
0041 std::pair<const_iterator, const_iterator> exterior
0042 = super.equal_range(inter_val);
0043 if(exterior.first == exterior.second)
0044 return false;
0045
0046 const_iterator last_overlap = cyclic_prior(super, exterior.second);
0047
0048 return
0049 icl::contains(hull(*(exterior.first), *last_overlap), inter_val)
0050 && Interval_Set::is_joinable(super, exterior.first, last_overlap);
0051 }
0052
0053 template<class Type, class OperandT>
0054 typename enable_if<has_same_concept<is_interval_set, Type, OperandT>,
0055 bool>::type
0056 contains(const Type& super, const OperandT& sub)
0057 {
0058 return Interval_Set::contains(super, sub);
0059 }
0060
0061
0062
0063
0064
0065
0066
0067 template<class Type>
0068 typename enable_if<is_interval_set<Type>, Type>::type&
0069 add(Type& object, const typename Type::segment_type& operand)
0070 {
0071 return object.add(operand);
0072 }
0073
0074 template<class Type>
0075 inline typename enable_if<is_interval_set<Type>, Type>::type&
0076 add(Type& object, const typename Type::element_type& operand)
0077 {
0078 typedef typename Type::segment_type segment_type;
0079 return icl::add(object, icl::singleton<segment_type>(operand));
0080 }
0081
0082
0083
0084
0085 template<class Type>
0086 inline typename enable_if<is_interval_set<Type>, typename Type::iterator>::type
0087 add(Type& object, typename Type::iterator prior,
0088 const typename Type::segment_type& operand)
0089 {
0090 return object.add(prior, operand);
0091 }
0092
0093
0094
0095
0096
0097
0098
0099 template<class Type>
0100 inline typename enable_if<is_interval_set<Type>, Type>::type&
0101 insert(Type& object, const typename Type::segment_type& operand)
0102 {
0103 return icl::add(object, operand);
0104 }
0105
0106 template<class Type>
0107 inline typename enable_if<is_interval_set<Type>, Type>::type&
0108 insert(Type& object, const typename Type::element_type& operand)
0109 {
0110 return icl::add(object, operand);
0111 }
0112
0113
0114
0115
0116 template<class Type>
0117 inline typename enable_if<is_interval_set<Type>, typename Type::iterator>::type
0118 insert(Type& object, typename Type::iterator prior,
0119 const typename Type::segment_type& operand)
0120 {
0121 return icl::add(object, prior, operand);
0122 }
0123
0124
0125
0126
0127
0128
0129
0130 template<class Type>
0131 typename enable_if<is_interval_set<Type>, Type>::type&
0132 subtract(Type& object, const typename Type::segment_type& operand)
0133 {
0134 return object.subtract(operand);
0135 }
0136
0137 template<class Type>
0138 inline typename enable_if<is_interval_set<Type>, Type>::type&
0139 subtract(Type& object, const typename Type::element_type& operand)
0140 {
0141 typedef typename Type::segment_type segment_type;
0142 return icl::subtract(object, icl::singleton<segment_type>(operand));
0143 }
0144
0145
0146
0147
0148
0149
0150
0151 template<class Type>
0152 typename enable_if<is_interval_set<Type>, Type>::type&
0153 erase(Type& object, const typename Type::segment_type& minuend)
0154 {
0155 return icl::subtract(object, minuend);
0156 }
0157
0158 template<class Type>
0159 typename enable_if<is_interval_set<Type>, Type>::type&
0160 erase(Type& object, const typename Type::element_type& minuend)
0161 {
0162 return icl::subtract(object, minuend);
0163 }
0164
0165
0166
0167
0168
0169
0170
0171 template<class Type>
0172 typename enable_if<is_interval_set<Type>, void>::type
0173 add_intersection(Type& section, const Type& object,
0174 const typename Type::element_type& operand)
0175 {
0176 typedef typename Type::const_iterator const_iterator;
0177 const_iterator found = icl::find(object, operand);
0178 if(found != object.end())
0179 icl::add(section, operand);
0180 }
0181
0182
0183 template<class Type>
0184 typename enable_if<is_interval_set<Type>, void>::type
0185 add_intersection(Type& section, const Type& object,
0186 const typename Type::segment_type& segment)
0187 {
0188 typedef typename Type::const_iterator const_iterator;
0189 typedef typename Type::iterator iterator;
0190 typedef typename Type::interval_type interval_type;
0191
0192 if(icl::is_empty(segment))
0193 return;
0194
0195 std::pair<const_iterator, const_iterator> exterior
0196 = object.equal_range(segment);
0197 if(exterior.first == exterior.second)
0198 return;
0199
0200 iterator prior_ = section.end();
0201 for(const_iterator it_=exterior.first; it_ != exterior.second; it_++)
0202 {
0203 interval_type common_interval = key_value<Type>(it_) & segment;
0204 if(!icl::is_empty(common_interval))
0205 prior_ = section.insert(prior_, common_interval);
0206 }
0207 }
0208
0209
0210
0211
0212
0213
0214
0215 template<class Type>
0216 typename enable_if<is_interval_set<Type>, Type>::type&
0217 flip(Type& object, const typename Type::element_type& operand)
0218 {
0219 if(icl::contains(object, operand))
0220 return object -= operand;
0221 else
0222 return object += operand;
0223 }
0224
0225 template<class Type>
0226 typename enable_if<is_interval_set<Type>, Type>::type&
0227 flip(Type& object, const typename Type::segment_type& segment)
0228 {
0229 typedef typename Type::const_iterator const_iterator;
0230 typedef typename Type::interval_type interval_type;
0231
0232
0233
0234 interval_type span = segment;
0235 std::pair<const_iterator, const_iterator> exterior
0236 = object.equal_range(span);
0237
0238 const_iterator fst_ = exterior.first;
0239 const_iterator end_ = exterior.second;
0240
0241 interval_type covered, left_over;
0242 const_iterator it_ = fst_;
0243 while(it_ != end_)
0244 {
0245 covered = *it_++;
0246
0247
0248
0249 left_over = right_subtract(span, covered);
0250 icl::subtract(object, span & covered);
0251 icl::add(object, left_over);
0252
0253
0254
0255
0256 span = left_subtract(span, covered);
0257 }
0258
0259
0260 icl::add(object, span);
0261 return object;
0262 }
0263
0264
0265 template<class Type, class OperandT>
0266 typename enable_if<is_concept_compatible<is_interval_set, Type, OperandT>, Type>::type&
0267 flip(Type& object, const OperandT& operand)
0268 {
0269 typedef typename OperandT::const_iterator const_iterator;
0270
0271 if(operand.empty())
0272 return object;
0273
0274 const_iterator common_lwb, common_upb;
0275
0276 if(!Set::common_range(common_lwb, common_upb, operand, object))
0277 return object += operand;
0278
0279 const_iterator it_ = operand.begin();
0280
0281
0282 while(it_ != common_lwb)
0283 icl::add(object, *it_++);
0284
0285 while(it_ != common_upb)
0286 icl::flip(object, *it_++);
0287
0288 while(it_ != operand.end())
0289 icl::add(object, *it_++);
0290
0291 return object;
0292 }
0293
0294
0295
0296
0297 template<class Type>
0298 typename enable_if<is_interval_set<Type>, Type>::type&
0299 domain(Type& dom, const Type& object)
0300 {
0301 typedef typename Type::const_iterator const_iterator;
0302 typedef typename Type::iterator iterator;
0303 dom.clear();
0304 const_iterator it_ = object.begin();
0305 iterator prior_ = dom.end();
0306
0307 while(it_ != object.end())
0308 prior_ = icl::insert(dom, prior_, *it_++);
0309
0310 return dom;
0311 }
0312
0313 template<class Type>
0314 typename enable_if<is_interval_set<Type>, Type>::type&
0315 between(Type& in_between, const Type& object)
0316 {
0317 typedef typename Type::const_iterator const_iterator;
0318 typedef typename Type::iterator iterator;
0319 in_between.clear();
0320 const_iterator it_ = object.begin(), pred_;
0321 iterator prior_ = in_between.end();
0322
0323 if(it_ != object.end())
0324 pred_ = it_++;
0325
0326 while(it_ != object.end())
0327 prior_ = icl::insert(in_between, prior_,
0328 icl::between(*pred_++, *it_++));
0329
0330 return in_between;
0331 }
0332
0333
0334
0335
0336
0337 template<class CharType, class CharTraits, class Type>
0338 typename enable_if<is_interval_set<Type>,
0339 std::basic_ostream<CharType, CharTraits> >::type&
0340 operator << (std::basic_ostream<CharType, CharTraits>& stream, const Type& object)
0341 {
0342 stream << "{";
0343 ICL_const_FORALL(typename Type, it_, object)
0344 stream << (*it_);
0345
0346 return stream << "}";
0347 }
0348
0349
0350 }}
0351
0352 #endif
0353
0354