| /*-----------------------------------------------------------------------------+ |
| Copyright (c) 2010-2010: 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_CONCEPT_INTERVAL_HPP_JOFA_100323 |
| #define BOOST_ICL_CONCEPT_INTERVAL_HPP_JOFA_100323 |
| |
| #include <boost/assert.hpp> |
| #include <boost/utility/enable_if.hpp> |
| #include <boost/mpl/and.hpp> |
| #include <boost/mpl/or.hpp> |
| #include <boost/mpl/not.hpp> |
| #include <boost/icl/detail/design_config.hpp> |
| #include <boost/icl/type_traits/unit_element.hpp> |
| #include <boost/icl/type_traits/identity_element.hpp> |
| #include <boost/icl/type_traits/infinity.hpp> |
| #include <boost/icl/type_traits/succ_pred.hpp> |
| #include <boost/icl/type_traits/is_numeric.hpp> |
| #include <boost/icl/type_traits/is_discrete.hpp> |
| #include <boost/icl/type_traits/is_continuous.hpp> |
| #include <boost/icl/type_traits/is_asymmetric_interval.hpp> |
| #include <boost/icl/type_traits/is_discrete_interval.hpp> |
| #include <boost/icl/type_traits/is_continuous_interval.hpp> |
| |
| #include <boost/icl/concept/interval_bounds.hpp> |
| #include <boost/icl/interval_traits.hpp> |
| #include <boost/icl/dynamic_interval_traits.hpp> |
| |
| |
| namespace boost{namespace icl |
| { |
| |
| //============================================================================== |
| //= Ordering |
| //============================================================================== |
| template<class Type> |
| inline typename enable_if<is_interval<Type>, bool>::type |
| domain_less(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| return typename interval_traits<Type>::domain_compare()(left, right); |
| } |
| |
| template<class Type> |
| inline typename enable_if<is_interval<Type>, bool>::type |
| domain_less_equal(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| return !(typename interval_traits<Type>::domain_compare()(right, left)); |
| } |
| |
| template<class Type> |
| inline typename enable_if<is_interval<Type>, bool>::type |
| domain_equal(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| return !(domain_compare()(left, right)) && !(domain_compare()(right, left)); |
| } |
| |
| template<class Type> |
| inline typename enable_if< is_interval<Type> |
| , typename interval_traits<Type>::domain_type>::type |
| domain_next(const typename interval_traits<Type>::domain_type value) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| return icl::successor<domain_type,domain_compare>::apply(value); |
| } |
| |
| template<class Type> |
| inline typename enable_if< is_interval<Type> |
| , typename interval_traits<Type>::domain_type>::type |
| domain_prior(const typename interval_traits<Type>::domain_type value) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| return icl::predecessor<domain_type,domain_compare>::apply(value); |
| } |
| |
| //============================================================================== |
| //= Construct<Interval> singleton |
| //============================================================================== |
| template<class Type> |
| typename enable_if |
| < |
| mpl::and_< is_static_right_open<Type> |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , Type |
| >::type |
| singleton(const typename interval_traits<Type>::domain_type& value) |
| { |
| //ASSERT: This always creates an interval with exactly one element |
| return interval_traits<Type>::construct(value, domain_next<Type>(value)); |
| } |
| |
| template<class Type> |
| typename enable_if |
| < |
| mpl::and_< is_static_left_open<Type> |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , Type |
| >::type |
| singleton(const typename interval_traits<Type>::domain_type& value) |
| { |
| //ASSERT: This always creates an interval with exactly one element |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(value) )); |
| |
| return interval_traits<Type>::construct(domain_prior<Type>(value), value); |
| } |
| |
| template<class Type> |
| typename enable_if<is_discrete_static_open<Type>, Type>::type |
| singleton(const typename interval_traits<Type>::domain_type& value) |
| { |
| //ASSERT: This always creates an interval with exactly one element |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(value))); |
| |
| return interval_traits<Type>::construct( domain_prior<Type>(value) |
| , domain_next<Type>(value)); |
| } |
| |
| template<class Type> |
| typename enable_if<is_discrete_static_closed<Type>, Type>::type |
| singleton(const typename interval_traits<Type>::domain_type& value) |
| { |
| //ASSERT: This always creates an interval with exactly one element |
| return interval_traits<Type>::construct(value, value); |
| } |
| |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, Type>::type |
| singleton(const typename interval_traits<Type>::domain_type& value) |
| { |
| return dynamic_interval_traits<Type>::construct(value, value, interval_bounds::closed()); |
| } |
| |
| namespace detail |
| { |
| |
| //============================================================================== |
| //= Construct<Interval> unit_trail == generalized singleton |
| // The smallest interval on an incrementable (and decrementable) type that can |
| // be constructed using ++ and -- and such that it contains a given value. |
| // If 'Type' is discrete, 'unit_trail' and 'singleton' are identical. So we |
| // can view 'unit_trail' as a generalized singleton for static intervals of |
| // continuous types. |
| //============================================================================== |
| template<class Type> |
| typename enable_if |
| < |
| mpl::and_< is_static_right_open<Type> |
| , boost::detail::is_incrementable<typename interval_traits<Type>::domain_type> > |
| , Type |
| >::type |
| unit_trail(const typename interval_traits<Type>::domain_type& value) |
| { |
| return interval_traits<Type>::construct(value, domain_next<Type>(value)); |
| } |
| |
| template<class Type> |
| typename enable_if |
| < |
| mpl::and_< is_static_left_open<Type> |
| , boost::detail::is_incrementable<typename interval_traits<Type>::domain_type> > |
| , Type |
| >::type |
| unit_trail(const typename interval_traits<Type>::domain_type& value) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(value) )); |
| |
| return interval_traits<Type>::construct(domain_prior<Type>(value), value); |
| } |
| |
| template<class Type> |
| typename enable_if |
| < |
| mpl::and_< is_static_open<Type> |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , Type |
| >::type |
| unit_trail(const typename interval_traits<Type>::domain_type& value) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(value))); |
| |
| return interval_traits<Type>::construct( domain_prior<Type>(value) |
| , domain_next<Type>(value)); |
| } |
| |
| template<class Type> |
| typename enable_if |
| < |
| mpl::and_< is_static_closed<Type> |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , Type |
| >::type |
| unit_trail(const typename interval_traits<Type>::domain_type& value) |
| { |
| return interval_traits<Type>::construct(value, value); |
| } |
| |
| //NOTE: statically bounded closed or open intervals of continuous domain types |
| // are NOT supported by ICL. They can not be used with interval containers |
| // consistently. |
| |
| |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, Type>::type |
| unit_trail(const typename interval_traits<Type>::domain_type& value) |
| { |
| return dynamic_interval_traits<Type>::construct(value, value, interval_bounds::closed()); |
| } |
| |
| } //namespace detail |
| |
| //============================================================================== |
| //= Construct<Interval> multon |
| //============================================================================== |
| template<class Type> |
| typename enable_if<has_static_bounds<Type>, Type>::type |
| construct(const typename interval_traits<Type>::domain_type& low, |
| const typename interval_traits<Type>::domain_type& up ) |
| { |
| return interval_traits<Type>::construct(low, up); |
| } |
| |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, Type>::type |
| construct(const typename interval_traits<Type>::domain_type& low, |
| const typename interval_traits<Type>::domain_type& up, |
| interval_bounds bounds = interval_bounds::right_open()) |
| { |
| return dynamic_interval_traits<Type>::construct(low, up, bounds); |
| } |
| |
| |
| //- construct form bounded values ---------------------------------------------- |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, Type>::type |
| construct(const typename Type::bounded_domain_type& low, |
| const typename Type::bounded_domain_type& up) |
| { |
| return dynamic_interval_traits<Type>::construct_bounded(low, up); |
| } |
| |
| template<class Type> |
| typename enable_if<is_interval<Type>, Type>::type |
| span(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| if(interval_traits<Type>::domain_compare()(left,right)) |
| return construct<Type>(left, right); |
| else |
| return construct<Type>(right, left); |
| } |
| |
| |
| //============================================================================== |
| template<class Type> |
| typename enable_if<is_static_right_open<Type>, Type>::type |
| hull(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| if(interval_traits<Type>::domain_compare()(left,right)) |
| return construct<Type>(left, domain_next<Type>(right)); |
| else |
| return construct<Type>(right, domain_next<Type>(left)); |
| } |
| |
| template<class Type> |
| typename enable_if<is_static_left_open<Type>, Type>::type |
| hull(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| if(interval_traits<Type>::domain_compare()(left,right)) |
| { |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(left) )); |
| return construct<Type>(domain_prior<Type>(left), right); |
| } |
| else |
| { |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(right) )); |
| return construct<Type>(domain_prior<Type>(right), left); |
| } |
| } |
| |
| template<class Type> |
| typename enable_if<is_static_closed<Type>, Type>::type |
| hull(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| if(interval_traits<Type>::domain_compare()(left,right)) |
| return construct<Type>(left, right); |
| else |
| return construct<Type>(right, left); |
| } |
| |
| template<class Type> |
| typename enable_if<is_static_open<Type>, Type>::type |
| hull(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| if(interval_traits<Type>::domain_compare()(left,right)) |
| { |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(left) )); |
| return construct<Type>( domain_prior<Type>(left) |
| , domain_next<Type>(right)); |
| } |
| else |
| { |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(right) )); |
| return construct<Type>( domain_prior<Type>(right) |
| , domain_next<Type>(left)); |
| } |
| } |
| |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, Type>::type |
| hull(const typename interval_traits<Type>::domain_type& left, |
| const typename interval_traits<Type>::domain_type& right) |
| { |
| if(interval_traits<Type>::domain_compare()(left,right)) |
| return construct<Type>(left, right, interval_bounds::closed()); |
| else |
| return construct<Type>(right, left, interval_bounds::closed()); |
| } |
| |
| //============================================================================== |
| //= Selection |
| //============================================================================== |
| |
| template<class Type> |
| inline typename enable_if<is_interval<Type>, |
| typename interval_traits<Type>::domain_type>::type |
| lower(const Type& object) |
| { |
| return interval_traits<Type>::lower(object); |
| } |
| |
| template<class Type> |
| inline typename enable_if<is_interval<Type>, |
| typename interval_traits<Type>::domain_type>::type |
| upper(const Type& object) |
| { |
| return interval_traits<Type>::upper(object); |
| } |
| |
| |
| //- first ---------------------------------------------------------------------- |
| template<class Type> |
| inline typename |
| enable_if< mpl::or_<is_static_right_open<Type>, is_static_closed<Type> > |
| , typename interval_traits<Type>::domain_type>::type |
| first(const Type& object) |
| { |
| return lower(object); |
| } |
| |
| template<class Type> |
| inline typename |
| enable_if< mpl::and_< mpl::or_<is_static_left_open<Type>, is_static_open<Type> > |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , typename interval_traits<Type>::domain_type>::type |
| first(const Type& object) |
| { |
| return domain_next<Type>(lower(object)); |
| } |
| |
| template<class Type> |
| inline typename enable_if<is_discrete_interval<Type>, |
| typename interval_traits<Type>::domain_type>::type |
| first(const Type& object) |
| { |
| return is_left_closed(object.bounds()) ? |
| lower(object) : |
| domain_next<Type>(lower(object)); |
| } |
| |
| //- last ----------------------------------------------------------------------- |
| template<class Type> |
| inline typename |
| enable_if< mpl::or_<is_static_left_open<Type>, is_static_closed<Type> > |
| , typename interval_traits<Type>::domain_type>::type |
| last(const Type& object) |
| { |
| return upper(object); |
| } |
| |
| template<class Type> |
| inline typename |
| enable_if< mpl::and_< mpl::or_<is_static_right_open<Type>, is_static_open<Type> > |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , typename interval_traits<Type>::domain_type>::type |
| last(const Type& object) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than(upper(object)) )); |
| return domain_prior<Type>(upper(object)); |
| } |
| |
| template<class Type> |
| inline typename enable_if<is_discrete_interval<Type>, |
| typename interval_traits<Type>::domain_type>::type |
| last(const Type& object) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| BOOST_ASSERT((numeric_minimum<domain_type, domain_compare, is_numeric<domain_type>::value> |
| ::is_less_than_or(upper(object), is_right_closed(object.bounds())) )); |
| return is_right_closed(object.bounds()) ? |
| upper(object) : |
| domain_prior<Type>(upper(object)); |
| } |
| |
| //- last_next ------------------------------------------------------------------ |
| template<class Type> |
| inline typename |
| enable_if< mpl::and_< mpl::or_<is_static_left_open<Type>, is_static_closed<Type> > |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , typename interval_traits<Type>::domain_type>::type |
| last_next(const Type& object) |
| { |
| return domain_next<Type>(upper(object)); |
| } |
| |
| template<class Type> |
| inline typename |
| enable_if< mpl::and_< mpl::or_<is_static_right_open<Type>, is_static_open<Type> > |
| , is_discrete<typename interval_traits<Type>::domain_type> > |
| , typename interval_traits<Type>::domain_type>::type |
| last_next(const Type& object) |
| { |
| typedef typename interval_traits<Type>::domain_type domain_type; |
| return upper(object); // NOTE: last_next is implemented to avoid calling pred(object) |
| } // For unsigned integral types this may cause underflow. |
| |
| template<class Type> |
| inline typename enable_if<is_discrete_interval<Type>, |
| typename interval_traits<Type>::domain_type>::type |
| last_next(const Type& object) |
| { |
| return is_right_closed(object.bounds()) ? |
| domain_next<Type>(upper(object)): |
| upper(object) ; |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type>::type |
| bounded_lower(const Type& object) |
| { |
| return typename |
| Type::bounded_domain_type(lower(object), object.bounds().left()); |
| } |
| |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type>::type |
| reverse_bounded_lower(const Type& object) |
| { |
| return typename |
| Type::bounded_domain_type(lower(object), |
| object.bounds().reverse_left()); |
| } |
| |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type>::type |
| bounded_upper(const Type& object) |
| { |
| return typename |
| Type::bounded_domain_type(upper(object), |
| object.bounds().right()); |
| } |
| |
| template<class Type> |
| typename enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type>::type |
| reverse_bounded_upper(const Type& object) |
| { |
| return typename |
| Type::bounded_domain_type(upper(object), |
| object.bounds().reverse_right()); |
| } |
| |
| //- bounds --------------------------------------------------------------------- |
| template<class Type> |
| inline typename enable_if<has_dynamic_bounds<Type>, interval_bounds>::type |
| bounds(const Type& object) |
| { |
| return object.bounds(); |
| } |
| |
| template<class Type> |
| inline typename enable_if<has_static_bounds<Type>, interval_bounds>::type |
| bounds(const Type&) |
| { |
| return interval_bounds(interval_bound_type<Type>::value); |
| } |
| |
| |
| //============================================================================== |
| //= Emptieness |
| //============================================================================== |
| /** Is the interval empty? */ |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type |
| is_empty(const Type& object) |
| { |
| return domain_less_equal<Type>(upper(object), lower(object)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_static_closed<Type>, bool>::type |
| is_empty(const Type& object) |
| { |
| return domain_less<Type>(upper(object), lower(object)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_static_open<Type>, bool>::type |
| is_empty(const Type& object) |
| { |
| return domain_less_equal<Type>(upper(object), domain_next<Type>(lower(object))); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| is_empty(const Type& object) |
| { |
| if(object.bounds() == interval_bounds::closed()) |
| return domain_less<Type>(upper(object), lower(object)); |
| else if(object.bounds() == interval_bounds::open()) |
| return domain_less_equal<Type>(upper(object), domain_next<Type>(lower(object))); |
| else |
| return domain_less_equal<Type>(upper(object), lower(object)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| is_empty(const Type& object) |
| { |
| return domain_less<Type>(upper(object), lower(object)) |
| || ( domain_equal<Type>(upper(object), lower(object)) |
| && object.bounds() != interval_bounds::closed() ); |
| } |
| |
| //============================================================================== |
| //= Orderings, containedness (non empty) |
| //============================================================================== |
| namespace non_empty |
| { |
| |
| template<class Type> |
| inline typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right))); |
| return domain_less_equal<Type>(upper(left), lower(right)); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right))); |
| return domain_less<Type>(last(left), first(right)); |
| } |
| |
| template<class Type> |
| inline typename boost:: |
| enable_if<has_symmetric_bounds<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right))); |
| return domain_less<Type>(last(left), first(right)); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| BOOST_ASSERT(!(icl::is_empty(left) || icl::is_empty(right))); |
| return domain_less <Type>(left.upper(), right.lower()) |
| || ( domain_equal<Type>(left.upper(), right.lower()) |
| && inner_bounds(left,right) != interval_bounds::open() ); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_interval<Type>, bool>::type |
| contains(const Type& super, const Type& sub) |
| { |
| return lower_less_equal(super,sub) && upper_less_equal(sub,super); |
| } |
| |
| |
| } //namespace non_empty |
| |
| |
| //- contains ------------------------------------------------------------------- |
| template<class Type> |
| inline typename boost::enable_if<is_interval<Type>, bool>::type |
| contains(const Type& super, const Type& sub) |
| { |
| return icl::is_empty(sub) || non_empty::contains(super, sub); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_static<Type>, bool>::type |
| contains(const Type& super, const typename interval_traits<Type>::domain_type& element) |
| { |
| return domain_less_equal<Type>(icl::first(super), element ) |
| && domain_less_equal<Type>( element, icl::last(super)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_left_open<Type>, bool>::type |
| contains(const Type& super, const typename interval_traits<Type>::domain_type& element) |
| { |
| return domain_less <Type>(icl::lower(super), element ) |
| && domain_less_equal<Type>( element, icl::upper(super)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_right_open<Type>, bool>::type |
| contains(const Type& super, const typename interval_traits<Type>::domain_type& element) |
| { |
| return domain_less_equal<Type>(icl::lower(super), element ) |
| && domain_less <Type>( element, icl::upper(super)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, bool>::type |
| contains(const Type& super, const typename interval_traits<Type>::domain_type& element) |
| { |
| return |
| (is_left_closed(super.bounds()) |
| ? domain_less_equal<Type>(super.lower(), element) |
| : domain_less<Type>(super.lower(), element)) |
| && |
| (is_right_closed(super.bounds()) |
| ? domain_less_equal<Type>(element, super.upper()) |
| : domain_less<Type>(element, super.upper())); |
| } |
| |
| //- within --------------------------------------------------------------------- |
| template<class Type> |
| inline typename boost::enable_if<is_interval<Type>, bool>::type |
| within(const Type& sub, const Type& super) |
| { |
| return contains(super,sub); |
| } |
| |
| |
| //============================================================================== |
| //= Equivalences and Orderings |
| //============================================================================== |
| //- exclusive_less ------------------------------------------------------------- |
| /** Maximal element of <tt>left</tt> is less than the minimal element of |
| <tt>right</tt> */ |
| template<class Type> |
| inline typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| return icl::is_empty(left) || icl::is_empty(right) |
| || domain_less_equal<Type>(upper(left), lower(right)); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| return icl::is_empty(left) || icl::is_empty(right) |
| || domain_less<Type>(last(left), first(right)); |
| } |
| |
| template<class Type> |
| inline typename boost:: |
| enable_if<has_symmetric_bounds<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| return icl::is_empty(left) || icl::is_empty(right) |
| || domain_less<Type>(last(left), first(right)); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| exclusive_less(const Type& left, const Type& right) |
| { |
| return icl::is_empty(left) || icl::is_empty(right) |
| || domain_less<Type>(left.upper(), right.lower()) |
| || ( domain_equal<Type>(left.upper(), right.lower()) |
| && inner_bounds(left,right) != interval_bounds::open() ); |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<has_static_bounds<Type>, bool>::type |
| lower_less(const Type& left, const Type& right) |
| { |
| return domain_less<Type>(left.lower(), right.lower()); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| lower_less(const Type& left, const Type& right) |
| { |
| return domain_less<Type>(first(left), first(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| lower_less(const Type& left, const Type& right) |
| { |
| if(left_bounds(left,right) == interval_bounds::right_open()) //'[(' == 10 |
| return domain_less_equal<Type>(left.lower(), right.lower()); |
| else |
| return domain_less<Type>(left.lower(), right.lower()); |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<has_static_bounds<Type>, bool>::type |
| upper_less(const Type& left, const Type& right) |
| { |
| return domain_less<Type>(left.upper(), right.upper()); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| upper_less(const Type& left, const Type& right) |
| { |
| return domain_less<Type>(last(left), last(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| upper_less(const Type& left, const Type& right) |
| { |
| if(right_bounds(left,right) == interval_bounds::left_open()) |
| return domain_less_equal<Type>(left.upper(), right.upper()); |
| else |
| return domain_less<Type>(left.upper(), right.upper()); |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type >::type |
| lower_min(const Type& left, const Type& right) |
| { |
| return lower_less(left, right) ? bounded_lower(left) : bounded_lower(right); |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type >::type |
| lower_max(const Type& left, const Type& right) |
| { |
| return lower_less(left, right) ? bounded_lower(right) : bounded_lower(left); |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type >::type |
| upper_max(const Type& left, const Type& right) |
| { |
| return upper_less(left, right) ? bounded_upper(right) : bounded_upper(left); |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, |
| typename Type::bounded_domain_type >::type |
| upper_min(const Type& left, const Type& right) |
| { |
| return upper_less(left, right) ? bounded_upper(left) : bounded_upper(right); |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type |
| lower_equal(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(left.lower(), right.lower()); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type |
| lower_equal(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(first(left), first(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| lower_equal(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(first(left), first(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| lower_equal(const Type& left, const Type& right) |
| { |
| return (left.bounds().left()==right.bounds().left()) |
| && domain_equal<Type>(left.lower(), right.lower()); |
| } |
| |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type |
| upper_equal(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(left.upper(), right.upper()); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type |
| upper_equal(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(last(left), last(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| upper_equal(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(last(left), last(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| upper_equal(const Type& left, const Type& right) |
| { |
| return (left.bounds().right()==right.bounds().right()) |
| && domain_equal<Type>(left.upper(), right.upper()); |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<is_interval<Type>, bool>::type |
| lower_less_equal(const Type& left, const Type& right) |
| { |
| return lower_less(left,right) || lower_equal(left,right); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_interval<Type>, bool>::type |
| upper_less_equal(const Type& left, const Type& right) |
| { |
| return upper_less(left,right) || upper_equal(left,right); |
| } |
| |
| |
| //- operator == ---------------------------------------------------------------- |
| template<class Type> |
| typename boost::enable_if<is_interval<Type>, bool>::type |
| operator == (const Type& left, const Type& right) |
| { |
| return (icl::is_empty(left) && icl::is_empty(right)) |
| || (lower_equal(left,right) && upper_equal(left,right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_interval<Type>, bool>::type |
| operator != (const Type& left, const Type& right) |
| { |
| return !(left == right); |
| } |
| |
| //- operator < ----------------------------------------------------------------- |
| template<class Type> |
| typename boost::enable_if<is_interval<Type>, bool>::type |
| operator < (const Type& left, const Type& right) |
| { |
| if(icl::is_empty(left)) |
| return !icl::is_empty(right); |
| else |
| return lower_less(left,right) |
| || (lower_equal(left,right) && upper_less(left,right)); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_interval<Type>, bool>::type |
| operator > (const Type& left, const Type& right) |
| { |
| return right < left; |
| } |
| |
| |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, bool>::type |
| touches(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(upper(left), lower(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_symmetric_bounds<Type>, bool>::type |
| touches(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(last_next(left), first(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_interval<Type>, bool>::type |
| touches(const Type& left, const Type& right) |
| { |
| return domain_equal<Type>(domain_next<Type>(last(left)), first(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_interval<Type>, bool>::type |
| touches(const Type& left, const Type& right) |
| { |
| return is_complementary(inner_bounds(left,right)) |
| && domain_equal<Type>(left.upper(), right.lower()); |
| } |
| |
| |
| //============================================================================== |
| //= Size |
| //============================================================================== |
| //- cardinality ---------------------------------------------------------------- |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_interval<Type>, |
| typename size_type_of<interval_traits<Type> >::type>::type |
| cardinality(const Type& object) |
| { |
| typedef typename size_type_of<interval_traits<Type> >::type SizeT; |
| if(icl::is_empty(object)) |
| return icl::identity_element<SizeT>::value(); |
| else if( object.bounds() == interval_bounds::closed() |
| && domain_equal<Type>(lower(object), upper(object))) |
| return icl::unit_element<SizeT>::value(); |
| else |
| return icl::infinity<SizeT>::value(); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_interval<Type>, |
| typename size_type_of<interval_traits<Type> >::type>::type |
| cardinality(const Type& object) |
| { |
| typedef typename size_type_of<interval_traits<Type> >::type SizeT; |
| return icl::is_empty(object) ? identity_element<SizeT>::value() |
| : static_cast<SizeT>(last_next(object) - first(object)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_asymmetric<Type>, |
| typename size_type_of<interval_traits<Type> >::type>::type |
| cardinality(const Type& object) |
| { |
| typedef typename size_type_of<interval_traits<Type> >::type SizeT; |
| if(icl::is_empty(object)) |
| return icl::identity_element<SizeT>::value(); |
| else |
| return icl::infinity<SizeT>::value(); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_asymmetric<Type>, |
| typename size_type_of<interval_traits<Type> >::type>::type |
| cardinality(const Type& object) |
| { |
| typedef typename size_type_of<interval_traits<Type> >::type SizeT; |
| return icl::is_empty(object) ? identity_element<SizeT>::value() |
| : static_cast<SizeT>(last_next(object) - first(object)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_symmetric_bounds<Type>, |
| typename size_type_of<interval_traits<Type> >::type>::type |
| cardinality(const Type& object) |
| { |
| typedef typename size_type_of<interval_traits<Type> >::type SizeT; |
| return icl::is_empty(object) ? identity_element<SizeT>::value() |
| : static_cast<SizeT>(last_next(object) - first(object)); |
| } |
| |
| |
| |
| //- size ----------------------------------------------------------------------- |
| template<class Type> |
| inline typename enable_if<is_interval<Type>, |
| typename size_type_of<interval_traits<Type> >::type>::type |
| size(const Type& object) |
| { |
| return cardinality(object); |
| } |
| |
| //- length --------------------------------------------------------------------- |
| template<class Type> |
| inline typename boost::enable_if<is_continuous_interval<Type>, |
| typename difference_type_of<interval_traits<Type> >::type>::type |
| length(const Type& object) |
| { |
| typedef typename difference_type_of<interval_traits<Type> >::type DiffT; |
| return icl::is_empty(object) ? identity_element<DiffT>::value() |
| : upper(object) - lower(object); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_discrete_interval<Type>, |
| typename difference_type_of<interval_traits<Type> >::type>::type |
| length(const Type& object) |
| { |
| typedef typename difference_type_of<interval_traits<Type> >::type DiffT; |
| return icl::is_empty(object) ? identity_element<DiffT>::value() |
| : last_next(object) - first(object); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_continuous_asymmetric<Type>, |
| typename difference_type_of<interval_traits<Type> >::type>::type |
| length(const Type& object) |
| { |
| typedef typename difference_type_of<interval_traits<Type> >::type DiffT; |
| return icl::is_empty(object) ? identity_element<DiffT>::value() |
| : upper(object) - lower(object); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_discrete_static<Type>, |
| typename difference_type_of<interval_traits<Type> >::type>::type |
| length(const Type& object) |
| { |
| typedef typename difference_type_of<interval_traits<Type> >::type DiffT; |
| return icl::is_empty(object) ? identity_element<DiffT>::value() |
| : last_next(object) - first(object); |
| } |
| |
| //- iterative_size ------------------------------------------------------------- |
| template<class Type> |
| inline typename enable_if<is_interval<Type>, |
| typename size_type_of<interval_traits<Type> >::type>::type |
| iterative_size(const Type&) |
| { |
| return 2; |
| } |
| |
| |
| //============================================================================== |
| //= Addition |
| //============================================================================== |
| //- hull ----------------------------------------------------------------------- |
| /** \c hull returns the smallest interval containing \c left and \c right. */ |
| template<class Type> |
| typename boost::enable_if<has_static_bounds<Type>, Type>::type |
| hull(Type left, const Type& right) |
| { |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| |
| if(icl::is_empty(right)) |
| return left; |
| else if(icl::is_empty(left)) |
| return right; |
| |
| return |
| construct<Type> |
| ( |
| (std::min)(lower(left), lower(right), domain_compare()), |
| (std::max)(upper(left), upper(right), domain_compare()) |
| ); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type |
| hull(Type left, const Type& right) |
| { |
| if(icl::is_empty(right)) |
| return left; |
| else if(icl::is_empty(left)) |
| return right; |
| |
| return dynamic_interval_traits<Type>::construct_bounded |
| ( |
| lower_min(left, right), |
| upper_max(left, right) |
| ); |
| } |
| |
| //============================================================================== |
| //= Subtraction |
| //============================================================================== |
| //- left_subtract -------------------------------------------------------------- |
| /** subtract \c left_minuend from the \c right interval on it's left side. |
| Return the difference: The part of \c right right of \c left_minuend. |
| \code |
| right_over = right - left_minuend; //on the left. |
| ... d) : right |
| ... c) : left_minuend |
| [c d) : right_over |
| \endcode |
| */ |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type |
| left_subtract(Type right, const Type& left_minuend) |
| { |
| if(exclusive_less(left_minuend, right)) |
| return right; |
| |
| return construct<Type>(upper(left_minuend), upper(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_static_closed<Type>, Type>::type |
| left_subtract(Type right, const Type& left_minuend) |
| { |
| if(exclusive_less(left_minuend, right)) |
| return right; |
| |
| return construct<Type>(domain_next<Type>(upper(left_minuend)), upper(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_static_open<Type>, Type>::type |
| left_subtract(Type right, const Type& left_minuend) |
| { |
| if(exclusive_less(left_minuend, right)) |
| return right; |
| |
| return construct<Type>(domain_prior<Type>(upper(left_minuend)), upper(right)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type |
| left_subtract(Type right, const Type& left_minuend) |
| { |
| if(exclusive_less(left_minuend, right)) |
| return right; |
| return dynamic_interval_traits<Type>::construct_bounded |
| ( reverse_bounded_upper(left_minuend), bounded_upper(right) ); |
| } |
| |
| |
| //- right_subtract ------------------------------------------------------------- |
| /** subtract \c right_minuend from the \c left interval on it's right side. |
| Return the difference: The part of \c left right of \c right_minuend. |
| \code |
| left_over = left - right_minuend; //on the right side. |
| [a ... : left |
| [b ... : right_minuend |
| [a b) : left_over |
| \endcode |
| */ |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type |
| right_subtract(Type left, const Type& right_minuend) |
| { |
| if(exclusive_less(left, right_minuend)) |
| return left; |
| return construct<Type>(lower(left), lower(right_minuend)); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_static_closed<Type>, Type>::type |
| right_subtract(Type left, const Type& right_minuend) |
| { |
| if(exclusive_less(left, right_minuend)) |
| return left; |
| else if(lower_less_equal(right_minuend, left)) |
| return identity_element<Type>::value(); |
| |
| return construct<Type>(lower(left), domain_prior<Type>(lower(right_minuend))); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_static_open<Type>, Type>::type |
| right_subtract(Type left, const Type& right_minuend) |
| { |
| if(exclusive_less(left, right_minuend)) |
| return left; |
| |
| return construct<Type>(lower(left), domain_next<Type>(lower(right_minuend))); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type |
| right_subtract(Type left, const Type& right_minuend) |
| { |
| if(exclusive_less(left, right_minuend)) |
| return left; |
| |
| return dynamic_interval_traits<Type>::construct_bounded |
| ( bounded_lower(left), reverse_bounded_lower(right_minuend) ); |
| } |
| |
| //============================================================================== |
| //= Intersection |
| //============================================================================== |
| //- operator & ----------------------------------------------------------------- |
| /** Returns the intersection of \c left and \c right interval. */ |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type |
| operator & (Type left, const Type& right) |
| { |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| |
| if(icl::is_empty(left) || icl::is_empty(right)) |
| return identity_element<Type>::value(); |
| else |
| return |
| construct<Type> |
| ( |
| (std::max)(icl::lower(left), icl::lower(right), domain_compare()), |
| (std::min)(icl::upper(left), icl::upper(right), domain_compare()) |
| ); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_symmetric_bounds<Type>, Type>::type |
| operator & (Type left, const Type& right) |
| { |
| typedef typename interval_traits<Type>::domain_compare domain_compare; |
| |
| if(icl::is_empty(left) || icl::is_empty(right)) |
| return identity_element<Type>::value(); |
| else |
| return |
| construct<Type> |
| ( |
| (std::max)(icl::lower(left), icl::lower(right), domain_compare()), |
| (std::min)(icl::upper(left), icl::upper(right), domain_compare()) |
| ); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type |
| operator & (Type left, const Type& right) |
| { |
| if(icl::is_empty(left) || icl::is_empty(right)) |
| return identity_element<Type>::value(); |
| else |
| return dynamic_interval_traits<Type>::construct_bounded |
| ( |
| lower_max(left, right), |
| upper_min(left, right) |
| ); |
| } |
| |
| |
| //- intersects ----------------------------------------------------------------- |
| template<class Type> |
| typename boost::enable_if<is_interval<Type>, bool>::type |
| intersects(const Type& left, const Type& right) |
| { |
| return !( icl::is_empty(left) || icl::is_empty(right) |
| || exclusive_less(left,right) || exclusive_less(right,left)); |
| } |
| |
| //- disjoint ------------------------------------------------------------------- |
| template<class Type> |
| typename boost::enable_if<is_interval<Type>, bool>::type |
| disjoint(const Type& left, const Type& right) |
| { |
| return icl::is_empty(left) || icl::is_empty(right) |
| || exclusive_less(left,right) || exclusive_less(right,left); |
| } |
| |
| //============================================================================== |
| //= Complement |
| //============================================================================== |
| |
| template<class Type> |
| typename boost::enable_if<is_asymmetric_interval<Type>, Type>::type |
| inner_complement(const Type& left, const Type& right) |
| { |
| if(icl::is_empty(left) || icl::is_empty(right)) |
| return identity_element<Type>::value(); |
| else if(exclusive_less(left, right)) |
| return construct<Type>(upper(left), lower(right)); |
| else if(exclusive_less(right, left)) |
| return construct<Type>(upper(right), lower(left)); |
| else |
| return identity_element<Type>::value(); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_static_closed<Type>, Type>::type |
| inner_complement(const Type& left, const Type& right) |
| { |
| if(icl::is_empty(left) || icl::is_empty(right)) |
| return identity_element<Type>::value(); |
| else if(exclusive_less(left, right)) |
| return construct<Type>(domain_next<Type>(upper(left)), domain_prior<Type>(lower(right))); |
| else if(exclusive_less(right, left)) |
| return construct<Type>(domain_next<Type>(upper(right)), domain_prior<Type>(lower(left))); |
| else |
| return identity_element<Type>::value(); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<is_discrete_static_open<Type>, Type>::type |
| inner_complement(const Type& left, const Type& right) |
| { |
| if(icl::is_empty(left) || icl::is_empty(right)) |
| return identity_element<Type>::value(); |
| else if(exclusive_less(left, right)) |
| return construct<Type>(last(left), first(right)); |
| else if(exclusive_less(right, left)) |
| return construct<Type>(last(right), first(left)); |
| else |
| return identity_element<Type>::value(); |
| } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, Type>::type |
| inner_complement(const Type& left, const Type& right) |
| { |
| if(icl::is_empty(left) || icl::is_empty(right)) |
| return identity_element<Type>::value(); |
| else if(exclusive_less(left, right)) |
| return right_subtract(left_subtract(hull(left, right), left), right); |
| else if(exclusive_less(right, left)) |
| return right_subtract(left_subtract(hull(right, left), right), left); |
| else |
| return identity_element<Type>::value(); |
| } |
| |
| template<class Type> |
| inline typename boost::enable_if<is_interval<Type>, Type>::type |
| between(const Type& left, const Type& right) |
| { |
| return inner_complement(left, right); |
| } |
| |
| |
| |
| //============================================================================== |
| //= Distance |
| //============================================================================== |
| template<class Type> |
| typename boost:: |
| enable_if< mpl::and_< is_interval<Type> |
| , has_difference<typename interval_traits<Type>::domain_type> |
| , is_discrete<typename interval_traits<Type>::domain_type> |
| > |
| , typename difference_type_of<interval_traits<Type> >::type>::type |
| distance(const Type& x1, const Type& x2) |
| { |
| typedef typename difference_type_of<interval_traits<Type> >::type difference_type; |
| |
| if(icl::is_empty(x1) || icl::is_empty(x2)) |
| return icl::identity_element<difference_type>::value(); |
| else if(domain_less<Type>(last(x1), first(x2))) |
| return static_cast<difference_type>(icl::pred(first(x2) - last(x1))); |
| else if(domain_less<Type>(last(x2), first(x1))) |
| return static_cast<difference_type>(icl::pred(first(x1) - last(x2))); |
| else |
| return icl::identity_element<difference_type>::value(); |
| } |
| |
| template<class Type> |
| typename boost:: |
| enable_if< mpl::and_< is_interval<Type> |
| , has_difference<typename interval_traits<Type>::domain_type> |
| , is_continuous<typename interval_traits<Type>::domain_type> |
| > |
| , typename difference_type_of<interval_traits<Type> >::type>::type |
| distance(const Type& x1, const Type& x2) |
| { |
| typedef typename difference_type_of<interval_traits<Type> >::type DiffT; |
| |
| if(icl::is_empty(x1) || icl::is_empty(x2)) |
| return icl::identity_element<DiffT>::value(); |
| else if(domain_less<Type>(upper(x1), lower(x2))) |
| return x2.lower() - x1.upper(); |
| else if(domain_less<Type>(upper(x2), lower(x1))) |
| return lower(x1) - upper(x2); |
| else |
| return icl::identity_element<DiffT>::value(); |
| } |
| |
| //============================================================================== |
| //= Streaming, representation |
| //============================================================================== |
| template<class Type> |
| typename boost:: |
| enable_if< mpl::or_< is_static_left_open<Type> |
| , is_static_open<Type> >, std::string>::type |
| left_bracket(const Type&) { return "("; } |
| |
| template<class Type> |
| typename boost:: |
| enable_if< mpl::or_< is_static_right_open<Type> |
| , is_static_closed<Type> >, std::string>::type |
| left_bracket(const Type&) { return "["; } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::type |
| left_bracket(const Type& object) |
| { |
| return left_bracket(object.bounds()); |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class Type> |
| typename boost:: |
| enable_if< mpl::or_< is_static_right_open<Type> |
| , is_static_open<Type> >, std::string>::type |
| right_bracket(const Type&) { return ")"; } |
| |
| template<class Type> |
| typename boost:: |
| enable_if< mpl::or_< is_static_left_open<Type> |
| , is_static_closed<Type> >, std::string>::type |
| right_bracket(const Type&) { return "]"; } |
| |
| template<class Type> |
| typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::type |
| right_bracket(const Type& object) |
| { |
| return right_bracket(object.bounds()); |
| } |
| |
| //------------------------------------------------------------------------------ |
| template<class CharType, class CharTraits, class Type> |
| typename boost::enable_if<is_interval<Type>, |
| std::basic_ostream<CharType, CharTraits> >::type& |
| operator << (std::basic_ostream<CharType, CharTraits> &stream, Type const& object) |
| { |
| if(boost::icl::is_empty(object)) |
| return stream << left_bracket<Type>(object) << right_bracket<Type>(object); |
| else |
| return stream << left_bracket<Type>(object) |
| << interval_traits<Type>::lower(object) |
| << "," |
| << interval_traits<Type>::upper(object) |
| << right_bracket<Type>(object) ; |
| } |
| |
| }} // namespace icl boost |
| |
| #endif |
| |