annotate DEPENDENCIES/generic/include/boost/icl/concept/interval_set.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*-----------------------------------------------------------------------------+
Chris@16 2 Copyright (c) 2010-2010: Joachim Faulhaber
Chris@16 3 +------------------------------------------------------------------------------+
Chris@16 4 Distributed under the Boost Software License, Version 1.0.
Chris@16 5 (See accompanying file LICENCE.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 +-----------------------------------------------------------------------------*/
Chris@16 8 #ifndef BOOST_ICL_CONCEPT_INTERVAL_SET_HPP_JOFA_100920
Chris@16 9 #define BOOST_ICL_CONCEPT_INTERVAL_SET_HPP_JOFA_100920
Chris@16 10
Chris@16 11 #include <boost/icl/type_traits/is_combinable.hpp>
Chris@16 12 #include <boost/icl/type_traits/interval_type_of.hpp>
Chris@16 13 #include <boost/icl/detail/set_algo.hpp>
Chris@16 14 #include <boost/icl/detail/interval_set_algo.hpp>
Chris@16 15 #include <boost/icl/concept/interval.hpp>
Chris@16 16
Chris@16 17 namespace boost{ namespace icl
Chris@16 18 {
Chris@16 19
Chris@16 20 //==============================================================================
Chris@16 21 //= Containedness<IntervalSet>
Chris@16 22 //==============================================================================
Chris@16 23 //------------------------------------------------------------------------------
Chris@16 24 //- bool contains(c T&, c P&) T:{S} P:{e i S} fragment_types
Chris@16 25 //------------------------------------------------------------------------------
Chris@16 26 template<class Type>
Chris@16 27 typename enable_if<is_interval_set<Type>, bool>::type
Chris@16 28 contains(const Type& super, const typename Type::element_type& element)
Chris@16 29 {
Chris@16 30 return !(icl::find(super, element) == super.end());
Chris@16 31 }
Chris@16 32
Chris@16 33 template<class Type>
Chris@16 34 typename enable_if<is_interval_set<Type>, bool>::type
Chris@16 35 contains(const Type& super, const typename Type::segment_type& inter_val)
Chris@16 36 {
Chris@16 37 typedef typename Type::const_iterator const_iterator;
Chris@16 38 if(icl::is_empty(inter_val))
Chris@16 39 return true;
Chris@16 40
Chris@16 41 std::pair<const_iterator, const_iterator> exterior
Chris@16 42 = super.equal_range(inter_val);
Chris@16 43 if(exterior.first == exterior.second)
Chris@16 44 return false;
Chris@16 45
Chris@16 46 const_iterator last_overlap = cyclic_prior(super, exterior.second);
Chris@16 47
Chris@16 48 return
Chris@16 49 icl::contains(hull(*(exterior.first), *last_overlap), inter_val)
Chris@16 50 && Interval_Set::is_joinable(super, exterior.first, last_overlap);
Chris@16 51 }
Chris@16 52
Chris@16 53 template<class Type, class OperandT>
Chris@16 54 typename enable_if<has_same_concept<is_interval_set, Type, OperandT>,
Chris@16 55 bool>::type
Chris@16 56 contains(const Type& super, const OperandT& sub)
Chris@16 57 {
Chris@16 58 return Interval_Set::contains(super, sub);
Chris@16 59 }
Chris@16 60
Chris@16 61 //==============================================================================
Chris@16 62 //= Addition<IntervalSet>
Chris@16 63 //==============================================================================
Chris@16 64 //------------------------------------------------------------------------------
Chris@16 65 //- T& add(T&, c P&) T:{S} P:{e i} fragment_types
Chris@16 66 //------------------------------------------------------------------------------
Chris@16 67 template<class Type>
Chris@16 68 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 69 add(Type& object, const typename Type::segment_type& operand)
Chris@16 70 {
Chris@16 71 return object.add(operand);
Chris@16 72 }
Chris@16 73
Chris@16 74 template<class Type>
Chris@16 75 inline typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 76 add(Type& object, const typename Type::element_type& operand)
Chris@16 77 {
Chris@16 78 typedef typename Type::segment_type segment_type;
Chris@16 79 return icl::add(object, icl::singleton<segment_type>(operand));
Chris@16 80 }
Chris@16 81
Chris@16 82 //------------------------------------------------------------------------------
Chris@16 83 //- T& add(T&, J, c P&) T:{S} P:{i} interval_type
Chris@16 84 //------------------------------------------------------------------------------
Chris@16 85 template<class Type>
Chris@16 86 inline typename enable_if<is_interval_set<Type>, typename Type::iterator>::type
Chris@16 87 add(Type& object, typename Type::iterator prior,
Chris@16 88 const typename Type::segment_type& operand)
Chris@16 89 {
Chris@16 90 return object.add(prior, operand);
Chris@16 91 }
Chris@16 92
Chris@16 93 //==============================================================================
Chris@16 94 //= Insertion<IntervalSet>
Chris@16 95 //==============================================================================
Chris@16 96 //------------------------------------------------------------------------------
Chris@16 97 //- T& insert(T&, c P&) T:{S} P:{e i} fragment_types
Chris@16 98 //------------------------------------------------------------------------------
Chris@16 99 template<class Type>
Chris@16 100 inline typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 101 insert(Type& object, const typename Type::segment_type& operand)
Chris@16 102 {
Chris@16 103 return icl::add(object, operand);
Chris@16 104 }
Chris@16 105
Chris@16 106 template<class Type>
Chris@16 107 inline typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 108 insert(Type& object, const typename Type::element_type& operand)
Chris@16 109 {
Chris@16 110 return icl::add(object, operand);
Chris@16 111 }
Chris@16 112
Chris@16 113 //------------------------------------------------------------------------------
Chris@16 114 //- T& insert(T&, J, c P&) T:{S} P:{i} with hint
Chris@16 115 //------------------------------------------------------------------------------
Chris@16 116 template<class Type>
Chris@16 117 inline typename enable_if<is_interval_set<Type>, typename Type::iterator>::type
Chris@16 118 insert(Type& object, typename Type::iterator prior,
Chris@16 119 const typename Type::segment_type& operand)
Chris@16 120 {
Chris@16 121 return icl::add(object, prior, operand);
Chris@16 122 }
Chris@16 123
Chris@16 124 //==============================================================================
Chris@16 125 //= Subtraction<IntervalSet>
Chris@16 126 //==============================================================================
Chris@16 127 //------------------------------------------------------------------------------
Chris@16 128 //- T& subtract(T&, c P&) T:{S} P:{e i} fragment_type
Chris@16 129 //------------------------------------------------------------------------------
Chris@16 130 template<class Type>
Chris@16 131 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 132 subtract(Type& object, const typename Type::segment_type& operand)
Chris@16 133 {
Chris@16 134 return object.subtract(operand);
Chris@16 135 }
Chris@16 136
Chris@16 137 template<class Type>
Chris@16 138 inline typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 139 subtract(Type& object, const typename Type::element_type& operand)
Chris@16 140 {
Chris@16 141 typedef typename Type::segment_type segment_type;
Chris@16 142 return icl::subtract(object, icl::singleton<segment_type>(operand));
Chris@16 143 }
Chris@16 144
Chris@16 145 //==============================================================================
Chris@16 146 //= Erasure<IntervalSet>
Chris@16 147 //==============================================================================
Chris@16 148 //------------------------------------------------------------------------------
Chris@16 149 //- T& erase(T&, c P&) T:{S} P:{e i} fragment_types
Chris@16 150 //------------------------------------------------------------------------------
Chris@16 151 template<class Type>
Chris@16 152 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 153 erase(Type& object, const typename Type::segment_type& minuend)
Chris@16 154 {
Chris@16 155 return icl::subtract(object, minuend);
Chris@16 156 }
Chris@16 157
Chris@16 158 template<class Type>
Chris@16 159 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 160 erase(Type& object, const typename Type::element_type& minuend)
Chris@16 161 {
Chris@16 162 return icl::subtract(object, minuend);
Chris@16 163 }
Chris@16 164
Chris@16 165 //==============================================================================
Chris@16 166 //= Intersection
Chris@16 167 //==============================================================================
Chris@16 168 //------------------------------------------------------------------------------
Chris@16 169 //- void add_intersection(T&, c T&, c P&) T:{S} P:{e i} fragment_types
Chris@16 170 //------------------------------------------------------------------------------
Chris@16 171 template<class Type>
Chris@16 172 typename enable_if<is_interval_set<Type>, void>::type
Chris@16 173 add_intersection(Type& section, const Type& object,
Chris@16 174 const typename Type::element_type& operand)
Chris@16 175 {
Chris@16 176 typedef typename Type::const_iterator const_iterator;
Chris@16 177 const_iterator found = icl::find(object, operand);
Chris@16 178 if(found != object.end())
Chris@16 179 icl::add(section, operand);
Chris@16 180 }
Chris@16 181
Chris@16 182
Chris@16 183 template<class Type>
Chris@16 184 typename enable_if<is_interval_set<Type>, void>::type
Chris@16 185 add_intersection(Type& section, const Type& object,
Chris@16 186 const typename Type::segment_type& segment)
Chris@16 187 {
Chris@16 188 typedef typename Type::const_iterator const_iterator;
Chris@16 189 typedef typename Type::iterator iterator;
Chris@16 190 typedef typename Type::interval_type interval_type;
Chris@16 191
Chris@16 192 if(icl::is_empty(segment))
Chris@16 193 return;
Chris@16 194
Chris@16 195 std::pair<const_iterator, const_iterator> exterior
Chris@16 196 = object.equal_range(segment);
Chris@16 197 if(exterior.first == exterior.second)
Chris@16 198 return;
Chris@16 199
Chris@16 200 iterator prior_ = section.end();
Chris@16 201 for(const_iterator it_=exterior.first; it_ != exterior.second; it_++)
Chris@16 202 {
Chris@16 203 interval_type common_interval = key_value<Type>(it_) & segment;
Chris@16 204 if(!icl::is_empty(common_interval))
Chris@16 205 prior_ = section.insert(prior_, common_interval);
Chris@16 206 }
Chris@16 207 }
Chris@16 208
Chris@16 209 //==============================================================================
Chris@16 210 //= Symmetric difference<IntervalSet>
Chris@16 211 //==============================================================================
Chris@16 212 //------------------------------------------------------------------------------
Chris@16 213 //- T& flip(T&, c P&) T:{S} P:{e i S'} fragment_types
Chris@16 214 //------------------------------------------------------------------------------
Chris@16 215 template<class Type>
Chris@16 216 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 217 flip(Type& object, const typename Type::element_type& operand)
Chris@16 218 {
Chris@16 219 if(icl::contains(object, operand))
Chris@16 220 return object -= operand;
Chris@16 221 else
Chris@16 222 return object += operand;
Chris@16 223 }
Chris@16 224
Chris@16 225 template<class Type>
Chris@16 226 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 227 flip(Type& object, const typename Type::segment_type& segment)
Chris@16 228 {
Chris@16 229 typedef typename Type::const_iterator const_iterator;
Chris@16 230 typedef typename Type::interval_type interval_type;
Chris@16 231 // That which is common shall be subtracted
Chris@16 232 // That which is not shall be added
Chris@16 233 // So x has to be 'complementary added' or flipped
Chris@16 234 interval_type span = segment;
Chris@16 235 std::pair<const_iterator, const_iterator> exterior
Chris@16 236 = object.equal_range(span);
Chris@16 237
Chris@16 238 const_iterator fst_ = exterior.first;
Chris@16 239 const_iterator end_ = exterior.second;
Chris@16 240
Chris@16 241 interval_type covered, left_over;
Chris@16 242 const_iterator it_ = fst_;
Chris@16 243 while(it_ != end_)
Chris@16 244 {
Chris@16 245 covered = *it_++;
Chris@16 246 //[a ... : span
Chris@16 247 // [b ... : covered
Chris@16 248 //[a b) : left_over
Chris@16 249 left_over = right_subtract(span, covered);
Chris@16 250 icl::subtract(object, span & covered); //That which is common shall be subtracted
Chris@16 251 icl::add(object, left_over); //That which is not shall be added
Chris@16 252
Chris@16 253 //... d) : span
Chris@16 254 //... c) : covered
Chris@16 255 // [c d) : span'
Chris@16 256 span = left_subtract(span, covered);
Chris@16 257 }
Chris@16 258
Chris@16 259 //If span is not empty here, it_ is not in the set so it_ shall be added
Chris@16 260 icl::add(object, span);
Chris@16 261 return object;
Chris@16 262 }
Chris@16 263
Chris@16 264
Chris@16 265 template<class Type, class OperandT>
Chris@16 266 typename enable_if<is_concept_compatible<is_interval_set, Type, OperandT>, Type>::type&
Chris@16 267 flip(Type& object, const OperandT& operand)
Chris@16 268 {
Chris@16 269 typedef typename OperandT::const_iterator const_iterator;
Chris@16 270
Chris@16 271 if(operand.empty())
Chris@16 272 return object;
Chris@16 273
Chris@16 274 const_iterator common_lwb, common_upb;
Chris@16 275
Chris@16 276 if(!Set::common_range(common_lwb, common_upb, operand, object))
Chris@16 277 return object += operand;
Chris@16 278
Chris@16 279 const_iterator it_ = operand.begin();
Chris@16 280
Chris@16 281 // All elements of operand left of the common range are added
Chris@16 282 while(it_ != common_lwb)
Chris@16 283 icl::add(object, *it_++);
Chris@16 284 // All elements of operand in the common range are symmertrically subtracted
Chris@16 285 while(it_ != common_upb)
Chris@16 286 icl::flip(object, *it_++);
Chris@16 287 // All elements of operand right of the common range are added
Chris@16 288 while(it_ != operand.end())
Chris@16 289 icl::add(object, *it_++);
Chris@16 290
Chris@16 291 return object;
Chris@16 292 }
Chris@16 293
Chris@16 294 //==============================================================================
Chris@16 295 //= Set selection
Chris@16 296 //==============================================================================
Chris@16 297 template<class Type>
Chris@16 298 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 299 domain(Type& dom, const Type& object)
Chris@16 300 {
Chris@16 301 typedef typename Type::const_iterator const_iterator;
Chris@16 302 typedef typename Type::iterator iterator;
Chris@16 303 dom.clear();
Chris@16 304 const_iterator it_ = object.begin();
Chris@16 305 iterator prior_ = dom.end();
Chris@16 306
Chris@16 307 while(it_ != object.end())
Chris@16 308 prior_ = icl::insert(dom, prior_, *it_++);
Chris@16 309
Chris@16 310 return dom;
Chris@16 311 }
Chris@16 312
Chris@16 313 template<class Type>
Chris@16 314 typename enable_if<is_interval_set<Type>, Type>::type&
Chris@16 315 between(Type& in_between, const Type& object)
Chris@16 316 {
Chris@16 317 typedef typename Type::const_iterator const_iterator;
Chris@16 318 typedef typename Type::iterator iterator;
Chris@16 319 in_between.clear();
Chris@16 320 const_iterator it_ = object.begin(), pred_;
Chris@16 321 iterator prior_ = in_between.end();
Chris@16 322
Chris@16 323 if(it_ != object.end())
Chris@16 324 pred_ = it_++;
Chris@16 325
Chris@16 326 while(it_ != object.end())
Chris@16 327 prior_ = icl::insert(in_between, prior_,
Chris@16 328 icl::between(*pred_++, *it_++));
Chris@16 329
Chris@16 330 return in_between;
Chris@16 331 }
Chris@16 332
Chris@16 333
Chris@16 334 //==============================================================================
Chris@16 335 //= Streaming
Chris@16 336 //==============================================================================
Chris@16 337 template<class CharType, class CharTraits, class Type>
Chris@16 338 typename enable_if<is_interval_set<Type>,
Chris@16 339 std::basic_ostream<CharType, CharTraits> >::type&
Chris@16 340 operator << (std::basic_ostream<CharType, CharTraits>& stream, const Type& object)
Chris@16 341 {
Chris@16 342 stream << "{";
Chris@16 343 ICL_const_FORALL(typename Type, it_, object)
Chris@16 344 stream << (*it_);
Chris@16 345
Chris@16 346 return stream << "}";
Chris@16 347 }
Chris@16 348
Chris@16 349
Chris@16 350 }} // namespace boost icl
Chris@16 351
Chris@16 352 #endif
Chris@16 353
Chris@16 354