summaryrefslogtreecommitdiff
path: root/boost/icl/concept/interval_associator.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/icl/concept/interval_associator.hpp')
-rw-r--r--boost/icl/concept/interval_associator.hpp1211
1 files changed, 1211 insertions, 0 deletions
diff --git a/boost/icl/concept/interval_associator.hpp b/boost/icl/concept/interval_associator.hpp
new file mode 100644
index 0000000000..75d8622af3
--- /dev/null
+++ b/boost/icl/concept/interval_associator.hpp
@@ -0,0 +1,1211 @@
+/*-----------------------------------------------------------------------------+
+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_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_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_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_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, *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_NO_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_NO_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_NO_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_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_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_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_RVALUE_REFERENCES
+
+#ifdef BOOST_NO_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_NO_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_NO_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
+
+