| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237 |
- /*-----------------------------------------------------------------------------+
- 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_ASSOCIATOR_HPP_JOFA_100920
- #define BOOST_ICL_CONCEPT_INTERVAL_ASSOCIATOR_HPP_JOFA_100920
- #include <boost/range/iterator_range.hpp>
- #include <boost/icl/type_traits/domain_type_of.hpp>
- #include <boost/icl/type_traits/interval_type_of.hpp>
- #include <boost/icl/type_traits/is_combinable.hpp>
- #include <boost/icl/detail/set_algo.hpp>
- #include <boost/icl/detail/map_algo.hpp>
- #include <boost/icl/detail/interval_set_algo.hpp>
- #include <boost/icl/detail/interval_map_algo.hpp>
- #include <boost/icl/concept/interval.hpp>
- namespace boost{ namespace icl
- {
- //==============================================================================
- //= Containedness<IntervalSet|IntervalMap>
- //==============================================================================
- //------------------------------------------------------------------------------
- //- bool within(c T&, c P&) T={Set,Map} P={e i b p S M}
- //------------------------------------------------------------------------------
- template<class SubT, class SuperT>
- typename enable_if<is_interval_container<SuperT>, bool>::type
- within(const SubT& sub, const SuperT& super)
- {
- return icl::contains(super, sub);
- }
- //==============================================================================
- //= Equivalences and Orderings<IntervalSet|IntervalMap>
- //==============================================================================
- template<class Type>
- inline typename enable_if<is_interval_container<Type>, bool>::type
- operator == (const Type& left, const Type& right)
- {
- return Set::lexicographical_equal(left, right);
- }
- template<class Type>
- inline typename enable_if<is_interval_container<Type>, bool>::type
- operator < (const Type& left, const Type& right)
- {
- typedef typename Type::segment_compare segment_compare;
- return std::lexicographical_compare(
- left.begin(), left.end(), right.begin(), right.end(),
- segment_compare()
- );
- }
- /** Returns true, if \c left and \c right contain the same elements.
- Complexity: linear. */
- template<class LeftT, class RightT>
- typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
- is_element_equal(const LeftT& left, const RightT& right)
- {
- return Interval_Set::is_element_equal(left, right);
- }
- /** Returns true, if \c left is lexicographically less than \c right.
- Intervals are interpreted as sequence of elements.
- Complexity: linear. */
- template<class LeftT, class RightT>
- typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
- is_element_less(const LeftT& left, const RightT& right)
- {
- return Interval_Set::is_element_less(left, right);
- }
- /** Returns true, if \c left is lexicographically greater than \c right.
- Intervals are interpreted as sequence of elements.
- Complexity: linear. */
- template<class LeftT, class RightT>
- typename enable_if<is_intra_combinable<LeftT, RightT>, bool>::type
- is_element_greater(const LeftT& left, const RightT& right)
- {
- return Interval_Set::is_element_greater(left, right);
- }
- //------------------------------------------------------------------------------
- template<class LeftT, class RightT>
- typename enable_if<is_inter_combinable<LeftT, RightT>, int>::type
- inclusion_compare(const LeftT& left, const RightT& right)
- {
- return Interval_Set::subset_compare(left, right,
- left.begin(), left.end(),
- right.begin(), right.end());
- }
- //------------------------------------------------------------------------------
- template<class LeftT, class RightT>
- typename enable_if< is_concept_compatible<is_interval_map, LeftT, RightT>,
- bool >::type
- is_distinct_equal(const LeftT& left, const RightT& right)
- {
- return Map::lexicographical_distinct_equal(left, right);
- }
- //==============================================================================
- //= Size<IntervalSet|IntervalMap>
- //==============================================================================
- template<class Type>
- typename enable_if<is_interval_container<Type>, std::size_t>::type
- iterative_size(const Type& object)
- {
- return object.iterative_size();
- }
- template<class Type>
- typename enable_if
- < mpl::and_< is_interval_container<Type>
- , is_discrete<typename Type::domain_type> >
- , typename Type::size_type
- >::type
- cardinality(const Type& object)
- {
- typedef typename Type::size_type size_type;
- //CL typedef typename Type::interval_type interval_type;
- size_type size = identity_element<size_type>::value();
- ICL_const_FORALL(typename Type, it, object)
- size += icl::cardinality(key_value<Type>(it));
- return size;
- }
- template<class Type>
- typename enable_if
- < mpl::and_< is_interval_container<Type>
- , mpl::not_<is_discrete<typename Type::domain_type> > >
- , typename Type::size_type
- >::type
- cardinality(const Type& object)
- {
- typedef typename Type::size_type size_type;
- //CL typedef typename Type::interval_type interval_type;
- size_type size = identity_element<size_type>::value();
- size_type interval_size;
- ICL_const_FORALL(typename Type, it, object)
- {
- interval_size = icl::cardinality(key_value<Type>(it));
- if(interval_size == icl::infinity<size_type>::value())
- return interval_size;
- else
- size += interval_size;
- }
- return size;
- }
- template<class Type>
- inline typename enable_if<is_interval_container<Type>, typename Type::size_type>::type
- size(const Type& object)
- {
- return icl::cardinality(object);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, typename Type::difference_type>::type
- length(const Type& object)
- {
- typedef typename Type::difference_type difference_type;
- typedef typename Type::const_iterator const_iterator;
- difference_type length = identity_element<difference_type>::value();
- const_iterator it_ = object.begin();
- while(it_ != object.end())
- length += icl::length(key_value<Type>(it_++));
- return length;
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, std::size_t>::type
- interval_count(const Type& object)
- {
- return icl::iterative_size(object);
- }
- template<class Type>
- typename enable_if< is_interval_container<Type>
- , typename Type::difference_type >::type
- distance(const Type& object)
- {
- typedef typename Type::difference_type DiffT;
- typedef typename Type::const_iterator const_iterator;
- const_iterator it_ = object.begin(), pred_;
- DiffT dist = identity_element<DiffT>::value();
- if(it_ != object.end())
- pred_ = it_++;
- while(it_ != object.end())
- dist += icl::distance(key_value<Type>(pred_++), key_value<Type>(it_++));
-
- return dist;
- }
- //==============================================================================
- //= Range<IntervalSet|IntervalMap>
- //==============================================================================
- template<class Type>
- typename enable_if<is_interval_container<Type>,
- typename Type::interval_type>::type
- hull(const Type& object)
- {
- return
- icl::is_empty(object)
- ? identity_element<typename Type::interval_type>::value()
- : icl::hull( key_value<Type>(object.begin()),
- key_value<Type>(object.rbegin()) );
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>,
- typename domain_type_of<Type>::type>::type
- lower(const Type& object)
- {
- typedef typename domain_type_of<Type>::type DomainT;
- return
- icl::is_empty(object)
- ? unit_element<DomainT>::value()
- : icl::lower( key_value<Type>(object.begin()) );
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>,
- typename domain_type_of<Type>::type>::type
- upper(const Type& object)
- {
- typedef typename domain_type_of<Type>::type DomainT;
- return
- icl::is_empty(object)
- ? identity_element<DomainT>::value()
- : icl::upper( key_value<Type>(object.rbegin()) );
- }
- //------------------------------------------------------------------------------
- template<class Type>
- typename enable_if
- < mpl::and_< is_interval_container<Type>
- , is_discrete<typename domain_type_of<Type>::type> >
- , typename domain_type_of<Type>::type>::type
- first(const Type& object)
- {
- typedef typename domain_type_of<Type>::type DomainT;
- return
- icl::is_empty(object)
- ? unit_element<DomainT>::value()
- : icl::first( key_value<Type>(object.begin()) );
- }
- template<class Type>
- typename enable_if
- < mpl::and_< is_interval_container<Type>
- , is_discrete<typename domain_type_of<Type>::type> >
- , typename domain_type_of<Type>::type>::type
- last(const Type& object)
- {
- typedef typename domain_type_of<Type>::type DomainT;
- return
- icl::is_empty(object)
- ? identity_element<DomainT>::value()
- : icl::last( key_value<Type>(object.rbegin()) );
- }
- //==============================================================================
- //= Addition<IntervalSet|IntervalMap>
- //==============================================================================
- //------------------------------------------------------------------------------
- //- T& op +=(T&, c P&) T:{S}|{M} P:{e i}|{b p}
- //------------------------------------------------------------------------------
- /* \par \b Requires: \c OperandT is an addable derivative type of \c Type.
- \b Effects: \c operand is added to \c object.
- \par \b Returns: A reference to \c object.
- \b Complexity:
- \code
- \ OperandT:
- \ element segment
- Type:
- interval container O(log n) O(n)
- interval_set amortized
- spearate_interval_set O(log n)
- n = object.interval_count()
- \endcode
- For the addition of \b elements or \b segments
- complexity is \b logarithmic or \b linear respectively.
- For \c interval_sets and \c separate_interval_sets addition of segments
- is \b amortized \b logarithmic.
- */
- template<class Type, class OperandT>
- typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
- operator += (Type& object, const OperandT& operand)
- {
- return icl::add(object, operand);
- }
- //------------------------------------------------------------------------------
- //- T& op +=(T&, c P&) T:{S}|{M} P:{S'}|{M'}
- //------------------------------------------------------------------------------
- /** \par \b Requires: \c OperandT is an interval container addable to \c Type.
- \b Effects: \c operand is added to \c object.
- \par \b Returns: A reference to \c object.
- \b Complexity: loglinear */
- template<class Type, class OperandT>
- typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
- operator += (Type& object, const OperandT& operand)
- {
- typename Type::iterator prior_ = object.end();
- ICL_const_FORALL(typename OperandT, elem_, operand)
- prior_ = icl::add(object, prior_, *elem_);
- return object;
- }
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op + (T, c P&) T:{S}|{M} P:{e i S}|{b p M}
- //------------------------------------------------------------------------------
- /** \par \b Requires: \c object and \c operand are addable.
- \b Effects: \c operand is added to \c object.
- \par \b Efficieny: There is one additional copy of
- \c Type \c object compared to inplace \c operator \c += */
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator + (Type object, const OperandT& operand)
- {
- return object += operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator + (const Type& object, const OperandT& operand)
- {
- Type temp = object;
- return boost::move(temp += operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator + (Type&& object, const OperandT& operand)
- {
- return boost::move(object += operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op + (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'}
- //------------------------------------------------------------------------------
- /** \par \b Requires: \c object and \c operand are addable.
- \b Effects: \c operand is added to \c object.
- \par \b Efficieny: There is one additional copy of
- \c Type \c object compared to inplace \c operator \c += */
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator + (const OperandT& operand, Type object)
- {
- return object += operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator + (const OperandT& operand, const Type& object)
- {
- Type temp = object;
- return boost::move(temp += operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator + (const OperandT& operand, Type&& object)
- {
- return boost::move(object += operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op + (T, c P&) T:{S}|{M} P:{S}|{M}
- //------------------------------------------------------------------------------
- /** \par \b Requires: \c object and \c operand are addable.
- \b Effects: \c operand is added to \c object.
- \par \b Efficieny: There is one additional copy of
- \c Type \c object compared to inplace \c operator \c += */
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator + (Type object, const Type& operand)
- {
- return object += operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator + (const Type& object, const Type& operand)
- {
- Type temp = object;
- return boost::move(temp += operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator + (Type&& object, const Type& operand)
- {
- return boost::move(object += operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator + (const Type& operand, Type&& object)
- {
- return boost::move(object += operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator + (Type&& object, Type&& operand)
- {
- return boost::move(object += operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- Addition |=, |
- //------------------------------------------------------------------------------
- //------------------------------------------------------------------------------
- //- T& op |=(c P&) T:{S}|{M} P:{e i}|{b p}
- //------------------------------------------------------------------------------
- /** \par \b Requires: Types \c Type and \c OperandT are addable.
- \par \b Effects: \c operand is added to \c object.
- \par \b Returns: A reference to \c object.
- \b Complexity:
- \code
- \ OperandT: interval
- \ element segment container
- Type:
- interval container O(log n) O(n) O(m log(n+m))
- interval_set amortized
- spearate_interval_set O(log n)
- n = object.interval_count()
- m = operand.interval_count()
- \endcode
- For the addition of \b elements, \b segments and \b interval \b containers
- complexity is \b logarithmic, \b linear and \b loglinear respectively.
- For \c interval_sets and \c separate_interval_sets addition of segments
- is \b amortized \b logarithmic.
- */
- template<class Type, class OperandT>
- typename enable_if<is_right_intra_combinable<Type, OperandT>, Type>::type&
- operator |= (Type& object, const OperandT& operand)
- {
- return object += operand;
- }
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op | (T, c P&) T:{S}|{M} P:{e i S}|{b p M}
- //------------------------------------------------------------------------------
- /** \par \b Requires: \c object and \c operand are addable.
- \b Effects: \c operand is added to \c object.
- \par \b Efficieny: There is one additional copy of
- \c Type \c object compared to inplace \c operator \c |= */
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator | (Type object, const OperandT& operand)
- {
- return object += operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator | (const Type& object, const OperandT& operand)
- {
- Type temp = object;
- return boost::move(temp += operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator | (Type&& object, const OperandT& operand)
- {
- return boost::move(object += operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op | (T, c P&) T:{S}|{M} P:{S}|{M}
- //------------------------------------------------------------------------------
- /** \par \b Requires: \c object and \c operand are addable.
- \b Effects: \c operand is added to \c object.
- \par \b Efficieny: There is one additional copy of
- \c Type \c object compared to inplace \c operator \c |= */
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator | (const OperandT& operand, Type object)
- {
- return object += operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator | (const OperandT& operand, const Type& object)
- {
- Type temp = object;
- return boost::move(temp += operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator | (const OperandT& operand, Type&& object)
- {
- return boost::move(object += operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op | (T, c P&) T:{S}|{M} P:{S}|{M}
- //------------------------------------------------------------------------------
- /** \par \b Requires: \c object and \c operand are addable.
- \b Effects: \c operand is added to \c object.
- \par \b Efficieny: There is one additional copy of
- \c Type \c object compared to inplace \c operator \c |= */
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator | (Type object, const Type& operand)
- {
- return object += operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator | (const Type& object, const Type& operand)
- {
- Type temp = object;
- return boost::move(temp += operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator | (Type&& object, const Type& operand)
- {
- return boost::move(object += operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator | (const Type& operand, Type&& object)
- {
- return boost::move(object += operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator | (Type&& object, Type&& operand)
- {
- return boost::move(object += operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //==============================================================================
- //= Insertion<IntervalSet|IntervalSet>
- //==============================================================================
- //------------------------------------------------------------------------------
- //- T& insert(T&, c P&) T:{S}|{M} P:{S'}|{M'}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
- insert(Type& object, const OperandT& operand)
- {
- typename Type::iterator prior_ = object.end();
- ICL_const_FORALL(typename OperandT, elem_, operand)
- insert(object, prior_, *elem_);
- return object;
- }
- //==============================================================================
- //= Erasure<IntervalSet|IntervalSet>
- //==============================================================================
- //------------------------------------------------------------------------------
- //- T& erase(T&, c P&) T:{S}|{M} P:{S'}|{S' M'}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<combines_right_to_interval_container<Type, OperandT>,
- Type>::type&
- erase(Type& object, const OperandT& operand)
- {
- typedef typename OperandT::const_iterator const_iterator;
- if(icl::is_empty(operand))
- return object;
- const_iterator common_lwb, common_upb;
- if(!Set::common_range(common_lwb, common_upb, operand, object))
- return object;
- const_iterator it_ = common_lwb;
- while(it_ != common_upb)
- icl::erase(object, *it_++);
- return object;
- }
- //==============================================================================
- //= Subtraction<IntervalSet|IntervalSet>
- //==============================================================================
- //------------------------------------------------------------------------------
- //- T& op -= (c P&) T:{M} P:{M'}
- //------------------------------------------------------------------------------
- /** \par \b Requires: Types \c Type and \c OperandT are subtractable.
- \par \b Effects: \c operand is subtracted from \c object.
- \par \b Returns: A reference to \c object.
- \b Complexity:
- \code
- \ OperandT: interval
- \ element segment container
- Type:
- interval container O(log n) O(n) O(m log(n+m))
- amortized
- interval_sets O(log n)
- n = object.interval_count()
- m = operand.interval_count()
- \endcode
- For the subtraction of \em elements, \b segments and \b interval \b containers
- complexity is \b logarithmic, \b linear and \b loglinear respectively.
- For interval sets subtraction of segments
- is \b amortized \b logarithmic.
- */
- template<class Type, class OperandT>
- typename enable_if<is_concept_compatible<is_interval_map, Type, OperandT>,
- Type>::type&
- operator -=(Type& object, const OperandT& operand)
- {
- ICL_const_FORALL(typename OperandT, elem_, operand)
- icl::subtract(object, *elem_);
- return object;
- }
- //------------------------------------------------------------------------------
- //- T& op -= (c P&) T:{S}|{M} P:{e i}|{b p}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
- operator -= (Type& object, const OperandT& operand)
- {
- return icl::subtract(object, operand);
- }
- //------------------------------------------------------------------------------
- //- T& op -= (c P&) T:{M} P:{e i}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_cross_derivative<Type, OperandT>, Type>::type&
- operator -= (Type& object, const OperandT& operand)
- {
- return icl::erase(object, operand);
- }
- //------------------------------------------------------------------------------
- //- T& op -= (c P&) T:{S M} P:{S'}
- //------------------------------------------------------------------------------
- template<class Type, class IntervalSetT>
- typename enable_if<combines_right_to_interval_set<Type, IntervalSetT>,
- Type>::type&
- operator -= (Type& object, const IntervalSetT& operand)
- {
- return erase(object, operand);
- }
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op - (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
- operator - (Type object, const OperandT& operand)
- {
- return object -= operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
- operator - (const Type& object, const OperandT& operand)
- {
- Type temp = object;
- return boost::move(temp -= operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type
- operator - (Type&& object, const OperandT& operand)
- {
- return boost::move(object -= operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //==============================================================================
- //= Intersection<IntervalSet|IntervalSet>
- //==============================================================================
- //------------------------------------------------------------------------------
- //- void add_intersection(T&, c T&, c P&) T:{S M} P:{S'}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<mpl::and_<is_interval_set<Type>,
- combines_right_to_interval_set<Type, OperandT> >,
- void>::type
- add_intersection(Type& section, const Type& object, const OperandT& operand)
- {
- typedef typename OperandT::const_iterator const_iterator;
- if(operand.empty())
- return;
- const_iterator common_lwb, common_upb;
- if(!Set::common_range(common_lwb, common_upb, operand, object))
- return;
- const_iterator it_ = common_lwb;
- while(it_ != common_upb)
- icl::add_intersection(section, object, key_value<OperandT>(it_++));
- }
- //------------------------------------------------------------------------------
- //- T& op &=(T&, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_right_inter_combinable<Type, OperandT>, Type>::type&
- operator &= (Type& object, const OperandT& operand)
- {
- Type intersection;
- add_intersection(intersection, object, operand);
- object.swap(intersection);
- return object;
- }
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op & (T, c P&) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
- operator & (Type object, const OperandT& operand)
- {
- return object &= operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
- operator & (const Type& object, const OperandT& operand)
- {
- Type temp = object;
- return boost::move(temp &= operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
- operator & (Type&& object, const OperandT& operand)
- {
- return boost::move(object &= operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op & (c P&, T) T:{S}|{M} P:{e i S'}|{e i b p S' M'} S<S' M<M' <:coarser
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
- operator & (const OperandT& operand, Type object)
- {
- return object &= operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
- operator & (const OperandT& operand, const Type& object)
- {
- Type temp = object;
- return boost::move(temp &= operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_inter_combinable<Type, OperandT>, Type>::type
- operator & (const OperandT& operand, Type&& object)
- {
- return boost::move(object &= operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op & (T, c T&) T:{S M}
- //------------------------------------------------------------------------------
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator & (Type object, const Type& operand)
- {
- return object &= operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator & (const Type& object, const Type& operand)
- {
- Type temp = object;
- return boost::move(temp &= operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator & (Type&& object, const Type& operand)
- {
- return boost::move(object &= operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator & (const Type& operand, Type&& object)
- {
- return boost::move(object &= operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator & (Type&& object, Type&& operand)
- {
- return boost::move(object &= operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- intersects<IntervalSet|IntervalMap>
- //------------------------------------------------------------------------------
- //------------------------------------------------------------------------------
- //- bool intersects(c T&, c P&) T:{S}|{M} P:{e i}
- //------------------------------------------------------------------------------
- template<class Type, class CoType>
- typename enable_if<mpl::and_< is_interval_container<Type>
- , boost::is_same<CoType, typename domain_type_of<Type>::type> >,
- bool>::type
- intersects(const Type& left, const CoType& right)
- {
- return icl::contains(left, right);
- }
- template<class Type, class CoType>
- typename enable_if<mpl::and_< is_interval_container<Type>
- , boost::is_same<CoType, typename interval_type_of<Type>::type> >,
- bool>::type
- intersects(const Type& left, const CoType& right)
- {
- return icl::find(left, right) != left.end();
- }
- template<class LeftT, class RightT>
- typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT>
- , mpl::or_<is_total<LeftT>, is_total<RightT> > >
- , bool>::type
- intersects(const LeftT&, const RightT&)
- {
- return true;
- }
- template<class LeftT, class RightT>
- typename enable_if< mpl::and_< is_intra_combinable<LeftT, RightT>
- , mpl::not_<mpl::or_< is_total<LeftT>
- , is_total<RightT> > > >
- , bool>::type
- intersects(const LeftT& left, const RightT& right)
- {
- typedef typename RightT::const_iterator const_iterator;
- LeftT intersection;
- const_iterator right_common_lower_, right_common_upper_;
- if(!Set::common_range(right_common_lower_, right_common_upper_, right, left))
- return false;
- const_iterator it_ = right_common_lower_;
- while(it_ != right_common_upper_)
- {
- icl::add_intersection(intersection, left, *it_++);
- if(!icl::is_empty(intersection))
- return true;
- }
- return false;
- }
- template<class LeftT, class RightT>
- typename enable_if<is_cross_combinable<LeftT, RightT>, bool>::type
- intersects(const LeftT& left, const RightT& right)
- {
- typedef typename RightT::const_iterator const_iterator;
- LeftT intersection;
- if(icl::is_empty(left) || icl::is_empty(right))
- return false;
- const_iterator right_common_lower_, right_common_upper_;
- if(!Set::common_range(right_common_lower_, right_common_upper_, right, left))
- return false;
- typename RightT::const_iterator it_ = right_common_lower_;
- while(it_ != right_common_upper_)
- {
- icl::add_intersection(intersection, left, key_value<RightT>(it_++));
- if(!icl::is_empty(intersection))
- return true;
- }
- return false;
- }
- /** \b Returns true, if \c left and \c right have no common elements.
- Intervals are interpreted as sequence of elements.
- \b Complexity: loglinear, if \c left and \c right are interval containers. */
- template<class LeftT, class RightT>
- typename enable_if<is_inter_combinable<LeftT, RightT>, bool>::type
- disjoint(const LeftT& left, const RightT& right)
- {
- return !intersects(left, right);
- }
- /** \b Returns true, if \c left and \c right have no common elements.
- Intervals are interpreted as sequence of elements.
- \b Complexity: logarithmic, if \c AssociateT is an element type \c Type::element_type.
- linear, if \c AssociateT is a segment type \c Type::segment_type. */
- template<class Type, class AssociateT>
- typename enable_if<is_inter_derivative<Type, AssociateT>, bool>::type
- disjoint(const Type& left, const AssociateT& right)
- {
- return !intersects(left,right);
- }
- //==============================================================================
- //= Symmetric difference<IntervalSet|IntervalSet>
- //==============================================================================
- //------------------------------------------------------------------------------
- //- Symmetric difference ^=, ^
- //------------------------------------------------------------------------------
- //------------------------------------------------------------------------------
- //- T& op ^=(T&, c P&) T:{S}|{M} P:{S'}|{M'}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_intra_combinable<Type, OperandT>, Type>::type&
- operator ^= (Type& object, const OperandT& operand)
- {
- return icl::flip(object, operand);
- }
- //------------------------------------------------------------------------------
- //- T& op ^=(T&, c P&) T:{S}|{M} P:{e i}|{b p}
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_intra_derivative<Type, OperandT>, Type>::type&
- operator ^= (Type& object, const OperandT& operand)
- {
- return icl::flip(object, operand);
- }
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op ^ (T, c P&) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator ^ (Type object, const OperandT& operand)
- {
- return object ^= operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator ^ (const Type& object, const OperandT& operand)
- {
- Type temp = object;
- return boost::move(temp ^= operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator ^ (Type&& object, const OperandT& operand)
- {
- return boost::move(object ^= operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op ^ (c P&, T) T:{S}|{M} P:{e i S'}|{b p M'} S<S' M<M' <:coarser
- //------------------------------------------------------------------------------
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator ^ (const OperandT& operand, Type object)
- {
- return object ^= operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator ^ (const OperandT& operand, const Type& object)
- {
- Type temp = object;
- return boost::move(temp ^= operand);
- }
- template<class Type, class OperandT>
- typename enable_if<is_binary_intra_combinable<Type, OperandT>, Type>::type
- operator ^ (const OperandT& operand, Type&& object)
- {
- return boost::move(object ^= operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- #ifdef BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //------------------------------------------------------------------------------
- //- T op ^ (T, c T&) T:{S M}
- //------------------------------------------------------------------------------
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator ^ (typename Type::overloadable_type object, const Type& operand)
- {
- return object ^= operand;
- }
- #else //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator ^ (const Type& object, const Type& operand)
- {
- Type temp = object;
- return boost::move(temp ^= operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator ^ (Type&& object, const Type& operand)
- {
- return boost::move(object ^= operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator ^ (const Type& operand, Type&& object)
- {
- return boost::move(object ^= operand);
- }
- template<class Type>
- typename enable_if<is_interval_container<Type>, Type>::type
- operator ^ (Type&& object, Type&& operand)
- {
- return boost::move(object ^= operand);
- }
- #endif //BOOST_ICL_NO_CXX11_RVALUE_REFERENCES
- //==========================================================================
- //= Element Iteration <IntervalSet|IntervalMap>
- //==========================================================================
- //--------------------------------------------------------------------------
- //- Forward
- //--------------------------------------------------------------------------
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_iterator>::type
- elements_begin(Type& object)
- {
- return typename Type::element_iterator(object.begin());
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_iterator>::type
- elements_end(Type& object)
- {
- return typename Type::element_iterator(object.end());
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_const_iterator>::type
- elements_begin(const Type& object)
- {
- return typename Type::element_const_iterator(object.begin());
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_const_iterator>::type
- elements_end(const Type& object)
- {
- return typename Type::element_const_iterator(object.end());
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- iterator_range<typename Type::element_iterator> >::type
- elements(Type& object)
- {
- return
- make_iterator_range( typename Type::element_iterator(object.begin())
- , typename Type::element_iterator(object.end()) );
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- iterator_range<typename Type::element_const_iterator> >::type
- elements(Type const& object)
- {
- return
- make_iterator_range( typename Type::element_const_iterator(object.begin())
- , typename Type::element_const_iterator(object.end()) );
- }
- //--------------------------------------------------------------------------
- //- Reverse
- //--------------------------------------------------------------------------
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_reverse_iterator>::type
- elements_rbegin(Type& object)
- {
- return typename Type::element_reverse_iterator(object.rbegin());
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_reverse_iterator>::type
- elements_rend(Type& object)
- {
- return typename Type::element_reverse_iterator(object.rend());
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_const_reverse_iterator>::type
- elements_rbegin(const Type& object)
- {
- return typename Type::element_const_reverse_iterator(object.rbegin());
- }
- template<class Type>
- typename enable_if
- <mpl::and_< is_interval_container<Type>
- , mpl::not_<is_continuous_interval<typename Type::interval_type> > >,
- typename Type::element_const_reverse_iterator>::type
- elements_rend(const Type& object)
- {
- return typename Type::element_const_reverse_iterator(object.rend());
- }
- }} // namespace boost icl
- #endif
|