12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211 |
- /*-----------------------------------------------------------------------------+
- 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/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;
- 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;
- 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());
- }
- //--------------------------------------------------------------------------
- //- 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
|