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