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