| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477 | /*-----------------------------------------------------------------------------+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>#include <algorithm>namespace boost{namespace icl{//==============================================================================//= Ordering//==============================================================================template<class Type>inline typename enable_if<is_interval<Type>, bool>::typedomain_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>::typedomain_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>::typedomain_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>::typedomain_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>::typedomain_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>::typesingleton(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>::typesingleton(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>::typesingleton(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>::typesingleton(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>::typesingleton(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>::typeunit_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>::typeunit_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>::typeunit_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>::typeunit_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>::typeunit_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>::typeconstruct(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>::typeconstruct(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>::typeconstruct(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>::typespan(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;    if(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>::typehull(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;    if(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>::typehull(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(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>::typehull(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;    if(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>::typehull(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(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>::typehull(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;    if(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>::typelower(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>::typeupper(const Type& object){    return interval_traits<Type>::upper(object);}//- first ----------------------------------------------------------------------template<class Type>inline typenameenable_if< mpl::or_<is_static_right_open<Type>, is_static_closed<Type> >         , typename interval_traits<Type>::domain_type>::typefirst(const Type& object){    return lower(object);}template<class Type>inline typenameenable_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>::typefirst(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>::typefirst(const Type& object){    return is_left_closed(object.bounds()) ?                                 lower(object) :               domain_next<Type>(lower(object));}//- last -----------------------------------------------------------------------template<class Type>inline typenameenable_if< mpl::or_<is_static_left_open<Type>, is_static_closed<Type> >         , typename interval_traits<Type>::domain_type>::typelast(const Type& object){    return upper(object);}template<class Type>inline typenameenable_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>::typelast(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>::typelast(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 typenameenable_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>::typelast_next(const Type& object){    return domain_next<Type>(upper(object));}template<class Type>inline typenameenable_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>::typelast_next(const Type& object){    //CL 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>::typelast_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>::typebounded_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>::typereverse_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>::typebounded_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>::typereverse_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>::typebounds(const Type& object){    return object.bounds();}template<class Type>inline typename enable_if<has_static_bounds<Type>, interval_bounds>::typebounds(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>::typeis_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>::typeis_empty(const Type& object){    return domain_less<Type>(upper(object), lower(object));}template<class Type>typename boost::enable_if<is_static_open<Type>, bool>::typeis_empty(const Type& object){    return domain_less_equal<Type>(upper(object),                   lower(object) )        || domain_less_equal<Type>(upper(object), domain_next<Type>(lower(object)));}template<class Type>typename boost::enable_if<is_discrete_interval<Type>, bool>::typeis_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),                   lower(object) )            || 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>::typeis_empty(const Type& object){    return     domain_less<Type>(upper(object), lower(object))        || (   domain_equal<Type>(upper(object), lower(object))            && object.bounds() != interval_bounds::closed()    );}//==============================================================================//= 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>::typeexclusive_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>::typeexclusive_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>::typeexclusive_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>::typeexclusive_less(const Type& left, const Type& right){    return     icl::is_empty(left) || icl::is_empty(right)        ||     domain_less<Type>(upper(left), lower(right))        || (   domain_equal<Type>(upper(left), lower(right))            && inner_bounds(left,right) != interval_bounds::open() );}//------------------------------------------------------------------------------template<class Type>typename boost::enable_if<has_static_bounds<Type>, bool>::typelower_less(const Type& left, const Type& right){    return domain_less<Type>(lower(left), lower(right));}template<class Type>typename boost::enable_if<is_discrete_interval<Type>, bool>::typelower_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>::typelower_less(const Type& left, const Type& right){    if(left_bounds(left,right) == interval_bounds::right_open())  //'[(' == 10        return domain_less_equal<Type>(lower(left), lower(right));    else        return domain_less<Type>(lower(left), lower(right));}//------------------------------------------------------------------------------template<class Type>typename boost::enable_if<has_static_bounds<Type>, bool>::typeupper_less(const Type& left, const Type& right){    return domain_less<Type>(upper(left), upper(right));}template<class Type>typename boost::enable_if<is_discrete_interval<Type>, bool>::typeupper_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>::typeupper_less(const Type& left, const Type& right){    if(right_bounds(left,right) == interval_bounds::left_open())        return domain_less_equal<Type>(upper(left), upper(right));    else        return domain_less<Type>(upper(left), upper(right));}//------------------------------------------------------------------------------template<class Type>typename boost::enable_if<has_dynamic_bounds<Type>,                          typename Type::bounded_domain_type   >::typelower_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   >::typelower_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   >::typeupper_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   >::typeupper_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>::typelower_equal(const Type& left, const Type& right){    return domain_equal<Type>(lower(left), lower(right));}template<class Type>typename boost::enable_if<has_symmetric_bounds<Type>, bool>::typelower_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>::typelower_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>::typelower_equal(const Type& left, const Type& right){    return (left.bounds().left()==right.bounds().left())        && domain_equal<Type>(lower(left), lower(right));}//------------------------------------------------------------------------------template<class Type>typename boost::enable_if<is_asymmetric_interval<Type>, bool>::typeupper_equal(const Type& left, const Type& right){    return domain_equal<Type>(upper(left), upper(right));}template<class Type>typename boost::enable_if<has_symmetric_bounds<Type>, bool>::typeupper_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>::typeupper_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>::typeupper_equal(const Type& left, const Type& right){    return (left.bounds().right()==right.bounds().right())        && domain_equal<Type>(upper(left), upper(right));}//------------------------------------------------------------------------------template<class Type>typename boost::enable_if<is_interval<Type>, bool>::typelower_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>::typeupper_less_equal(const Type& left, const Type& right){    return upper_less(left,right) || upper_equal(left,right);}//==============================================================================//= 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>(upper(left), lower(right))            || (   domain_equal<Type>(upper(left), lower(right))                && 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>::typecontains(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>::typecontains(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>::typecontains(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>::typecontains(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>::typecontains(const Type& super, const typename interval_traits<Type>::domain_type& element){    return        (is_left_closed(super.bounds())            ? domain_less_equal<Type>(lower(super), element)            :       domain_less<Type>(lower(super), element))    &&        (is_right_closed(super.bounds())            ? domain_less_equal<Type>(element, upper(super))            :       domain_less<Type>(element, upper(super)));}//- within ---------------------------------------------------------------------template<class Type>inline typename boost::enable_if<is_interval<Type>, bool>::typewithin(const Type& sub, const Type& super){    return contains(super,sub);}//- operator == ----------------------------------------------------------------template<class Type>typename boost::enable_if<is_interval<Type>, bool>::typeoperator == (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>::typeoperator != (const Type& left, const Type& right){    return !(left == right);}//- operator < -----------------------------------------------------------------template<class Type>typename boost::enable_if<is_interval<Type>, bool>::typeoperator < (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>::typeoperator > (const Type& left, const Type& right){    return right < left;}//------------------------------------------------------------------------------template<class Type>typename boost::enable_if<is_asymmetric_interval<Type>, bool>::typetouches(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>::typetouches(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>::typetouches(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>::typetouches(const Type& left, const Type& right){    return is_complementary(inner_bounds(left,right))        && domain_equal<Type>(upper(left), lower(right));}//==============================================================================//= Size//==============================================================================//- cardinality ----------------------------------------------------------------template<class Type>typename boost::enable_if<is_continuous_interval<Type>,    typename size_type_of<interval_traits<Type> >::type>::typecardinality(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>::typecardinality(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>::typecardinality(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>::typecardinality(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>::typecardinality(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>::typesize(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>::typelength(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>::typelength(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>::typelength(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>::typelength(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>::typeiterative_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>::typehull(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>::typehull(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.\coderight_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>::typeleft_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>::typeleft_subtract(Type right, const Type& left_minuend){    if(exclusive_less(left_minuend, right))        return right;    else if(upper_less_equal(right, left_minuend))        return identity_element<Type>::value();    return construct<Type>(domain_next<Type>(upper(left_minuend)), upper(right));}template<class Type>typename boost::enable_if<is_static_open<Type>, Type>::typeleft_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>::typeleft_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 left of \c right_minuend.\codeleft_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>::typeright_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>::typeright_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>::typeright_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>::typeright_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>::typeoperator & (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>::typeoperator & (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>::typeoperator & (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>::typeintersects(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>::typedisjoint(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>::typeinner_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>::typeinner_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>::typeinner_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>::typeinner_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>::typebetween(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>::typedistance(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>::typedistance(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 lower(x2) - upper(x1);    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>::typeleft_bracket(const Type&) { return "("; }template<class Type>typename boost::    enable_if< mpl::or_< is_static_right_open<Type>                       , is_static_closed<Type>   >, std::string>::typeleft_bracket(const Type&) { return "["; }template<class Type>typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::typeleft_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>::typeright_bracket(const Type&) { return ")"; }template<class Type>typename boost::    enable_if< mpl::or_< is_static_left_open<Type>                       , is_static_closed<Type>    >, std::string>::typeright_bracket(const Type&) { return "]"; }template<class Type>typename boost::enable_if<has_dynamic_bounds<Type>, std::string>::typeright_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
 |