File indexing completed on 2025-01-18 09:38:19
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_ICL_ELEMENT_COMPARER_HPP_JOFA_090202
0009 #define BOOST_ICL_ELEMENT_COMPARER_HPP_JOFA_090202
0010
0011 #include <boost/mpl/and.hpp>
0012 #include <boost/icl/type_traits/is_map.hpp>
0013 #include <boost/icl/detail/notate.hpp>
0014 #include <boost/icl/type_traits/identity_element.hpp>
0015
0016 namespace boost{namespace icl
0017 {
0018
0019 namespace Interval_Set
0020 {
0021
0022 template<class LeftT, class RightT>
0023 class element_comparer
0024 {
0025 public:
0026 typedef typename LeftT::const_iterator LeftIterT;
0027 typedef typename RightT::const_iterator RightIterT;
0028
0029 BOOST_STATIC_CONSTANT(bool,
0030 _compare_codomain = (mpl::and_<is_map<LeftT>, is_map<RightT> >::value));
0031
0032 element_comparer(const LeftT& left,
0033 const RightT& right,
0034 const LeftIterT& left_end,
0035 const RightIterT& right_end)
0036 : _left(left), _right(right),
0037 _left_end(left_end), _right_end(right_end), _result(equal)
0038 {}
0039
0040 enum{nextboth, nextleft, nextright, stop};
0041
0042 enum
0043 {
0044 less = comparison::less,
0045 equal = comparison::equal,
0046 greater = comparison::greater
0047 };
0048
0049 int result()const{ return _result; }
0050
0051 bool covalues_are_equal(LeftIterT& left, RightIterT& right)
0052 {
0053 if(co_value<LeftT>(left) < co_value<RightT>(right))
0054 _result = less;
0055 if(co_value<RightT>(right) < co_value<LeftT>(left))
0056 _result = greater;
0057 return _result == equal;
0058 }
0059
0060 int proceed(LeftIterT& left, RightIterT& right)
0061 {
0062 if(upper_less(key_value<LeftT>(left), key_value<RightT>(right)))
0063 {
0064 _prior_left = left;
0065 ++left;
0066 return nextleft;
0067 }
0068 else if(upper_less(key_value<RightT>(right), key_value<LeftT>(left)))
0069 {
0070 _prior_right = right;
0071 ++right;
0072 return nextright;
0073 }
0074 else
0075 {
0076 ++left;
0077 ++right;
0078 return nextboth;
0079 }
0080 }
0081
0082 int next_both(LeftIterT& left, RightIterT& right)
0083 {
0084 if(left == _left_end)
0085 {
0086 _result = (right == _right_end) ? equal : less;
0087 return stop;
0088 }
0089
0090
0091 if(right == _right_end)
0092 {
0093 _result = greater;
0094 return stop;
0095 }
0096
0097
0098 if(lower_less(key_value<LeftT>(left), key_value<RightT>(right)))
0099 {
0100
0101 _result = less;
0102 return stop;
0103 }
0104
0105 if(lower_less(key_value<LeftT>(right), key_value<RightT>(left)))
0106 {
0107
0108 _result = greater;
0109 return stop;
0110 }
0111
0112 if(_compare_codomain && !covalues_are_equal(left, right))
0113 return stop;
0114
0115 return proceed(left, right);
0116 }
0117
0118 int next_left(LeftIterT& left, RightIterT& right)
0119 {
0120 if(left == _left_end)
0121 {
0122
0123 _result = less;
0124 return stop;
0125 }
0126
0127 if(!key_value<LeftT>(_prior_left).touches(key_value<LeftT>(left)))
0128 {
0129
0130 _result = greater;
0131 return stop;
0132 }
0133
0134 if(_compare_codomain && !covalues_are_equal(left, right))
0135 return stop;
0136
0137 return proceed(left, right);
0138 }
0139
0140 int next_right(LeftIterT& left, RightIterT& right)
0141 {
0142 if(right == _right_end)
0143 {
0144
0145 _result = greater;
0146 return stop;
0147 }
0148
0149 if(!key_value<RightT>(_prior_right).touches(key_value<RightT>(right)))
0150 {
0151
0152
0153 _result = less;
0154 return stop;
0155 }
0156
0157 if(_compare_codomain && !covalues_are_equal(left, right))
0158 return stop;
0159
0160 return proceed(left, right);
0161 }
0162
0163 private:
0164 const LeftT& _left;
0165 const RightT& _right;
0166 LeftIterT _left_end;
0167 RightIterT _right_end;
0168 LeftIterT _prior_left;
0169 RightIterT _prior_right;
0170 int _result;
0171 };
0172
0173
0174
0175 template<class LeftT, class RightT>
0176 int element_compare
0177 (
0178 const LeftT& left,
0179 const RightT& right,
0180 typename LeftT::const_iterator left_begin,
0181 typename LeftT::const_iterator left_end,
0182 typename RightT::const_iterator right_begin,
0183 typename RightT::const_iterator right_end
0184 )
0185 {
0186 typedef element_comparer<LeftT,RightT> Step;
0187 Step step(left, right, left_end, right_end);
0188
0189 typename LeftT::const_iterator left_ = left_begin;
0190 typename RightT::const_iterator right_ = right_begin;
0191
0192 int state = Step::nextboth;
0193 while(state != Step::stop)
0194 {
0195 switch(state){
0196 case Step::nextboth: state = step.next_both (left_, right_); break;
0197 case Step::nextleft: state = step.next_left (left_, right_); break;
0198 case Step::nextright: state = step.next_right(left_, right_); break;
0199 }
0200 }
0201 return step.result();
0202 }
0203
0204
0205 }
0206
0207 }}
0208
0209 #endif
0210