annotate DEPENDENCIES/generic/include/boost/icl/detail/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_SUBSET_COMPARER_HPP_JOFA_090202
Chris@16 9 #define BOOST_ICL_SUBSET_COMPARER_HPP_JOFA_090202
Chris@16 10
Chris@16 11 #include <boost/mpl/and.hpp>
Chris@16 12 #include <boost/icl/type_traits/is_map.hpp>
Chris@16 13 #include <boost/icl/detail/notate.hpp>
Chris@16 14 #include <boost/icl/detail/relation_state.hpp>
Chris@16 15 #include <boost/icl/type_traits/identity_element.hpp>
Chris@16 16 #include <boost/icl/type_traits/codomain_type_of.hpp>
Chris@16 17 #include <boost/icl/type_traits/is_concept_equivalent.hpp>
Chris@16 18 #include <boost/icl/type_traits/is_element_container.hpp>
Chris@16 19 #include <boost/icl/concept/interval_set_value.hpp>
Chris@16 20 #include <boost/icl/concept/map_value.hpp>
Chris@16 21
Chris@16 22 namespace boost{namespace icl
Chris@16 23 {
Chris@16 24
Chris@16 25 #ifdef BOOST_MSVC
Chris@16 26 #pragma warning(push)
Chris@16 27 #pragma warning(disable:4127) // conditional expression is constant
Chris@16 28 #endif
Chris@16 29
Chris@16 30 namespace Set
Chris@16 31 {
Chris@16 32
Chris@16 33 //------------------------------------------------------------------------------
Chris@16 34 template<class LeftT, class RightT>
Chris@16 35 struct settic_codomain_compare
Chris@16 36 {
Chris@16 37 static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
Chris@16 38 {
Chris@16 39 return inclusion_compare( co_value<LeftT>(left_),
Chris@16 40 co_value<RightT>(right_));
Chris@16 41 }
Chris@16 42 };
Chris@16 43
Chris@16 44 template<class LeftT, class RightT>
Chris@16 45 struct atomic_codomain_compare
Chris@16 46 {
Chris@16 47 static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
Chris@16 48 {
Chris@16 49 if(co_value<LeftT>(left_) == co_value<RightT>(right_))
Chris@16 50 return inclusion::equal;
Chris@16 51 else
Chris@16 52 return inclusion::unrelated;
Chris@16 53 }
Chris@16 54 };
Chris@16 55
Chris@16 56 template<class LeftT, class RightT>
Chris@16 57 struct empty_codomain_compare
Chris@16 58 {
Chris@16 59 static int apply(typename LeftT::const_iterator&, typename RightT::const_iterator&)
Chris@16 60 {
Chris@16 61 return inclusion::equal;
Chris@16 62 }
Chris@16 63 };
Chris@16 64
Chris@16 65 template<class LeftT, class RightT>
Chris@16 66 struct map_codomain_compare
Chris@16 67 {
Chris@16 68 static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
Chris@16 69 {
Chris@16 70 using namespace boost::mpl;
Chris@16 71 typedef typename LeftT::codomain_type LeftCodomainT;
Chris@16 72 typedef typename RightT::codomain_type RightCodomainT;
Chris@16 73
Chris@16 74 return
Chris@16 75 if_<
Chris@16 76 bool_<is_concept_equivalent<is_set,LeftCodomainT,
Chris@16 77 RightCodomainT>::value>,
Chris@16 78 settic_codomain_compare<LeftT,RightT>,
Chris@16 79 atomic_codomain_compare<LeftT,RightT>
Chris@16 80 >
Chris@16 81 ::type::apply(left_, right_);
Chris@16 82 }
Chris@16 83 };
Chris@16 84
Chris@16 85
Chris@16 86 //------------------------------------------------------------------------------
Chris@16 87 template<class LeftT, class RightT>
Chris@16 88 class subset_comparer
Chris@16 89 {
Chris@16 90 private:
Chris@16 91 subset_comparer& operator = (const subset_comparer&);
Chris@16 92 public:
Chris@16 93 typedef typename LeftT::const_iterator LeftIterT;
Chris@16 94 typedef typename RightT::const_iterator RightIterT;
Chris@16 95
Chris@16 96 BOOST_STATIC_CONSTANT(bool,
Chris@16 97 _compare_codomain = (mpl::and_<is_map<LeftT>, is_map<RightT> >::value));
Chris@16 98
Chris@16 99 subset_comparer(const LeftT& left,
Chris@16 100 const RightT& right,
Chris@16 101 const LeftIterT& left_end,
Chris@16 102 const RightIterT& right_end)
Chris@16 103 : _left(left), _right(right),
Chris@16 104 _left_end(left_end), _right_end(right_end), _result(equal)
Chris@16 105 {}
Chris@16 106
Chris@16 107 enum{nextboth, stop};
Chris@16 108
Chris@16 109 enum
Chris@16 110 {
Chris@16 111 unrelated = inclusion::unrelated,
Chris@16 112 subset = inclusion::subset, // left is_subset_of right
Chris@16 113 superset = inclusion::superset, // left is_superset_of right
Chris@16 114 equal = inclusion::equal // equal = subset | superset
Chris@16 115 };
Chris@16 116
Chris@16 117 int result()const{ return _result; }
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 typedef typename codomain_type_of<LeftT>::type LeftCodomainT;
Chris@16 123 typedef typename codomain_type_of<RightT>::type RightCodomainT;
Chris@16 124
Chris@16 125 return
Chris@16 126 if_<
Chris@16 127 bool_<is_concept_equivalent<is_element_map,LeftT,RightT>::value>,
Chris@16 128 map_codomain_compare<LeftT,RightT>,
Chris@16 129 empty_codomain_compare<LeftT,RightT>
Chris@16 130 >
Chris@16 131 ::type::apply(left,right);
Chris@16 132 }
Chris@16 133
Chris@16 134 int restrict_result(int state) { return _result &= state; }
Chris@16 135
Chris@16 136 int next_both(LeftIterT& left, RightIterT& right)
Chris@16 137 {
Chris@16 138 if(left == _left_end && right == _right_end)
Chris@16 139 return stop;
Chris@16 140 else if(left == _left_end)
Chris@16 141 {
Chris@16 142 restrict_result(subset);
Chris@16 143 return stop;
Chris@16 144 }
Chris@16 145 else if(right == _right_end)
Chris@16 146 {
Chris@16 147 restrict_result(superset);
Chris@16 148 return stop;
Chris@16 149 }
Chris@16 150 else if(typename LeftT::key_compare()(key_value<LeftT>(left), key_value<RightT>(right)))
Chris@16 151 { // left: *left . . *joint_ left could be superset
Chris@16 152 // right: *right ... if joint_ exists
Chris@16 153 restrict_result(superset);
Chris@16 154 if(unrelated == _result)
Chris@16 155 return stop;
Chris@16 156 else
Chris@16 157 {
Chris@16 158 LeftIterT joint_ = _left.lower_bound(key_value<RightT>(right));
Chris@16 159 if( joint_ == _left.end()
Chris@16 160 || typename LeftT::key_compare()(key_value<RightT>(right), key_value<LeftT>(joint_)))
Chris@16 161 {
Chris@16 162 _result = unrelated;
Chris@16 163 return stop;
Chris@16 164 }
Chris@16 165 else
Chris@16 166 left = joint_;
Chris@16 167 }
Chris@16 168 }
Chris@16 169 else if(typename LeftT::key_compare()(key_value<RightT>(right), key_value<LeftT>(left)))
Chris@16 170 { // left: *left left could be subset
Chris@16 171 // right:*right . . .*joint_ if *joint_ exists
Chris@16 172 restrict_result(subset);
Chris@16 173 if(unrelated == _result)
Chris@16 174 return stop;
Chris@16 175 else
Chris@16 176 {
Chris@16 177 RightIterT joint_ = _right.lower_bound(key_value<LeftT>(left));
Chris@16 178 if( joint_ == _right.end()
Chris@16 179 || typename LeftT::key_compare()(key_value<LeftT>(left), key_value<RightT>(joint_)))
Chris@16 180 {
Chris@16 181 _result = unrelated;
Chris@16 182 return stop;
Chris@16 183 }
Chris@16 184 else
Chris@16 185 right = joint_;
Chris@16 186 }
Chris@16 187 }
Chris@16 188
Chris@16 189 // left =key= right
Chris@16 190 if(_compare_codomain)
Chris@16 191 if(unrelated == restrict_result(co_compare(left,right)))
Chris@16 192 return stop;
Chris@16 193
Chris@16 194 ++left;
Chris@16 195 ++right;
Chris@16 196 return nextboth;
Chris@16 197 }
Chris@16 198
Chris@16 199 private:
Chris@16 200 const LeftT& _left;
Chris@16 201 const RightT& _right;
Chris@16 202 LeftIterT _left_end;
Chris@16 203 RightIterT _right_end;
Chris@16 204 int _result;
Chris@16 205 };
Chris@16 206
Chris@16 207
Chris@16 208
Chris@16 209
Chris@16 210
Chris@16 211 //------------------------------------------------------------------------------
Chris@16 212 // Subset/superset comparison on ranges of two interval container
Chris@16 213 //------------------------------------------------------------------------------
Chris@16 214 template<class LeftT, class RightT>
Chris@16 215 int subset_compare
Chris@16 216 (
Chris@16 217 const LeftT& left, //sub
Chris@16 218 const RightT& right, //super
Chris@16 219 typename LeftT::const_iterator left_begin,
Chris@16 220 typename LeftT::const_iterator left_end,
Chris@16 221 typename RightT::const_iterator right_begin,
Chris@16 222 typename RightT::const_iterator right_end
Chris@16 223 )
Chris@16 224 {
Chris@16 225 typedef subset_comparer<LeftT,RightT> Step;
Chris@16 226 Step step(left, right, left_end, right_end);
Chris@16 227
Chris@16 228 typename LeftT::const_iterator left_ = left_begin;
Chris@16 229 typename RightT::const_iterator right_ = right_begin;
Chris@16 230
Chris@16 231 int state = Step::nextboth;
Chris@16 232 while(state != Step::stop)
Chris@16 233 state = step.next_both(left_, right_);
Chris@16 234
Chris@16 235 return step.result();
Chris@16 236 }
Chris@16 237
Chris@16 238 template<class LeftT, class RightT>
Chris@16 239 int subset_compare(const LeftT& left, const RightT& right)
Chris@16 240 {
Chris@16 241 return subset_compare
Chris@16 242 (
Chris@16 243 left, right,
Chris@16 244 left.begin(), left.end(),
Chris@16 245 right.begin(), right.end()
Chris@16 246 );
Chris@16 247 }
Chris@16 248
Chris@16 249
Chris@16 250 } // namespace Set
Chris@16 251
Chris@16 252 #ifdef BOOST_MSVC
Chris@16 253 #pragma warning(pop)
Chris@16 254 #endif
Chris@16 255
Chris@16 256 }} // namespace icl boost
Chris@16 257
Chris@16 258 #endif
Chris@16 259