Mercurial > hg > vamp-build-and-test
diff DEPENDENCIES/generic/include/boost/icl/detail/element_comparer.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DEPENDENCIES/generic/include/boost/icl/detail/element_comparer.hpp Tue Aug 05 11:11:38 2014 +0100 @@ -0,0 +1,210 @@ +/*-----------------------------------------------------------------------------+ +Copyright (c) 2008-2009: Joachim Faulhaber ++------------------------------------------------------------------------------+ + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENCE.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) ++-----------------------------------------------------------------------------*/ +#ifndef BOOST_ICL_ELEMENT_COMPARER_HPP_JOFA_090202 +#define BOOST_ICL_ELEMENT_COMPARER_HPP_JOFA_090202 + +#include <boost/mpl/and.hpp> +#include <boost/icl/type_traits/is_map.hpp> +#include <boost/icl/detail/notate.hpp> +#include <boost/icl/type_traits/identity_element.hpp> + +namespace boost{namespace icl +{ + +namespace Interval_Set +{ + +template<class LeftT, class RightT> +class element_comparer +{ +public: + typedef typename LeftT::const_iterator LeftIterT; + typedef typename RightT::const_iterator RightIterT; + + BOOST_STATIC_CONSTANT(bool, + _compare_codomain = (mpl::and_<is_map<LeftT>, is_map<RightT> >::value)); + + element_comparer(const LeftT& left, + const RightT& right, + const LeftIterT& left_end, + const RightIterT& right_end) + : _left(left), _right(right), + _left_end(left_end), _right_end(right_end), _result(equal) + {} + + enum{nextboth, nextleft, nextright, stop}; + + enum + { + less = comparison::less, + equal = comparison::equal, + greater = comparison::greater + }; + + int result()const{ return _result; } + + bool covalues_are_equal(LeftIterT& left, RightIterT& right) + { + if(co_value<LeftT>(left) < co_value<RightT>(right)) + _result = less; + if(co_value<RightT>(right) < co_value<LeftT>(left)) + _result = greater; + return _result == equal; + } + + int proceed(LeftIterT& left, RightIterT& right) + { + if(upper_less(key_value<LeftT>(left), key_value<RightT>(right))) + { + _prior_left = left; + ++left; + return nextleft; + } + else if(upper_less(key_value<RightT>(right), key_value<LeftT>(left))) + { + _prior_right = right; + ++right; + return nextright; + } + else + { + ++left; + ++right; + return nextboth; + } + } + + int next_both(LeftIterT& left, RightIterT& right) + { + if(left == _left_end) + { + _result = (right == _right_end) ? equal : less; + return stop; + } + + // left != _left_end + if(right == _right_end) + { + _result = greater; + return stop; + } + + // The starting intervals have to begin equally + if(lower_less(key_value<LeftT>(left), key_value<RightT>(right))) + { // left: same A... = sameA... + // right:same B.. = sameB... + _result = less; + return stop; + } + + if(lower_less(key_value<LeftT>(right), key_value<RightT>(left))) + { // left: same B.. = sameB... + // right:same A... = sameA... + _result = greater; + return stop; + } + + if(_compare_codomain && !covalues_are_equal(left, right)) + return stop; + + return proceed(left, right); + } + + int next_left(LeftIterT& left, RightIterT& right) + { + if(left == _left_end) + { // left: same + // right:sameA... + _result = less; + return stop; + } + + if(!key_value<LeftT>(_prior_left).touches(key_value<LeftT>(left))) + { // left: same B = sameB... + // right:sameA = sameA... + _result = greater; + return stop; + } + + if(_compare_codomain && !covalues_are_equal(left, right)) + return stop; + + return proceed(left, right); + } + + int next_right(LeftIterT& left, RightIterT& right) + { + if(right == _right_end) + { // left: sameA... + // right:same + _result = greater; + return stop; + } + + if(!key_value<RightT>(_prior_right).touches(key_value<RightT>(right))) + { + // left: sameA... = sameA... + // right:same B.. = sameB... + _result = less; + return stop; + } + + if(_compare_codomain && !covalues_are_equal(left, right)) + return stop; + + return proceed(left, right); + } + +private: + const LeftT& _left; + const RightT& _right; + LeftIterT _left_end; + RightIterT _right_end; + LeftIterT _prior_left; + RightIterT _prior_right; + int _result; +}; + + + +template<class LeftT, class RightT> +int element_compare +( + const LeftT& left, //sub + const RightT& right, //super + typename LeftT::const_iterator left_begin, + typename LeftT::const_iterator left_end, + typename RightT::const_iterator right_begin, + typename RightT::const_iterator right_end +) +{ + typedef element_comparer<LeftT,RightT> Step; + Step step(left, right, left_end, right_end); + + typename LeftT::const_iterator left_ = left_begin; + typename RightT::const_iterator right_ = right_begin; + + int state = Step::nextboth; + while(state != Step::stop) + { + switch(state){ + case Step::nextboth: state = step.next_both (left_, right_); break; + case Step::nextleft: state = step.next_left (left_, right_); break; + case Step::nextright: state = step.next_right(left_, right_); break; + } + } + return step.result(); +} + + +} // namespace Interval_Set + +}} // namespace icl boost + +#endif +