annotate DEPENDENCIES/generic/include/boost/icl/detail/interval_subset_comparer.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) 2008-2009: 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_INTERVAL_SUBSET_COMPARER_HPP_JOFA_090827
Chris@16 9 #define BOOST_ICL_INTERVAL_SUBSET_COMPARER_HPP_JOFA_090827
Chris@16 10
Chris@16 11 #include <boost/icl/type_traits/is_map.hpp>
Chris@16 12 #include <boost/icl/detail/notate.hpp>
Chris@16 13 #include <boost/icl/detail/relation_state.hpp>
Chris@16 14 #include <boost/icl/type_traits/identity_element.hpp>
Chris@16 15 #include <boost/icl/type_traits/is_concept_equivalent.hpp>
Chris@16 16 #include <boost/icl/type_traits/is_interval_container.hpp>
Chris@16 17 #include <boost/icl/type_traits/is_set.hpp>
Chris@16 18 #include <boost/icl/concept/interval_set_value.hpp>
Chris@16 19
Chris@16 20 namespace boost{namespace icl
Chris@16 21 {
Chris@16 22
Chris@16 23 #ifdef BOOST_MSVC
Chris@16 24 #pragma warning(push)
Chris@16 25 #pragma warning(disable:4127) // conditional expression is constant
Chris@16 26 #endif
Chris@16 27
Chris@16 28 namespace Interval_Set
Chris@16 29 {
Chris@16 30
Chris@16 31 //------------------------------------------------------------------------------
Chris@16 32 template<class LeftT, class RightT>
Chris@16 33 struct settic_codomain_compare
Chris@16 34 {
Chris@16 35 static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
Chris@16 36 {
Chris@16 37 return inclusion_compare( icl::co_value<LeftT>(left_),
Chris@16 38 icl::co_value<RightT>(right_));
Chris@16 39 }
Chris@16 40 };
Chris@16 41
Chris@16 42 template<class LeftT, class RightT>
Chris@16 43 struct atomic_codomain_compare
Chris@16 44 {
Chris@16 45 static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
Chris@16 46 {
Chris@16 47 if(icl::co_value<LeftT>(left_) == icl::co_value<RightT>(right_))
Chris@16 48 return inclusion::equal;
Chris@16 49 else
Chris@16 50 return inclusion::unrelated;
Chris@16 51 }
Chris@16 52 };
Chris@16 53
Chris@16 54 template<class LeftT, class RightT>
Chris@16 55 struct empty_codomain_compare
Chris@16 56 {
Chris@16 57 static int apply(typename LeftT::const_iterator&, typename RightT::const_iterator)
Chris@16 58 {
Chris@16 59 return inclusion::equal;
Chris@16 60 }
Chris@16 61 };
Chris@16 62
Chris@16 63 template<class LeftT, class RightT>
Chris@16 64 struct map_codomain_compare
Chris@16 65 {
Chris@16 66 static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
Chris@16 67 {
Chris@16 68 using namespace boost::mpl;
Chris@16 69 typedef typename LeftT::codomain_type LeftCodomainT;
Chris@16 70 typedef typename RightT::codomain_type RightCodomainT;
Chris@16 71
Chris@16 72 return
Chris@16 73 if_<
Chris@16 74 bool_<is_concept_equivalent<is_set,LeftCodomainT,
Chris@16 75 RightCodomainT>::value>,
Chris@16 76 settic_codomain_compare<LeftT,RightT>,
Chris@16 77 atomic_codomain_compare<LeftT,RightT>
Chris@16 78 >
Chris@16 79 ::type::apply(left_, right_);
Chris@16 80 }
Chris@16 81 };
Chris@16 82
Chris@16 83
Chris@16 84 //------------------------------------------------------------------------------
Chris@16 85 template<class LeftT, class RightT>
Chris@16 86 class subset_comparer
Chris@16 87 {
Chris@16 88 private:
Chris@16 89 subset_comparer& operator = (const subset_comparer&);
Chris@16 90 public:
Chris@16 91 typedef typename LeftT::const_iterator LeftIterT;
Chris@16 92 typedef typename RightT::const_iterator RightIterT;
Chris@16 93
Chris@16 94 BOOST_STATIC_CONSTANT(bool,
Chris@16 95 _compare_codomain = (mpl::and_<is_map<LeftT>, is_map<RightT> >::value));
Chris@16 96
Chris@16 97
Chris@16 98 subset_comparer(const LeftT& left,
Chris@16 99 const RightT& right,
Chris@16 100 const LeftIterT& left_end,
Chris@16 101 const RightIterT& right_end)
Chris@16 102 : _left(left), _right(right),
Chris@16 103 _left_end(left_end), _right_end(right_end), _result(equal)
Chris@16 104 {}
Chris@16 105
Chris@16 106 enum{nextboth, nextleft, nextright, stop};
Chris@16 107
Chris@16 108 enum
Chris@16 109 {
Chris@16 110 unrelated = inclusion::unrelated,
Chris@16 111 subset = inclusion::subset, // left is_subset_of right
Chris@16 112 superset = inclusion::superset, // left is_superset_of right
Chris@16 113 equal = inclusion::equal // equal = subset | superset
Chris@16 114 };
Chris@16 115
Chris@16 116 int result()const{ return _result; }
Chris@16 117
Chris@16 118
Chris@16 119 int co_compare(LeftIterT& left, RightIterT& right)
Chris@16 120 {
Chris@16 121 using namespace boost::mpl;
Chris@16 122
Chris@16 123 return
Chris@16 124 if_<
Chris@16 125 bool_<is_concept_equivalent<is_interval_map,LeftT,RightT>::value>,
Chris@16 126 map_codomain_compare<LeftT,RightT>,
Chris@16 127 empty_codomain_compare<LeftT,RightT>
Chris@16 128 >
Chris@16 129 ::type::apply(left,right);
Chris@16 130 }
Chris@16 131
Chris@16 132 int restrict_result(int state) { return _result &= state; }
Chris@16 133
Chris@16 134 int proceed(LeftIterT& left, RightIterT& right)
Chris@16 135 {
Chris@16 136 if(upper_less(key_value<LeftT>(left), key_value<RightT>(right)))
Chris@16 137 { // left ..)
Chris@16 138 // right .....)
Chris@16 139 _prior_left = left;
Chris@16 140 ++left;
Chris@16 141 return nextleft;
Chris@16 142 }
Chris@16 143 else if(upper_less(key_value<RightT>(right), key_value<LeftT>(left)))
Chris@16 144 { // left .....)
Chris@16 145 // right ..)
Chris@16 146 _prior_right = right;
Chris@16 147 ++right;
Chris@16 148 return nextright;
Chris@16 149 }
Chris@16 150 else//key_value<LeftT>(left).upper_equal(key_value<RightT>(right))
Chris@16 151 { // left ..)
Chris@16 152 // right ..)
Chris@16 153 ++left;
Chris@16 154 ++right;
Chris@16 155 return nextboth;
Chris@16 156 }
Chris@16 157 }
Chris@16 158
Chris@16 159 int next_both(LeftIterT& left, RightIterT& right)
Chris@16 160 {
Chris@16 161 if(left == _left_end && right == _right_end)
Chris@16 162 return stop;
Chris@16 163 else if(left == _left_end)
Chris@16 164 { // left: ....end left could be subset
Chris@16 165 // right:....[..
Chris@16 166 restrict_result(subset);
Chris@16 167 return stop;
Chris@16 168 }
Chris@16 169 else if(right == _right_end)
Chris@16 170 { // left: ....[.. left could be superset
Chris@16 171 // right:....end
Chris@16 172 restrict_result(superset);
Chris@16 173 return stop;
Chris@16 174 }
Chris@16 175 else if(exclusive_less(key_value<LeftT>(left), key_value<RightT>(right)))
Chris@16 176 { // left: [..) . . .[---) left could be superset
Chris@16 177 // right: [..).... if [---) exists
Chris@16 178 restrict_result(superset);
Chris@16 179 if(unrelated == _result)
Chris@16 180 return stop;
Chris@16 181 else
Chris@16 182 {
Chris@16 183 LeftIterT joint_ = _left.lower_bound(key_value<RightT>(right));
Chris@16 184 if(joint_ == _left.end())
Chris@16 185 {
Chris@16 186 _result = unrelated;
Chris@16 187 return stop;
Chris@16 188 }
Chris@16 189 else
Chris@16 190 {
Chris@16 191 left = joint_;
Chris@16 192 return nextboth;
Chris@16 193 }
Chris@16 194 }
Chris@16 195 }
Chris@16 196 else if(exclusive_less(key_value<RightT>(right), key_value<LeftT>(left)))
Chris@16 197 { // left: [.. left could be subset
Chris@16 198 // right:....) . . .[---) if [---) exists
Chris@16 199 restrict_result(subset);
Chris@16 200 if(unrelated == _result)
Chris@16 201 return stop;
Chris@16 202 else
Chris@16 203 {
Chris@16 204 RightIterT joint_ = _right.lower_bound(key_value<LeftT>(left));
Chris@16 205 if(joint_ == _right.end())
Chris@16 206 {
Chris@16 207 _result = unrelated;
Chris@16 208 return stop;
Chris@16 209 }
Chris@16 210 else
Chris@16 211 {
Chris@16 212 right = joint_;
Chris@16 213 return nextboth;
Chris@16 214 }
Chris@16 215 }
Chris@16 216 }
Chris@16 217
Chris@16 218 // left and right have intervals with nonempty intersection:
Chris@16 219 if(_compare_codomain)
Chris@16 220 if(unrelated == restrict_result(co_compare(left,right)))
Chris@16 221 return stop;
Chris@16 222
Chris@16 223 // examine left borders only. Right borders are checked in proceed
Chris@16 224 if(lower_less(key_value<LeftT>(left), key_value<RightT>(right)))
Chris@16 225 { // left: ....[... left could be superset
Chris@16 226 // right:.... [..
Chris@16 227 if(unrelated == restrict_result(superset))
Chris@16 228 return stop;
Chris@16 229 }
Chris@16 230 else if(lower_less(key_value<RightT>(right), key_value<LeftT>(left)))
Chris@16 231 { // left: .... [.. left can be subset
Chris@16 232 // right:....[...
Chris@16 233 if(unrelated == restrict_result(subset))
Chris@16 234 return stop;
Chris@16 235 }
Chris@16 236 //else key_value<LeftT>(right).lower_equal(key_value<RightT>(left))
Chris@16 237 // left: ....[.. both can be equal
Chris@16 238 // right:....[..
Chris@16 239 // nothing to do: proceed
Chris@16 240
Chris@16 241 return proceed(left, right);
Chris@16 242 }
Chris@16 243
Chris@16 244 int next_left(LeftIterT& left, RightIterT& right)
Chris@16 245 {
Chris@16 246 if(left == _left_end)
Chris@16 247 { // left: ..)end left could be subset
Chris@16 248 // right:......)
Chris@16 249 restrict_result(subset);
Chris@16 250 return stop;
Chris@16 251 }
Chris@16 252 else if(!touches(key_value<LeftT>(_prior_left), key_value<LeftT>(left)))
Chris@16 253 { // left: ..) [..
Chris@16 254 // right:.........)
Chris@16 255 if(lower_less(key_value<RightT>(right), key_value<LeftT>(left)))
Chris@16 256 { // ..) [.. left could be subset
Chris@16 257 // ..........)
Chris@16 258 if(unrelated == restrict_result(subset))
Chris@16 259 return stop;
Chris@16 260 }
Chris@16 261 //else ..) [...
Chris@16 262 // [..
Chris@16 263 if(_compare_codomain && intersects(key_value<LeftT>(left),key_value<RightT>(right)) )
Chris@16 264 if(unrelated == restrict_result(co_compare(left,right)))
Chris@16 265 return stop;
Chris@16 266 }
Chris@16 267 else
Chris@16 268 { // left: ..)[.. left could be subset
Chris@16 269 // right:.......)
Chris@16 270 if(_compare_codomain && intersects(key_value<LeftT>(left), key_value<RightT>(right)) )
Chris@16 271 if(unrelated == restrict_result(co_compare(left,right)))
Chris@16 272 return stop;
Chris@16 273 }
Chris@16 274
Chris@16 275 return proceed(left, right);
Chris@16 276 }
Chris@16 277
Chris@16 278
Chris@16 279 int next_right(LeftIterT& left, RightIterT& right)
Chris@16 280 {
Chris@16 281 if(right == _right_end)
Chris@16 282 { // left: ......) left could be superset
Chris@16 283 // right:..)end
Chris@16 284 restrict_result(superset);
Chris@16 285 return stop;
Chris@16 286 }
Chris@16 287 else if(!touches(key_value<RightT>(_prior_right), key_value<RightT>(right)))
Chris@16 288 { // left: .........)
Chris@16 289 // right:..) [..
Chris@16 290 if(lower_less(key_value<LeftT>(left), key_value<RightT>(right)))
Chris@16 291 { // [....) left could be superset
Chris@16 292 // ..) [..
Chris@16 293 if(unrelated == restrict_result(superset))
Chris@16 294 return stop;
Chris@16 295 }
Chris@16 296 //else [....)
Chris@16 297 // ..) [..
Chris@16 298 if(_compare_codomain && intersects(key_value<LeftT>(left), key_value<RightT>(right)) )
Chris@16 299 if(unrelated == restrict_result(co_compare(left,right)))
Chris@16 300 return stop;
Chris@16 301 }
Chris@16 302 else
Chris@16 303 {
Chris@16 304 if(_compare_codomain && intersects(key_value<LeftT>(left), key_value<RightT>(right)) )
Chris@16 305 if(unrelated == restrict_result(co_compare(left,right)))
Chris@16 306 return stop;
Chris@16 307 }
Chris@16 308
Chris@16 309 return proceed(left, right);
Chris@16 310 }
Chris@16 311
Chris@16 312 private:
Chris@16 313 const LeftT& _left;
Chris@16 314 const RightT& _right;
Chris@16 315 LeftIterT _left_end;
Chris@16 316 RightIterT _right_end;
Chris@16 317 LeftIterT _prior_left;
Chris@16 318 RightIterT _prior_right;
Chris@16 319 int _result;
Chris@16 320 };
Chris@16 321
Chris@16 322
Chris@16 323
Chris@16 324
Chris@16 325
Chris@16 326 //------------------------------------------------------------------------------
Chris@16 327 // Subset/superset comparison on ranges of two interval container
Chris@16 328 //------------------------------------------------------------------------------
Chris@16 329 template<class LeftT, class RightT>
Chris@16 330 int subset_compare
Chris@16 331 (
Chris@16 332 const LeftT& left, //sub
Chris@16 333 const RightT& right, //super
Chris@16 334 typename LeftT::const_iterator left_begin,
Chris@16 335 typename LeftT::const_iterator left_end,
Chris@16 336 typename RightT::const_iterator right_begin,
Chris@16 337 typename RightT::const_iterator right_end
Chris@16 338 )
Chris@16 339 {
Chris@16 340 typedef subset_comparer<LeftT,RightT> Step;
Chris@16 341 Step step(left, right, left_end, right_end);
Chris@16 342
Chris@16 343 typename LeftT::const_iterator left_ = left_begin;
Chris@16 344 typename RightT::const_iterator right_ = right_begin;
Chris@16 345
Chris@16 346 int state = Step::nextboth;
Chris@16 347 while(state != Step::stop)
Chris@16 348 {
Chris@16 349 switch(state){
Chris@16 350 case Step::nextboth: state = step.next_both(left_, right_); break;
Chris@16 351 case Step::nextleft: state = step.next_left(left_, right_); break;
Chris@16 352 case Step::nextright: state = step.next_right(left_, right_); break;
Chris@16 353 }
Chris@16 354 }
Chris@16 355 return step.result();
Chris@16 356 }
Chris@16 357
Chris@16 358
Chris@16 359 } // namespace Interval_Set
Chris@16 360
Chris@16 361 #ifdef BOOST_MSVC
Chris@16 362 #pragma warning(pop)
Chris@16 363 #endif
Chris@16 364
Chris@16 365 }} // namespace icl boost
Chris@16 366
Chris@16 367 #endif
Chris@16 368