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