123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236 |
- /*-----------------------------------------------------------------------------+
- 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
|