early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,43 @@
/*-----------------------------------------------------------------------------+
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_DETAIL_ASSOCIATED_VALUE_HPP_JOFA_100829
#define BOOST_ICL_DETAIL_ASSOCIATED_VALUE_HPP_JOFA_100829
#include <boost/icl/detail/design_config.hpp>
#include <boost/icl/type_traits/is_combinable.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/and.hpp>
namespace boost{namespace icl
{
template<class Type, class CoType>
typename enable_if< mpl::and_< is_key_compare_equal<Type,CoType>
, mpl::and_<is_map<Type>, is_map<CoType> > >,
bool>::type
co_equal(typename Type::const_iterator left_, typename CoType::const_iterator right_,
const Type* = 0, const CoType* = 0)
{
return co_value<Type>(left_) == co_value<CoType>(right_);
}
template<class Type, class CoType>
typename enable_if< mpl::and_< is_key_compare_equal<Type,CoType>
, mpl::not_<mpl::and_<is_map<Type>, is_map<CoType> > > >,
bool>::type
co_equal(typename Type::const_iterator, typename CoType::const_iterator,
const Type* = 0, const CoType* = 0)
{
return true;
}
}} // namespace icl boost
#endif

View File

@@ -0,0 +1,26 @@
/*-----------------------------------------------------------------------------+
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_DETAIL_BOOST_CONFIG_HPP_JOFA_101031
#define BOOST_ICL_DETAIL_BOOST_CONFIG_HPP_JOFA_101031
// Since boost_1_44_0 boost/config.hpp can produce warnings too.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4996) // Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
#endif
#include <boost/config.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,31 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2009-2009: 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_CHECK_HPP_JOFA_090913
#define BOOST_ICL_CONCEPT_CHECK_HPP_JOFA_090913
#include <boost/concept_check.hpp>
#include <boost/concept/detail/concept_def.hpp>
namespace boost{ namespace icl
{
BOOST_concept(EqualComparable,(Type))
{
BOOST_CONCEPT_USAGE(EqualComparable) {
require_boolean_expr(_left == _right);
}
private:
Type _left, _right;
};
}}// namespace boost icl
#include <boost/concept/detail/concept_undef.hpp>
#endif

View File

@@ -0,0 +1,113 @@
/*-----------------------------------------------------------------------------+
Author: Joachim Faulhaber
Copyright (c) 2009-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)
+-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------+
Template parameters of major itl class templates can be designed as
template template parameters or
template type parameter
by setting defines in this file.
+-----------------------------------------------------------------------------*/
#ifndef BOOST_ICL_DESIGN_CONFIG_HPP_JOFA_090214
#define BOOST_ICL_DESIGN_CONFIG_HPP_JOFA_090214
// If this macro is defined, right_open_interval with static interval borders
// will be used as default for all interval containers.
// BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS should be defined in the application
// before other includes from the ITL
//#define BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS
// If BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS is NOT defined, ITL uses intervals
// with dynamic borders as default.
//------------------------------------------------------------------------------
// Auxiliary macros for denoting template signatures.
// Purpose:
// (1) Shorten the lenthy and redundant template signatures.
// (2) Name anonymous template types according to their meaning ...
// (3) Making easier to refactor by redefinitin of the macros
// (4) Being able to check template template parameter variants against
// template type parameter variants.
#define ICL_USE_COMPARE_TEMPLATE_TEMPLATE
#define ICL_USE_COMBINE_TEMPLATE_TEMPLATE
#define ICL_USE_SECTION_TEMPLATE_TEMPLATE
// ICL_USE_INTERVAL_TEMPLATE_TYPE
//------------------------------------------------------------------------------
// template parameter Compare can not be a template type parameter as long as
// Compare<Interval<DomainT,Compare> >() is called in std::lexicographical_compare
// implementing operator< for interval_base_{set,map}. see NOTE DESIGN TTP
#ifdef ICL_USE_COMPARE_TEMPLATE_TEMPLATE
# define ICL_COMPARE template<class>class
# define ICL_COMPARE_DOMAIN(itl_compare, domain_type) itl_compare<domain_type>
# define ICL_COMPARE_INSTANCE(compare_instance, domain_type) compare_instance
# define ICL_EXCLUSIVE_LESS(interval_type) exclusive_less_than
#else//ICL_USE_COMPARE_TEMPLATE_TYPE
# define ICL_COMPARE class
# define ICL_COMPARE_DOMAIN(itl_compare, domain_type) itl_compare
# define ICL_COMPARE_INSTANCE(compare_instance, domain_type) compare_instance<domain_type>
# define ICL_EXCLUSIVE_LESS(interval_type) exclusive_less_than<interval_type>
#endif
//------------------------------------------------------------------------------
// template parameter Combine could be a template type parameter.
#ifdef ICL_USE_COMBINE_TEMPLATE_TEMPLATE
# define ICL_COMBINE template<class>class
# define ICL_COMBINE_CODOMAIN(itl_combine, codomain_type) itl_combine<codomain_type>
# define ICL_COMBINE_INSTANCE(combine_instance,codomain_type) combine_instance
#else//ICL_USE_COMBINE_TEMPLATE_TYPE
# define ICL_COMBINE class
# define ICL_COMBINE_CODOMAIN(itl_combine, codomain_type) itl_combine
# define ICL_COMBINE_INSTANCE(combine_instance,codomain_type) combine_instance<codomain_type>
#endif
//------------------------------------------------------------------------------
// template parameter Section could be a template type parameter.
#ifdef ICL_USE_SECTION_TEMPLATE_TEMPLATE
# define ICL_SECTION template<class>class
# define ICL_SECTION_CODOMAIN(itl_intersect, codomain_type) itl_intersect<codomain_type>
# define ICL_SECTION_INSTANCE(section_instance,codomain_type) section_instance
#else//ICL_USE_SECTION_TEMPLATE_TYPE
# define ICL_SECTION class
# define ICL_SECTION_CODOMAIN(itl_intersect, codomain_type) itl_intersect
# define ICL_SECTION_INSTANCE(section_instance,codomain_type) section_instance<codomain_type>
#endif
//------------------------------------------------------------------------------
// template parameter Interval could be a template type parameter.
#ifdef ICL_USE_INTERVAL_TEMPLATE_TEMPLATE
# define ICL_INTERVAL(itl_compare) template<class,itl_compare>class
# define ICL_INTERVAL2(itl_compare) template<class DomT2,itl_compare>class
# define ICL_INTERVAL_TYPE(itl_interval, domain_type, itl_compare) itl_interval<domain_type,itl_compare>
# define ICL_INTERVAL_INSTANCE(interval_instance,domain_type,itl_compare) interval_instance
#else//ICL_USE_INTERVAL_TEMPLATE_TYPE
# define ICL_INTERVAL(itl_compare) class
# define ICL_INTERVAL2(itl_compare) class
# define ICL_INTERVAL_TYPE(itl_interval, domain_type, itl_compare) itl_interval
# define ICL_INTERVAL_INSTANCE(interval_instance,domain_type,itl_compare) typename interval_instance<domain_type,itl_compare>::type
#endif
//------------------------------------------------------------------------------
#define ICL_ALLOC template<class>class
//------------------------------------------------------------------------------
#define ICL_INTERVAL_DEFAULT boost::icl::interval_type_default
#ifndef BOOST_ICL_USE_COMPARE_STD_GREATER
# define ICL_COMPARE_DEFAULT std::less
#else
# define ICL_COMPARE_DEFAULT std::greater
#endif
//------------------------------------------------------------------------------
#endif // BOOST_ICL_DESIGN_CONFIG_HPP_JOFA_090214

View File

@@ -0,0 +1,210 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2008-2009: 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_ELEMENT_COMPARER_HPP_JOFA_090202
#define BOOST_ICL_ELEMENT_COMPARER_HPP_JOFA_090202
#include <boost/mpl/and.hpp>
#include <boost/icl/type_traits/is_map.hpp>
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/type_traits/identity_element.hpp>
namespace boost{namespace icl
{
namespace Interval_Set
{
template<class LeftT, class RightT>
class element_comparer
{
public:
typedef typename LeftT::const_iterator LeftIterT;
typedef typename RightT::const_iterator RightIterT;
BOOST_STATIC_CONSTANT(bool,
_compare_codomain = (mpl::and_<is_map<LeftT>, is_map<RightT> >::value));
element_comparer(const LeftT& left,
const RightT& right,
const LeftIterT& left_end,
const RightIterT& right_end)
: _left(left), _right(right),
_left_end(left_end), _right_end(right_end), _result(equal)
{}
enum{nextboth, nextleft, nextright, stop};
enum
{
less = comparison::less,
equal = comparison::equal,
greater = comparison::greater
};
int result()const{ return _result; }
bool covalues_are_equal(LeftIterT& left, RightIterT& right)
{
if(co_value<LeftT>(left) < co_value<RightT>(right))
_result = less;
if(co_value<RightT>(right) < co_value<LeftT>(left))
_result = greater;
return _result == equal;
}
int proceed(LeftIterT& left, RightIterT& right)
{
if(upper_less(key_value<LeftT>(left), key_value<RightT>(right)))
{
_prior_left = left;
++left;
return nextleft;
}
else if(upper_less(key_value<RightT>(right), key_value<LeftT>(left)))
{
_prior_right = right;
++right;
return nextright;
}
else
{
++left;
++right;
return nextboth;
}
}
int next_both(LeftIterT& left, RightIterT& right)
{
if(left == _left_end)
{
_result = (right == _right_end) ? equal : less;
return stop;
}
// left != _left_end
if(right == _right_end)
{
_result = greater;
return stop;
}
// The starting intervals have to begin equally
if(lower_less(key_value<LeftT>(left), key_value<RightT>(right)))
{ // left: same A... = sameA...
// right:same B.. = sameB...
_result = less;
return stop;
}
if(lower_less(key_value<LeftT>(right), key_value<RightT>(left)))
{ // left: same B.. = sameB...
// right:same A... = sameA...
_result = greater;
return stop;
}
if(_compare_codomain && !covalues_are_equal(left, right))
return stop;
return proceed(left, right);
}
int next_left(LeftIterT& left, RightIterT& right)
{
if(left == _left_end)
{ // left: same
// right:sameA...
_result = less;
return stop;
}
if(!key_value<LeftT>(_prior_left).touches(key_value<LeftT>(left)))
{ // left: same B = sameB...
// right:sameA = sameA...
_result = greater;
return stop;
}
if(_compare_codomain && !covalues_are_equal(left, right))
return stop;
return proceed(left, right);
}
int next_right(LeftIterT& left, RightIterT& right)
{
if(right == _right_end)
{ // left: sameA...
// right:same
_result = greater;
return stop;
}
if(!key_value<RightT>(_prior_right).touches(key_value<RightT>(right)))
{
// left: sameA... = sameA...
// right:same B.. = sameB...
_result = less;
return stop;
}
if(_compare_codomain && !covalues_are_equal(left, right))
return stop;
return proceed(left, right);
}
private:
const LeftT& _left;
const RightT& _right;
LeftIterT _left_end;
RightIterT _right_end;
LeftIterT _prior_left;
RightIterT _prior_right;
int _result;
};
template<class LeftT, class RightT>
int element_compare
(
const LeftT& left, //sub
const RightT& right, //super
typename LeftT::const_iterator left_begin,
typename LeftT::const_iterator left_end,
typename RightT::const_iterator right_begin,
typename RightT::const_iterator right_end
)
{
typedef element_comparer<LeftT,RightT> Step;
Step step(left, right, left_end, right_end);
typename LeftT::const_iterator left_ = left_begin;
typename RightT::const_iterator right_ = right_begin;
int state = Step::nextboth;
while(state != Step::stop)
{
switch(state){
case Step::nextboth: state = step.next_both (left_, right_); break;
case Step::nextleft: state = step.next_left (left_, right_); break;
case Step::nextright: state = step.next_right(left_, right_); break;
}
}
return step.result();
}
} // namespace Interval_Set
}} // namespace icl boost
#endif

View File

@@ -0,0 +1,335 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2009-2009: 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_DETAIL_ELEMENT_ITERATOR_HPP_JOFA_091104
#define BOOST_ICL_DETAIL_ELEMENT_ITERATOR_HPP_JOFA_091104
#include <boost/mpl/if.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/config/warning_disable.hpp>
#include <boost/icl/type_traits/succ_pred.hpp>
#include <boost/icl/detail/mapped_reference.hpp>
namespace boost{namespace icl
{
//------------------------------------------------------------------------------
template<class Type>
struct is_std_pair
{
typedef is_std_pair<Type> type;
BOOST_STATIC_CONSTANT(bool, value = false);
};
template<class FirstT, class SecondT>
struct is_std_pair<std::pair<FirstT, SecondT> >
{
typedef is_std_pair<std::pair<FirstT, SecondT> > type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
//------------------------------------------------------------------------------
template<class Type>
struct first_element
{
typedef Type type;
};
template<class FirstT, class SecondT>
struct first_element<std::pair<FirstT, SecondT> >
{
typedef FirstT type;
};
//------------------------------------------------------------------------------
template <class SegmentIteratorT> class element_iterator;
template<class IteratorT>
struct is_reverse
{
typedef is_reverse type;
BOOST_STATIC_CONSTANT(bool, value = false);
};
template<class BaseIteratorT>
struct is_reverse<std::reverse_iterator<BaseIteratorT> >
{
typedef is_reverse<std::reverse_iterator<BaseIteratorT> > type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<class BaseIteratorT>
struct is_reverse<icl::element_iterator<BaseIteratorT> >
{
typedef is_reverse<icl::element_iterator<BaseIteratorT> > type;
BOOST_STATIC_CONSTANT(bool, value = is_reverse<BaseIteratorT>::value);
};
//------------------------------------------------------------------------------
template<class SegmentT>
struct elemental;
#ifdef ICL_USE_INTERVAL_TEMPLATE_TEMPLATE
template<class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval>
struct elemental<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) >
{
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
typedef segment_type interval_type;
typedef DomainT type;
typedef DomainT domain_type;
typedef DomainT codomain_type;
typedef DomainT transit_type;
};
template< class DomainT, class CodomainT,
ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval >
struct elemental<std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
{
typedef std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare), CodomainT> segment_type;
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
typedef std::pair<DomainT, CodomainT> type;
typedef DomainT domain_type;
typedef CodomainT codomain_type;
typedef mapped_reference<DomainT, CodomainT> transit_type;
};
#else //ICL_USE_INTERVAL_TEMPLATE_TYPE
template<ICL_INTERVAL(ICL_COMPARE) Interval>
struct elemental
{
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
typedef segment_type interval_type;
typedef typename interval_traits<interval_type>::domain_type domain_type;
typedef domain_type type;
typedef domain_type codomain_type;
typedef domain_type transit_type;
};
template< class CodomainT, ICL_INTERVAL(ICL_COMPARE) Interval >
struct elemental<std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
{
typedef std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare), CodomainT> segment_type;
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
typedef typename interval_traits<interval_type>::domain_type domain_type;
typedef CodomainT codomain_type;
typedef std::pair<domain_type, codomain_type> type;
typedef mapped_reference<domain_type, codomain_type> transit_type;
};
#endif //ICL_USE_INTERVAL_TEMPLATE_TEMPLATE
//------------------------------------------------------------------------------
//- struct segment_adapter
//------------------------------------------------------------------------------
template<class SegmentIteratorT, class SegmentT>
struct segment_adapter;
#ifdef ICL_USE_INTERVAL_TEMPLATE_TEMPLATE
template<class SegmentIteratorT, class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval>
struct segment_adapter<SegmentIteratorT, ICL_INTERVAL_TYPE(Interval,DomainT,Compare) >
{
typedef segment_adapter type;
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
typedef segment_type interval_type;
typedef typename interval_type::difference_type domain_difference_type;
typedef DomainT domain_type;
typedef DomainT codomain_type;
typedef domain_type element_type;
typedef domain_type& transit_type;
static domain_type first (const SegmentIteratorT& leaper){ return leaper->first(); }
static domain_type last (const SegmentIteratorT& leaper){ return leaper->last(); }
static domain_difference_type length(const SegmentIteratorT& leaper){ return leaper->length();}
static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
const domain_difference_type& sneaker)
{
inter_pos = is_reverse<SegmentIteratorT>::value ? leaper->last() - sneaker
: leaper->first() + sneaker;
return inter_pos;
}
};
template < class SegmentIteratorT, class DomainT, class CodomainT,
ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE) Interval >
struct segment_adapter<SegmentIteratorT, std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
{
typedef segment_adapter type;
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
typedef DomainT domain_type;
typedef std::pair<DomainT, CodomainT> element_type;
typedef CodomainT codomain_type;
typedef mapped_reference<DomainT, CodomainT> transit_type;
typedef typename difference_type_of<interval_traits<interval_type> >::type
domain_difference_type;
static domain_type first (const SegmentIteratorT& leaper){ return leaper->first.first(); }
static domain_type last (const SegmentIteratorT& leaper){ return leaper->first.last(); }
static domain_difference_type length(const SegmentIteratorT& leaper){ return leaper->first.length();}
static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
const domain_difference_type& sneaker)
{
inter_pos = is_reverse<SegmentIteratorT>::value ? leaper->first.last() - sneaker
: leaper->first.first() + sneaker;
return transit_type(inter_pos, leaper->second);
}
};
#else // ICL_USE_INTERVAL_TEMPLATE_TYPE
template<class SegmentIteratorT, ICL_INTERVAL(ICL_COMPARE) Interval>
struct segment_adapter
{
typedef segment_adapter type;
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) segment_type;
typedef segment_type interval_type;
typedef typename interval_traits<interval_type>::domain_type domain_type;
typedef domain_type codomain_type;
typedef domain_type element_type;
typedef domain_type& transit_type;
typedef typename difference_type_of<interval_traits<interval_type> >::type
domain_difference_type;
static domain_type first (const SegmentIteratorT& leaper){ return leaper->first(); }
static domain_type last (const SegmentIteratorT& leaper){ return leaper->last(); }
static domain_difference_type length(const SegmentIteratorT& leaper){ return icl::length(*leaper);}
static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
const domain_difference_type& sneaker)
{
inter_pos = is_reverse<SegmentIteratorT>::value ? icl::last(*leaper) - sneaker
: icl::first(*leaper) + sneaker;
return inter_pos;
}
};
template < class SegmentIteratorT, class CodomainT, ICL_INTERVAL(ICL_COMPARE) Interval >
struct segment_adapter<SegmentIteratorT, std::pair<ICL_INTERVAL_TYPE(Interval,DomainT,Compare) const, CodomainT> >
{
typedef segment_adapter type;
typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
typedef typename interval_traits<interval_type>::domain_type domain_type;
typedef CodomainT codomain_type;
typedef std::pair<domain_type, codomain_type> element_type;
typedef mapped_reference<domain_type, CodomainT> transit_type;
typedef typename difference_type_of<interval_traits<interval_type> >::type
domain_difference_type;
static domain_type first (const SegmentIteratorT& leaper){ return leaper->first.first(); }
static domain_type last (const SegmentIteratorT& leaper){ return leaper->first.last(); }
static domain_difference_type length(const SegmentIteratorT& leaper){ return icl::length(leaper->first);}
static transit_type transient_element(domain_type& inter_pos, const SegmentIteratorT& leaper,
const domain_difference_type& sneaker)
{
inter_pos = is_reverse<SegmentIteratorT>::value ? icl::last(leaper->first) - sneaker
: icl::first(leaper->first) + sneaker;
return transit_type(inter_pos, leaper->second);
}
};
#endif // ICL_USE_INTERVAL_TEMPLATE_TEMPLATE
template <class SegmentIteratorT>
class element_iterator
: public boost::iterator_facade<
element_iterator<SegmentIteratorT>
, typename elemental<typename SegmentIteratorT::value_type>::transit_type
, boost::bidirectional_traversal_tag
, typename elemental<typename SegmentIteratorT::value_type>::transit_type
>
{
public:
typedef element_iterator type;
typedef SegmentIteratorT segment_iterator;
typedef typename SegmentIteratorT::value_type segment_type;
typedef typename first_element<segment_type>::type interval_type;
typedef typename elemental<segment_type>::type element_type;
typedef typename elemental<segment_type>::domain_type domain_type;
typedef typename elemental<segment_type>::codomain_type codomain_type;
typedef typename elemental<segment_type>::transit_type transit_type;
typedef transit_type value_type;
typedef typename difference_type_of<interval_traits<interval_type> >::type
domain_difference_type;
private:
typedef typename segment_adapter<segment_iterator,segment_type>::type adapt;
struct enabler{};
public:
element_iterator()
: _saltator(identity_element<segment_iterator>::value())
, _reptator(identity_element<domain_difference_type>::value()){}
explicit element_iterator(segment_iterator jumper)
: _saltator(jumper), _reptator(identity_element<domain_difference_type>::value()) {}
template <class SaltatorT>
element_iterator
( element_iterator<SaltatorT> const& other
, typename enable_if<boost::is_convertible<SaltatorT*,SegmentIteratorT*>, enabler>::type = enabler())
: _saltator(other._saltator), _reptator(other._reptator) {}
private:
friend class boost::iterator_core_access;
template <class> friend class element_iterator;
template <class SaltatorT>
bool equal(element_iterator<SaltatorT> const& other) const
{
return this->_saltator == other._saltator
&& this->_reptator == other._reptator;
}
void increment()
{
if(_reptator < icl::pred(adapt::length(_saltator)))
++_reptator;
else
{
++_saltator;
_reptator = identity_element<domain_difference_type>::value();
}
}
void decrement()
{
if(identity_element<domain_difference_type>::value() < _reptator)
--_reptator;
else
{
--_saltator;
_reptator = adapt::length(_saltator);
--_reptator;
}
}
value_type dereference()const
{
return adapt::transient_element(_inter_pos, _saltator, _reptator);
}
private:
segment_iterator _saltator; // satltare: to jump : the fast moving iterator
mutable domain_difference_type _reptator; // reptare: to sneak : the slow moving iterator 0 based
mutable domain_type _inter_pos; // inter position : Position within the current segment
// _saltator->first.first() <= _inter_pos <= _saltator->first.last()
};
}} // namespace icl boost
#endif // BOOST_ICL_DETAIL_ELEMENT_ITERATOR_HPP_JOFA_091104

View File

@@ -0,0 +1,31 @@
/*-----------------------------------------------------------------------------+
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_DETAIL_EXCLUSIVE_LESS_THAN_HPP_JOFA_100929
#define BOOST_ICL_DETAIL_EXCLUSIVE_LESS_THAN_HPP_JOFA_100929
#include <boost/icl/concept/interval.hpp>
namespace boost{ namespace icl
{
/// Comparison functor on intervals implementing an overlap free less
template <class IntervalT>
struct exclusive_less_than
{
/** Operator <tt>operator()</tt> implements a strict weak ordering on intervals. */
bool operator()(const IntervalT& left, const IntervalT& right)const
{
return icl::non_empty::exclusive_less(left, right);
}
};
}} // namespace boost icl
#endif

View File

@@ -0,0 +1,171 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2008-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_INTERVAL_MAP_ALGO_HPP_JOFA_100730
#define BOOST_ICL_INTERVAL_MAP_ALGO_HPP_JOFA_100730
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/icl/type_traits/is_total.hpp>
#include <boost/icl/type_traits/is_map.hpp>
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/detail/relation_state.hpp>
#include <boost/icl/type_traits/identity_element.hpp>
#include <boost/icl/interval_combining_style.hpp>
#include <boost/icl/detail/element_comparer.hpp>
#include <boost/icl/detail/interval_subset_comparer.hpp>
namespace boost{namespace icl
{
namespace Interval_Map
{
using namespace segmental;
template<class IntervalMapT>
bool is_joinable(const IntervalMapT& container,
typename IntervalMapT::const_iterator first,
typename IntervalMapT::const_iterator past)
{
if(first == container.end())
return true;
typename IntervalMapT::const_iterator it_ = first, next_ = first;
++next_;
const typename IntervalMapT::codomain_type& co_value
= icl::co_value<IntervalMapT>(first);
while(it_ != past)
{
if(icl::co_value<IntervalMapT>(next_) != co_value)
return false;
if(!icl::touches(key_value<IntervalMapT>(it_++),
key_value<IntervalMapT>(next_++)))
return false;
}
return true;
}
//------------------------------------------------------------------------------
//- Containedness of key objects
//------------------------------------------------------------------------------
//- domain_type ----------------------------------------------------------------
template<class IntervalMapT>
typename enable_if<mpl::not_<is_total<IntervalMapT> >, bool>::type
contains(const IntervalMapT& container,
const typename IntervalMapT::domain_type& key)
{
return container.find(key) != container.end();
}
template<class IntervalMapT>
typename enable_if<is_total<IntervalMapT>, bool>::type
contains(const IntervalMapT&,
const typename IntervalMapT::domain_type&)
{
return true;
}
//- interval_type --------------------------------------------------------------
template<class IntervalMapT>
typename enable_if<mpl::not_<is_total<IntervalMapT> >, bool>::type
contains(const IntervalMapT& container,
const typename IntervalMapT::interval_type& sub_interval)
{
typedef typename IntervalMapT::const_iterator const_iterator;
if(icl::is_empty(sub_interval))
return true;
std::pair<const_iterator, const_iterator> exterior = container.equal_range(sub_interval);
if(exterior.first == exterior.second)
return false;
const_iterator last_overlap = prior(exterior.second);
return
icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
&& Interval_Set::is_joinable(container, exterior.first, last_overlap);
}
template<class IntervalMapT>
typename enable_if<is_total<IntervalMapT>, bool>::type
contains(const IntervalMapT&,
const typename IntervalMapT::interval_type&)
{
return true;
}
//- set_type -------------------------------------------------------------------
template<class IntervalMapT, class IntervalSetT>
typename enable_if<mpl::and_<mpl::not_<is_total<IntervalMapT> >
,is_interval_set<IntervalSetT> >, bool>::type
contains(const IntervalMapT& super_map, const IntervalSetT& sub_set)
{
return Interval_Set::within(sub_set, super_map);
}
template<class IntervalMapT, class IntervalSetT>
typename enable_if<mpl::and_<is_total<IntervalMapT>
,is_interval_set<IntervalSetT> >, bool>::type
contains(const IntervalMapT&, const IntervalSetT&)
{
return true;
}
//------------------------------------------------------------------------------
//- Containedness of sub objects
//------------------------------------------------------------------------------
template<class IntervalMapT>
bool contains(const IntervalMapT& container,
const typename IntervalMapT::element_type& key_value_pair)
{
typename IntervalMapT::const_iterator it_ = container.find(key_value_pair.key);
return it_ != container.end() && (*it_).second == key_value_pair.data;
}
template<class IntervalMapT>
bool contains(const IntervalMapT& container,
const typename IntervalMapT::segment_type sub_segment)
{
typedef typename IntervalMapT::const_iterator const_iterator;
typename IntervalMapT::interval_type sub_interval = sub_segment.first;
if(icl::is_empty(sub_interval))
return true;
std::pair<const_iterator, const_iterator> exterior = container.equal_range(sub_interval);
if(exterior.first == exterior.second)
return false;
const_iterator last_overlap = prior(exterior.second);
if(!(sub_segment.second == exterior.first->second) )
return false;
return
icl::contains(hull(exterior.first->first, last_overlap->first), sub_interval)
&& Interval_Map::is_joinable(container, exterior.first, last_overlap);
}
template<class IntervalMapT>
bool contains(const IntervalMapT& super, const IntervalMapT& sub)
{
return Interval_Set::within(sub, super);
}
} // namespace Interval_Map
}} // namespace icl boost
#endif

View File

@@ -0,0 +1,107 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2008-2009: 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_DETAIL_INTERVAL_MORPHISM_HPP_JOFA_080315
#define BOOST_ICL_DETAIL_INTERVAL_MORPHISM_HPP_JOFA_080315
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/concept/interval_set_value.hpp>
#include <boost/icl/concept/element_set_value.hpp>
#include <boost/icl/concept/set_value.hpp>
#include <boost/icl/concept/map_value.hpp>
#include <boost/icl/associative_interval_container.hpp>
#include <boost/icl/associative_element_container.hpp>
namespace boost{namespace icl
{
namespace segmental
{
template <typename ElementContainerT, typename IntervalContainerT>
void atomize(ElementContainerT& result, const IntervalContainerT& src)
{
ICL_const_FORALL(typename IntervalContainerT, itv_, src)
{
const typename IntervalContainerT::key_type& itv = icl::key_value<IntervalContainerT>(itv_);
typename IntervalContainerT::codomain_type coval = icl::co_value<IntervalContainerT>(itv_);
for(typename IntervalContainerT::domain_type element = first(itv); element <= last(itv); ++element)
icl::insert(result, icl::make_value<ElementContainerT>(element, coval));
}
}
template <typename IntervalContainerT, typename ElementContainerT>
void cluster(IntervalContainerT& result, const ElementContainerT& src)
{
typedef typename IntervalContainerT::key_type key_type;
ICL_const_FORALL(typename ElementContainerT, element_, src)
{
const typename ElementContainerT::key_type& key
= key_value<ElementContainerT>(element_);
const typename codomain_type_of<ElementContainerT>::type& coval
= co_value<ElementContainerT>(element_);
result += icl::make_value<IntervalContainerT>(key_type(key), coval);
}
}
template <typename AtomizedType, typename ClusteredType>
struct atomizer
{
void operator()(AtomizedType& atomized, const ClusteredType& clustered)
{
segmental::atomize(atomized, clustered);
}
};
template <typename ClusteredType, typename AtomizedType>
struct clusterer
{
void operator()(ClusteredType& clustered, const AtomizedType& atomized)
{
segmental::cluster(clustered, atomized);
}
};
template <typename JointType, typename SplitType>
struct joiner
{
void operator()(JointType& joint, SplitType& split)
{
icl::join(split);
ICL_FORALL(typename SplitType, split_, split)
joint.insert(*split_);
}
};
template <typename AbsorberType, typename EnricherType>
struct identity_absorber
{
void operator()(AbsorberType& absorber, EnricherType& enricher)
{
icl::absorb_identities(enricher);
ICL_FORALL(typename EnricherType, enricher_, enricher)
absorber.insert(*enricher_);
}
};
} // namespace Interval
template<>
inline std::string binary_template_to_string<segmental::atomizer>::apply() { return "@"; }
template<>
inline std::string binary_template_to_string<segmental::clusterer>::apply() { return "&"; }
template<>
inline std::string binary_template_to_string<segmental::joiner>::apply() { return "j"; }
template<>
inline std::string binary_template_to_string<segmental::identity_absorber>::apply() { return "a0"; }
}} // namespace boost icl
#endif // BOOST_ICL_DETAIL_INTERVAL_MORPHISM_HPP_JOFA_080315

View File

@@ -0,0 +1,648 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2008-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_INTERVAL_SET_ALGO_HPP_JOFA_081005
#define BOOST_ICL_INTERVAL_SET_ALGO_HPP_JOFA_081005
#include <boost/next_prior.hpp>
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/detail/relation_state.hpp>
#include <boost/icl/type_traits/identity_element.hpp>
#include <boost/icl/type_traits/is_map.hpp>
#include <boost/icl/type_traits/is_total.hpp>
#include <boost/icl/type_traits/is_combinable.hpp>
#include <boost/icl/concept/set_value.hpp>
#include <boost/icl/concept/map_value.hpp>
#include <boost/icl/interval_combining_style.hpp>
#include <boost/icl/detail/element_comparer.hpp>
#include <boost/icl/detail/interval_subset_comparer.hpp>
#include <boost/icl/detail/associated_value.hpp>
namespace boost{namespace icl
{
namespace Interval_Set
{
//------------------------------------------------------------------------------
// Lexicographical comparison on ranges of two interval container
//------------------------------------------------------------------------------
template<class LeftT, class RightT>
bool is_element_equal(const LeftT& left, const RightT& right)
{
return subset_compare
(
left, right,
left.begin(), left.end(),
right.begin(), right.end()
) == inclusion::equal;
}
template<class LeftT, class RightT>
bool is_element_less(const LeftT& left, const RightT& right)
{
return element_compare
(
left, right,
left.begin(), left.end(),
right.begin(), right.end()
) == comparison::less;
}
template<class LeftT, class RightT>
bool is_element_greater(const LeftT& left, const RightT& right)
{
return element_compare
(
left, right,
left.begin(), left.end(),
right.begin(), right.end()
) == comparison::greater;
}
//------------------------------------------------------------------------------
// Subset/superset compare on ranges of two interval container
//------------------------------------------------------------------------------
template<class IntervalContainerT>
bool is_joinable(const IntervalContainerT& container,
typename IntervalContainerT::const_iterator first,
typename IntervalContainerT::const_iterator past)
{
if(first == container.end())
return true;
typename IntervalContainerT::const_iterator it_ = first, next_ = first;
++next_;
while(next_ != container.end() && it_ != past)
if(!icl::touches(key_value<IntervalContainerT>(it_++),
key_value<IntervalContainerT>(next_++)))
return false;
return true;
}
template<class LeftT, class RightT>
bool is_inclusion_equal(const LeftT& left, const RightT& right)
{
return subset_compare
(
left, right,
left.begin(), left.end(),
right.begin(), right.end()
) == inclusion::equal;
}
template<class LeftT, class RightT>
typename enable_if<mpl::and_<is_concept_combinable<is_interval_set, is_interval_map, LeftT, RightT>,
is_total<RightT> >,
bool>::type
within(const LeftT&, const RightT&)
{
return true;
}
template<class LeftT, class RightT>
typename enable_if<mpl::and_<is_concept_combinable<is_interval_set, is_interval_map, LeftT, RightT>,
mpl::not_<is_total<RightT> > >,
bool>::type
within(const LeftT& sub, const RightT& super)
{
int result =
subset_compare
(
sub, super,
sub.begin(), sub.end(),
super.begin(), super.end()
);
return result == inclusion::subset || result == inclusion::equal;
}
template<class LeftT, class RightT>
typename enable_if<is_concept_combinable<is_interval_map, is_interval_map, LeftT, RightT>,
bool>::type
within(const LeftT& sub, const RightT& super)
{
int result =
subset_compare
(
sub, super,
sub.begin(), sub.end(),
super.begin(), super.end()
);
return result == inclusion::subset || result == inclusion::equal;
}
template<class LeftT, class RightT>
typename enable_if<is_concept_combinable<is_interval_set, is_interval_set, LeftT, RightT>,
bool>::type
within(const LeftT& sub, const RightT& super)
{
int result =
subset_compare
(
sub, super,
sub.begin(), sub.end(),
super.begin(), super.end()
);
return result == inclusion::subset || result == inclusion::equal;
}
template<class LeftT, class RightT>
typename enable_if<mpl::and_<is_concept_combinable<is_interval_map, is_interval_set, LeftT, RightT>,
is_total<LeftT> >,
bool>::type
contains(const LeftT&, const RightT&)
{
return true;
}
template<class LeftT, class RightT>
typename enable_if<mpl::and_<is_concept_combinable<is_interval_map, is_interval_set, LeftT, RightT>,
mpl::not_<is_total<LeftT> > >,
bool>::type
contains(const LeftT& super, const RightT& sub)
{
int result =
subset_compare
(
super, sub,
super.begin(), super.end(),
sub.begin(), sub.end()
);
return result == inclusion::superset || result == inclusion::equal;
}
template<class LeftT, class RightT>
typename enable_if<is_concept_combinable<is_interval_set, is_interval_set, LeftT, RightT>,
bool>::type
contains(const LeftT& super, const RightT& sub)
{
int result =
subset_compare
(
super, sub,
super.begin(), super.end(),
sub.begin(), sub.end()
);
return result == inclusion::superset || result == inclusion::equal;
}
template<class IntervalContainerT>
bool is_dense(const IntervalContainerT& container,
typename IntervalContainerT::const_iterator first,
typename IntervalContainerT::const_iterator past)
{
if(first == container.end())
return true;
typename IntervalContainerT::const_iterator it_ = first, next_ = first;
++next_;
while(next_ != container.end() && it_ != past)
if(!icl::touches(key_value<IntervalContainerT>(it_++),
key_value<IntervalContainerT>(next_++)))
return false;
return true;
}
} // namespace Interval_Set
namespace segmental
{
template<class Type>
inline bool joinable(const Type& _Type, typename Type::iterator& some, typename Type::iterator& next)
{
// assert: next != end && some++ == next
return touches(key_value<Type>(some), key_value<Type>(next))
&& co_equal(some, next, &_Type, &_Type);
}
template<class Type>
inline void join_nodes(Type& object, typename Type::iterator& left_,
typename Type::iterator& right_)
{
typedef typename Type::interval_type interval_type;
interval_type right_interval = key_value<Type>(right_);
object.erase(right_);
const_cast<interval_type&>(key_value<Type>(left_))
= hull(key_value<Type>(left_), right_interval);
}
template<class Type>
inline typename Type::iterator
join_on_left(Type& object, typename Type::iterator& left_,
typename Type::iterator& right_)
{
//CL typedef typename Type::interval_type interval_type;
// both left and right are in the set and they are neighbours
BOOST_ASSERT(exclusive_less(key_value<Type>(left_), key_value<Type>(right_)));
BOOST_ASSERT(joinable(object, left_, right_));
join_nodes(object, left_, right_);
return left_;
}
template<class Type>
inline typename Type::iterator
join_on_right(Type& object, typename Type::iterator& left_,
typename Type::iterator& right_)
{
//CL typedef typename Type::interval_type interval_type;
// both left and right are in the map and they are neighbours
BOOST_ASSERT(exclusive_less(key_value<Type>(left_), key_value<Type>(right_)));
BOOST_ASSERT(joinable(object, left_, right_));
join_nodes(object, left_, right_);
right_ = left_;
return right_;
}
template<class Type>
typename Type::iterator join_left(Type& object, typename Type::iterator& it_)
{
typedef typename Type::iterator iterator;
if(it_ == object.begin())
return it_;
// there is a predecessor
iterator pred_ = it_;
if(joinable(object, --pred_, it_))
return join_on_right(object, pred_, it_);
return it_;
}
template<class Type>
typename Type::iterator join_right(Type& object, typename Type::iterator& it_)
{
typedef typename Type::iterator iterator;
if(it_ == object.end())
return it_;
// there is a successor
iterator succ_ = it_;
if(++succ_ != object.end() && joinable(object, it_, succ_))
return join_on_left(object, it_, succ_);
return it_;
}
template<class Type>
typename Type::iterator join_neighbours(Type& object, typename Type::iterator& it_)
{
join_left (object, it_);
return join_right(object, it_);
}
template<class Type>
inline typename Type::iterator
join_under(Type& object, const typename Type::value_type& addend)
{
//ASSERT: There is at least one interval in object that overlaps with addend
typedef typename Type::iterator iterator;
typedef typename Type::interval_type interval_type;
typedef typename Type::value_type value_type;
std::pair<iterator,iterator> overlap = object.equal_range(addend);
iterator first_ = overlap.first,
end_ = overlap.second,
last_ = end_; --last_;
iterator second_= first_; ++second_;
interval_type left_resid = right_subtract(key_value<Type>(first_), addend);
interval_type right_resid = left_subtract(key_value<Type>(last_) , addend);
object.erase(second_, end_);
const_cast<value_type&>(key_value<Type>(first_))
= hull(hull(left_resid, addend), right_resid);
return first_;
}
template<class Type>
inline typename Type::iterator
join_under(Type& object, const typename Type::value_type& addend,
typename Type::iterator last_)
{
//ASSERT: There is at least one interval in object that overlaps with addend
typedef typename Type::iterator iterator;
typedef typename Type::interval_type interval_type;
typedef typename Type::value_type value_type;
iterator first_ = object.lower_bound(addend);
//BOOST_ASSERT(next(last_) == this->_set.upper_bound(inter_val));
iterator second_= boost::next(first_), end_ = boost::next(last_);
interval_type left_resid = right_subtract(key_value<Type>(first_), addend);
interval_type right_resid = left_subtract(key_value<Type>(last_) , addend);
object.erase(second_, end_);
const_cast<value_type&>(key_value<Type>(first_))
= hull(hull(left_resid, addend), right_resid);
return first_;
}
} // namespace segmental
namespace Interval_Set
{
using namespace segmental;
template<class Type, int combining_style>
struct on_style;
template<class Type>
struct on_style<Type, interval_combine::joining>
{
typedef on_style type;
typedef typename Type::interval_type interval_type;
typedef typename Type::iterator iterator;
inline static iterator handle_inserted(Type& object, iterator inserted_)
{ return join_neighbours(object, inserted_); }
inline static iterator add_over
(Type& object, const interval_type& addend, iterator last_)
{
iterator joined_ = join_under(object, addend, last_);
return join_neighbours(object, joined_);
}
inline static iterator add_over
(Type& object, const interval_type& addend)
{
iterator joined_ = join_under(object, addend);
return join_neighbours(object, joined_);
}
};
template<class Type>
struct on_style<Type, interval_combine::separating>
{
typedef on_style type;
typedef typename Type::interval_type interval_type;
typedef typename Type::iterator iterator;
inline static iterator handle_inserted(Type&, iterator inserted_)
{ return inserted_; }
inline static iterator add_over
(Type& object, const interval_type& addend, iterator last_)
{
return join_under(object, addend, last_);
}
inline static iterator add_over
(Type& object, const interval_type& addend)
{
return join_under(object, addend);
}
};
template<class Type>
struct on_style<Type, interval_combine::splitting>
{
typedef on_style type;
typedef typename Type::interval_type interval_type;
typedef typename Type::iterator iterator;
inline static iterator handle_inserted(Type&, iterator inserted_)
{ return inserted_; }
inline static iterator add_over
(Type& object, const interval_type& addend, iterator last_)
{
iterator first_ = object.lower_bound(addend);
//BOOST_ASSERT(next(last_) == this->_set.upper_bound(inter_val));
iterator it_ = first_;
interval_type rest_interval = addend;
add_front(object, rest_interval, it_);
add_main (object, rest_interval, it_, last_);
add_rear (object, rest_interval, it_);
return it_;
}
inline static iterator add_over
(Type& object, const interval_type& addend)
{
std::pair<iterator,iterator> overlap = object.equal_range(addend);
iterator first_ = overlap.first,
end_ = overlap.second,
last_ = end_; --last_;
iterator it_ = first_;
interval_type rest_interval = addend;
add_front(object, rest_interval, it_);
add_main (object, rest_interval, it_, last_);
add_rear (object, rest_interval, it_);
return it_;
}
};
template<class Type>
void add_front(Type& object, const typename Type::interval_type& inter_val,
typename Type::iterator& first_)
{
typedef typename Type::interval_type interval_type;
typedef typename Type::iterator iterator;
// If the collision sequence has a left residual 'left_resid' it will
// be split, to provide a standardized start of algorithms:
// The addend interval 'inter_val' covers the beginning of the collision sequence.
// only for the first there can be a left_resid: a part of *first_ left of inter_val
interval_type left_resid = right_subtract(key_value<Type>(first_), inter_val);
if(!icl::is_empty(left_resid))
{ // [------------ . . .
// [left_resid---first_ --- . . .
iterator prior_ = cyclic_prior(object, first_);
const_cast<interval_type&>(key_value<Type>(first_))
= left_subtract(key_value<Type>(first_), left_resid);
//NOTE: Only splitting
object._insert(prior_, icl::make_value<Type>(left_resid, co_value<Type>(first_)));
}
//POST:
// [----- inter_val ---- . . .
// ...[-- first_ --...
}
template<class Type>
void add_segment(Type& object, const typename Type::interval_type& inter_val,
typename Type::iterator& it_ )
{
typedef typename Type::interval_type interval_type;
interval_type lead_gap = right_subtract(inter_val, *it_);
if(!icl::is_empty(lead_gap))
// [lead_gap--- . . .
// [prior_) [-- it_ ...
object._insert(prior(it_), lead_gap);
// . . . --------- . . . addend interval
// [-- it_ --) has a common part with the first overval
++it_;
}
template<class Type>
void add_main(Type& object, typename Type::interval_type& rest_interval,
typename Type::iterator& it_,
const typename Type::iterator& last_)
{
typedef typename Type::interval_type interval_type;
interval_type cur_interval;
while(it_ != last_)
{
cur_interval = *it_ ;
add_segment(object, rest_interval, it_);
// shrink interval
rest_interval = left_subtract(rest_interval, cur_interval);
}
}
template<class Type>
void add_rear(Type& object, const typename Type::interval_type& inter_val,
typename Type::iterator& it_ )
{
typedef typename Type::interval_type interval_type;
typedef typename Type::iterator iterator;
iterator prior_ = cyclic_prior(object, it_);
interval_type cur_itv = *it_;
interval_type lead_gap = right_subtract(inter_val, cur_itv);
if(!icl::is_empty(lead_gap))
// [lead_gap--- . . .
// [prior_) [-- it_ ...
object._insert(prior_, lead_gap);
interval_type end_gap = left_subtract(inter_val, cur_itv);
if(!icl::is_empty(end_gap))
// [---------------end_gap)
// [-- it_ --)
it_ = object._insert(it_, end_gap);
else
{
// only for the last there can be a right_resid: a part of *it_ right of addend
interval_type right_resid = left_subtract(cur_itv, inter_val);
if(!icl::is_empty(right_resid))
{
// [--------------)
// [-- it_ --right_resid)
const_cast<interval_type&>(*it_) = right_subtract(*it_, right_resid);
it_ = object._insert(it_, right_resid);
}
}
}
//==============================================================================
//= Addition
//==============================================================================
template<class Type>
typename Type::iterator
add(Type& object, const typename Type::value_type& addend)
{
//CL typedef typename Type::interval_type interval_type;
typedef typename Type::iterator iterator;
typedef typename on_style<Type, Type::fineness>::type on_style_;
if(icl::is_empty(addend))
return object.end();
std::pair<iterator,bool> insertion = object._insert(addend);
if(insertion.second)
return on_style_::handle_inserted(object, insertion.first);
else
return on_style_::add_over(object, addend, insertion.first);
}
template<class Type>
typename Type::iterator
add(Type& object, typename Type::iterator prior_,
const typename Type::value_type& addend)
{
//CL typedef typename Type::interval_type interval_type;
typedef typename Type::iterator iterator;
typedef typename on_style<Type, Type::fineness>::type on_style_;
if(icl::is_empty(addend))
return prior_;
iterator insertion = object._insert(prior_, addend);
if(*insertion == addend)
return on_style_::handle_inserted(object, insertion);
else
return on_style_::add_over(object, addend);
}
//==============================================================================
//= Subtraction
//==============================================================================
template<class Type>
void subtract(Type& object, const typename Type::value_type& minuend)
{
typedef typename Type::iterator iterator;
typedef typename Type::interval_type interval_type;
//CL typedef typename Type::value_type value_type;
if(icl::is_empty(minuend)) return;
std::pair<iterator, iterator> exterior = object.equal_range(minuend);
if(exterior.first == exterior.second) return;
iterator first_ = exterior.first;
iterator end_ = exterior.second;
iterator last_ = end_; --last_;
interval_type leftResid = right_subtract(*first_, minuend);
interval_type rightResid;
if(first_ != end_ )
rightResid = left_subtract(*last_ , minuend);
object.erase(first_, end_);
if(!icl::is_empty(leftResid))
object._insert(leftResid);
if(!icl::is_empty(rightResid))
object._insert(rightResid);
}
} // namespace Interval_Set
}} // namespace icl boost
#endif

View File

@@ -0,0 +1,368 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2008-2009: 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_INTERVAL_SUBSET_COMPARER_HPP_JOFA_090827
#define BOOST_ICL_INTERVAL_SUBSET_COMPARER_HPP_JOFA_090827
#include <boost/icl/type_traits/is_map.hpp>
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/detail/relation_state.hpp>
#include <boost/icl/type_traits/identity_element.hpp>
#include <boost/icl/type_traits/is_concept_equivalent.hpp>
#include <boost/icl/type_traits/is_interval_container.hpp>
#include <boost/icl/type_traits/is_set.hpp>
#include <boost/icl/concept/interval_set_value.hpp>
namespace boost{namespace icl
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#endif
namespace Interval_Set
{
//------------------------------------------------------------------------------
template<class LeftT, class RightT>
struct settic_codomain_compare
{
static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
{
return inclusion_compare( icl::co_value<LeftT>(left_),
icl::co_value<RightT>(right_));
}
};
template<class LeftT, class RightT>
struct atomic_codomain_compare
{
static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
{
if(icl::co_value<LeftT>(left_) == icl::co_value<RightT>(right_))
return inclusion::equal;
else
return inclusion::unrelated;
}
};
template<class LeftT, class RightT>
struct empty_codomain_compare
{
static int apply(typename LeftT::const_iterator&, typename RightT::const_iterator)
{
return inclusion::equal;
}
};
template<class LeftT, class RightT>
struct map_codomain_compare
{
static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
{
using namespace boost::mpl;
typedef typename LeftT::codomain_type LeftCodomainT;
typedef typename RightT::codomain_type RightCodomainT;
return
if_<
bool_<is_concept_equivalent<is_set,LeftCodomainT,
RightCodomainT>::value>,
settic_codomain_compare<LeftT,RightT>,
atomic_codomain_compare<LeftT,RightT>
>
::type::apply(left_, right_);
}
};
//------------------------------------------------------------------------------
template<class LeftT, class RightT>
class subset_comparer
{
private:
subset_comparer& operator = (const subset_comparer&);
public:
typedef typename LeftT::const_iterator LeftIterT;
typedef typename RightT::const_iterator RightIterT;
BOOST_STATIC_CONSTANT(bool,
_compare_codomain = (mpl::and_<is_map<LeftT>, is_map<RightT> >::value));
subset_comparer(const LeftT& left,
const RightT& right,
const LeftIterT& left_end,
const RightIterT& right_end)
: _left(left), _right(right),
_left_end(left_end), _right_end(right_end), _result(equal)
{}
enum{nextboth, nextleft, nextright, stop};
enum
{
unrelated = inclusion::unrelated,
subset = inclusion::subset, // left is_subset_of right
superset = inclusion::superset, // left is_superset_of right
equal = inclusion::equal // equal = subset | superset
};
int result()const{ return _result; }
int co_compare(LeftIterT& left, RightIterT& right)
{
using namespace boost::mpl;
return
if_<
bool_<is_concept_equivalent<is_interval_map,LeftT,RightT>::value>,
map_codomain_compare<LeftT,RightT>,
empty_codomain_compare<LeftT,RightT>
>
::type::apply(left,right);
}
int restrict_result(int state) { return _result &= state; }
int proceed(LeftIterT& left, RightIterT& right)
{
if(upper_less(key_value<LeftT>(left), key_value<RightT>(right)))
{ // left ..)
// right .....)
_prior_left = left;
++left;
return nextleft;
}
else if(upper_less(key_value<RightT>(right), key_value<LeftT>(left)))
{ // left .....)
// right ..)
_prior_right = right;
++right;
return nextright;
}
else//key_value<LeftT>(left).upper_equal(key_value<RightT>(right))
{ // left ..)
// right ..)
++left;
++right;
return nextboth;
}
}
int next_both(LeftIterT& left, RightIterT& right)
{
if(left == _left_end && right == _right_end)
return stop;
else if(left == _left_end)
{ // left: ....end left could be subset
// right:....[..
restrict_result(subset);
return stop;
}
else if(right == _right_end)
{ // left: ....[.. left could be superset
// right:....end
restrict_result(superset);
return stop;
}
else if(exclusive_less(key_value<LeftT>(left), key_value<RightT>(right)))
{ // left: [..) . . .[---) left could be superset
// right: [..).... if [---) exists
restrict_result(superset);
if(unrelated == _result)
return stop;
else
{
LeftIterT joint_ = _left.lower_bound(key_value<RightT>(right));
if(joint_ == _left.end())
{
_result = unrelated;
return stop;
}
else
{
left = joint_;
return nextboth;
}
}
}
else if(exclusive_less(key_value<RightT>(right), key_value<LeftT>(left)))
{ // left: [.. left could be subset
// right:....) . . .[---) if [---) exists
restrict_result(subset);
if(unrelated == _result)
return stop;
else
{
RightIterT joint_ = _right.lower_bound(key_value<LeftT>(left));
if(joint_ == _right.end())
{
_result = unrelated;
return stop;
}
else
{
right = joint_;
return nextboth;
}
}
}
// left and right have intervals with nonempty intersection:
if(_compare_codomain)
if(unrelated == restrict_result(co_compare(left,right)))
return stop;
// examine left borders only. Right borders are checked in proceed
if(lower_less(key_value<LeftT>(left), key_value<RightT>(right)))
{ // left: ....[... left could be superset
// right:.... [..
if(unrelated == restrict_result(superset))
return stop;
}
else if(lower_less(key_value<RightT>(right), key_value<LeftT>(left)))
{ // left: .... [.. left can be subset
// right:....[...
if(unrelated == restrict_result(subset))
return stop;
}
//else key_value<LeftT>(right).lower_equal(key_value<RightT>(left))
// left: ....[.. both can be equal
// right:....[..
// nothing to do: proceed
return proceed(left, right);
}
int next_left(LeftIterT& left, RightIterT& right)
{
if(left == _left_end)
{ // left: ..)end left could be subset
// right:......)
restrict_result(subset);
return stop;
}
else if(!touches(key_value<LeftT>(_prior_left), key_value<LeftT>(left)))
{ // left: ..) [..
// right:.........)
if(lower_less(key_value<RightT>(right), key_value<LeftT>(left)))
{ // ..) [.. left could be subset
// ..........)
if(unrelated == restrict_result(subset))
return stop;
}
//else ..) [...
// [..
if(_compare_codomain && intersects(key_value<LeftT>(left),key_value<RightT>(right)) )
if(unrelated == restrict_result(co_compare(left,right)))
return stop;
}
else
{ // left: ..)[.. left could be subset
// right:.......)
if(_compare_codomain && intersects(key_value<LeftT>(left), key_value<RightT>(right)) )
if(unrelated == restrict_result(co_compare(left,right)))
return stop;
}
return proceed(left, right);
}
int next_right(LeftIterT& left, RightIterT& right)
{
if(right == _right_end)
{ // left: ......) left could be superset
// right:..)end
restrict_result(superset);
return stop;
}
else if(!touches(key_value<RightT>(_prior_right), key_value<RightT>(right)))
{ // left: .........)
// right:..) [..
if(lower_less(key_value<LeftT>(left), key_value<RightT>(right)))
{ // [....) left could be superset
// ..) [..
if(unrelated == restrict_result(superset))
return stop;
}
//else [....)
// ..) [..
if(_compare_codomain && intersects(key_value<LeftT>(left), key_value<RightT>(right)) )
if(unrelated == restrict_result(co_compare(left,right)))
return stop;
}
else
{
if(_compare_codomain && intersects(key_value<LeftT>(left), key_value<RightT>(right)) )
if(unrelated == restrict_result(co_compare(left,right)))
return stop;
}
return proceed(left, right);
}
private:
const LeftT& _left;
const RightT& _right;
LeftIterT _left_end;
RightIterT _right_end;
LeftIterT _prior_left;
RightIterT _prior_right;
int _result;
};
//------------------------------------------------------------------------------
// Subset/superset comparison on ranges of two interval container
//------------------------------------------------------------------------------
template<class LeftT, class RightT>
int subset_compare
(
const LeftT& left, //sub
const RightT& right, //super
typename LeftT::const_iterator left_begin,
typename LeftT::const_iterator left_end,
typename RightT::const_iterator right_begin,
typename RightT::const_iterator right_end
)
{
typedef subset_comparer<LeftT,RightT> Step;
Step step(left, right, left_end, right_end);
typename LeftT::const_iterator left_ = left_begin;
typename RightT::const_iterator right_ = right_begin;
int state = Step::nextboth;
while(state != Step::stop)
{
switch(state){
case Step::nextboth: state = step.next_both(left_, right_); break;
case Step::nextleft: state = step.next_left(left_, right_); break;
case Step::nextright: state = step.next_right(left_, right_); break;
}
}
return step.result();
}
} // namespace Interval_Set
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}} // namespace icl boost
#endif

View File

@@ -0,0 +1,90 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2007-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_MAPALGO_HPP_JOFA_080225
#define BOOST_ICL_MAPALGO_HPP_JOFA_080225
#include <boost/mpl/and.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/detail/set_algo.hpp>
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#endif
namespace boost{namespace icl
{
namespace Map
{
template <class ObjectT, class CoObjectT>
bool intersects(const ObjectT& left, const CoObjectT& right)
{
typedef typename CoObjectT::const_iterator co_iterator;
co_iterator right_common_lower_, right_common_upper_;
if(!Set::common_range(right_common_lower_, right_common_upper_, right, left))
return false;
co_iterator right_ = right_common_lower_;
while(right_ != right_common_upper_)
if(!(left.find(key_value<CoObjectT>(right_++))==left.end()))
return true;
return false;
}
template<class MapT>
typename MapT::const_iterator next_proton(typename MapT::const_iterator& iter_, const MapT& object)
{
while( iter_ != object.end()
&& (*iter_).second == identity_element<typename MapT::codomain_type>::value())
++iter_;
return iter_;
}
/** Function template <tt>lexicographical_equal</tt> implements
lexicographical equality except for identity_elementic content values. */
template<class MapT>
bool lexicographical_distinct_equal(const MapT& left, const MapT& right)
{
if(&left == &right)
return true;
typename MapT::const_iterator left_ = left.begin();
typename MapT::const_iterator right_ = right.begin();
left_ = next_proton(left_, left);
right_ = next_proton(right_, right);
while(left_ != left.end() && right_ != right.end())
{
if(!(left_->first == right_->first && left_->second == right_->second))
return false;
++left_;
++right_;
left_ = next_proton(left_, left);
right_ = next_proton(right_, right);
}
return left_ == left.end() && right_ == right.end();
}
} // namespace Map
}} // namespace boost icl
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,192 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2009-2009: 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_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108
#define BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/mpl/if.hpp>
#include <boost/icl/type_traits/is_concept_equivalent.hpp>
namespace boost{namespace icl
{
template<class FirstT, class SecondT> class mapped_reference;
//------------------------------------------------------------------------------
template<class Type>
struct is_mapped_reference_combinable{
typedef is_mapped_reference_combinable type;
BOOST_STATIC_CONSTANT(bool, value = false);
};
template<class FirstT, class SecondT>
struct is_mapped_reference_combinable<std::pair<const FirstT,SecondT> >
{
typedef is_mapped_reference_combinable<std::pair<const FirstT,SecondT> > type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<class FirstT, class SecondT>
struct is_mapped_reference_combinable<std::pair<FirstT,SecondT> >
{
typedef is_mapped_reference_combinable<std::pair<FirstT,SecondT> > type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
//------------------------------------------------------------------------------
template<class Type>
struct is_mapped_reference_or_combinable{
typedef is_mapped_reference_or_combinable type;
BOOST_STATIC_CONSTANT(bool, value = is_mapped_reference_combinable<Type>::value);
};
template<class FirstT, class SecondT>
struct is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> >
{
typedef is_mapped_reference_or_combinable<mapped_reference<FirstT,SecondT> > type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
//------------------------------------------------------------------------------
template<class FirstT, class SecondT>
class mapped_reference
{
private:
mapped_reference& operator = (const mapped_reference&);
public:
typedef FirstT first_type;
typedef SecondT second_type;
typedef mapped_reference type;
typedef typename
mpl::if_<is_const<second_type>,
second_type&,
const second_type&>::type second_reference_type;
typedef std::pair< first_type, second_type> std_pair_type;
typedef std::pair<const first_type, second_type> key_std_pair_type;
const first_type& first ;
second_reference_type second;
mapped_reference(const FirstT& fst, second_reference_type snd) : first(fst), second(snd){}
template<class FstT, class SndT>
mapped_reference(const mapped_reference<FstT, SndT>& source):
first(source.first), second(source.second){}
template<class FstT, class SndT>
operator std::pair<FstT,SndT>(){ return std::pair<FstT,SndT>(first, second); }
template<class Comparand>
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
operator == (const Comparand& right)const
{ return first == right.first && second == right.second; }
template<class Comparand>
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
operator != (const Comparand& right)const
{ return !(*this == right); }
template<class Comparand>
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
operator < (const Comparand& right)const
{
return first < right.first
||(!(right.first < first) && second < right.second);
}
template<class Comparand>
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
operator > (const Comparand& right)const
{
return first > right.first
||(!(right.first > first) && second > right.second);
}
template<class Comparand>
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
operator <= (const Comparand& right)const
{
return !(*this > right);
}
template<class Comparand>
typename enable_if<is_mapped_reference_or_combinable<Comparand>, bool>::type
operator >= (const Comparand& right)const
{
return !(*this < right);
}
};
//------------------------------------------------------------------------------
template<class FirstT, class SecondT, class StdPairT>
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
operator == ( const StdPairT& left,
const mapped_reference<FirstT, SecondT>& right)
{
return right == left;
}
template<class FirstT, class SecondT, class StdPairT>
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
operator != ( const StdPairT& left,
const mapped_reference<FirstT, SecondT>& right)
{
return !(right == left);
}
//------------------------------------------------------------------------------
template<class FirstT, class SecondT, class StdPairT>
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
operator < ( const StdPairT& left,
const mapped_reference<FirstT, SecondT>& right)
{
return right > left;
}
//------------------------------------------------------------------------------
template<class FirstT, class SecondT, class StdPairT>
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
operator > ( const StdPairT& left,
const mapped_reference<FirstT, SecondT>& right)
{
return right < left;
}
//------------------------------------------------------------------------------
template<class FirstT, class SecondT, class StdPairT>
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
operator <= ( const StdPairT& left,
const mapped_reference<FirstT, SecondT>& right)
{
return !(right < left);
}
//------------------------------------------------------------------------------
template<class FirstT, class SecondT, class StdPairT>
inline typename enable_if<is_mapped_reference_combinable<StdPairT>, bool>::type
operator >= ( const StdPairT& left,
const mapped_reference<FirstT, SecondT>& right)
{
return !(left < right);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
template<class FirstT, class SecondT>
inline mapped_reference<FirstT, SecondT> make_mapped_reference(const FirstT& left, SecondT& right)
{ return mapped_reference<FirstT, SecondT>(left, right); }
}} // namespace icl boost
#endif // BOOST_ICL_DETAIL_MAPPED_REFERENCE_HPP_JOFA_091108

View File

@@ -0,0 +1,35 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2007-2009: Joachim Faulhaber
+------------------------------------------------------------------------------+
Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
+------------------------------------------------------------------------------+
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)
+-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
Macro definitions for some useful notations e.g. iteration headers
-----------------------------------------------------------------------------*/
#ifndef BOOST_ICL_DETAIL_NOTATE_HPP_JOFA_990119
#define BOOST_ICL_DETAIL_NOTATE_HPP_JOFA_990119
// Iterations over stl or stl-compatible containers:
#define ICL_FORALL(type,iter,obj) for(type::iterator iter=(obj).begin(); (iter)!=(obj).end(); (iter)++)
#define ICL_const_FORALL(type,iter,obj) for(type::const_iterator iter=(obj).begin(); !((iter)==(obj).end()); (iter)++)
#define ICL_FORALL_THIS(iter) for(iterator iter=begin(); (iter)!=end(); (iter)++)
#define ICL_const_FORALL_THIS(iter) for(const_iterator iter=this->begin(); (iter)!=this->end(); (iter)++)
// Plain old array iteration (assuming member function VecT::size()!)
#define ICL_FORALL_VEC(idx, vec) for(int idx=0; idx<vec.size(); idx++)
namespace boost{namespace icl
{
const int UNDEFINED_INDEX = -1;
}} // namespace icl boost
#endif // BOOST_ICL_DETAIL_NOTATE_HPP_JOFA_990119

View File

@@ -0,0 +1,43 @@
/*-----------------------------------------------------------------------------+
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_TYPE_TRAITS_ON_ABSORBTION_HPP_JOFA_100915
#define BOOST_ICL_TYPE_TRAITS_ON_ABSORBTION_HPP_JOFA_100915
namespace boost{ namespace icl
{
template<class Type, class Combiner, bool absorbs_identities>
struct on_absorbtion;
template<class Type, class Combiner>
struct on_absorbtion<Type, Combiner, false>
{
typedef on_absorbtion type;
typedef typename Type::codomain_type codomain_type;
static bool is_absorbable(const codomain_type&){ return false; }
};
template<class Type, class Combiner>
struct on_absorbtion<Type, Combiner, true>
{
typedef on_absorbtion type;
typedef typename Type::codomain_type codomain_type;
typedef typename Type::codomain_combine codomain_combine;
static bool is_absorbable(const codomain_type& co_value)
{
return co_value == Combiner::identity_element();
}
};
}} // namespace boost icl
#endif

View File

@@ -0,0 +1,37 @@
/*-----------------------------------------------------------------------------+
Author: Joachim Faulhaber
Copyright (c) 2009-2009: 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)
+-----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------+
States of comparison and inclusion relations as static constants
+-----------------------------------------------------------------------------*/
#ifndef BOOST_ICL_RELATION_STATE_HPP_JOFA_090214
#define BOOST_ICL_RELATION_STATE_HPP_JOFA_090214
namespace boost{namespace icl
{
namespace comparison
{
static const int less = -1;
static const int equal = 0;
static const int greater = 1;
}
namespace inclusion
{
static const int unrelated = 0;
static const int subset = 1;
static const int superset = 2;
static const int equal = 3;
}
}} // namespace icl boost
#endif // BOOST_ICL_RELATION_STATE_HPP_JOFA_090214

View File

@@ -0,0 +1,131 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2007-2010: Joachim Faulhaber
+------------------------------------------------------------------------------+
Copyright (c) 1999-2006: Cortex Software GmbH, Kantstrasse 57, Berlin
+------------------------------------------------------------------------------+
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_SET_ALGO_HPP_JOFA_990225
#define BOOST_ICL_SET_ALGO_HPP_JOFA_990225
#include <boost/type_traits/remove_const.hpp>
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/concept/container.hpp>
#include <boost/icl/concept/set_value.hpp>
#include <boost/icl/concept/map_value.hpp>
namespace boost{namespace icl
{
namespace Set
{
template<class ObjectT, class ConstObjectT, class IteratorT>
bool common_range(IteratorT& lwb, IteratorT& upb, ObjectT& x1, const ConstObjectT& x2)
{
// lwb and upb are iterators of x1 marking the lower and upper bound of
// the common range of x1 and x2.
typedef typename ConstObjectT::const_iterator ConstObject_iterator;
// ObjectT may be const or non const.
typedef typename remove_const<ObjectT>::type PureObjectT;
lwb = x1.end();
upb = x1.end();
if(icl::is_empty(x1) || icl::is_empty(x2))
return false;
IteratorT x1_fst_ = x1.begin();
IteratorT x1_lst_ = x1.end(); x1_lst_--;
ConstObject_iterator x2_fst_ = x2.begin();
ConstObject_iterator x2_lst_ = x2.end(); x2_lst_--;
typename ObjectT::key_compare key_less;
if(key_less(icl::key_value< PureObjectT>(x1_lst_),
icl::key_value<ConstObjectT>(x2_fst_))) // {x1} {x2}
return false;
if(key_less(icl::key_value<ConstObjectT>(x2_lst_),
icl::key_value< PureObjectT>(x1_fst_))) // {x2} {x1}
return false;
// We do have a common range
lwb = x1.lower_bound(icl::key_value<ConstObjectT>(x2_fst_));
upb = x1.upper_bound(icl::key_value<ConstObjectT>(x2_lst_));
return true;
}
/** Function template <tt>contained_in</tt> implements the subset relation.
<tt>contained_in(sub, super)</tt> is true if <tt>sub</tt> is contained in <tt>super</tt> */
template<class SetType>
inline bool within(const SetType& sub, const SetType& super)
{
if(&super == &sub) return true;
if(icl::is_empty(sub)) return true;
if(icl::is_empty(super)) return false;
typename SetType::const_iterator common_lwb_, common_upb_;
if(!common_range(common_lwb_, common_upb_, sub, super))
return false;
typename SetType::const_iterator sub_ = common_lwb_, super_;
while(sub_ != common_upb_)
{
super_ = super.find(*sub_++);
if(super_ == super.end())
return false;
}
return true;
}
template<class SetType>
bool intersects(const SetType& left, const SetType& right)
{
typename SetType::const_iterator common_lwb_right_, common_upb_right_;
if(!common_range(common_lwb_right_, common_upb_right_, right, left))
return false;
typename SetType::const_iterator right_ = common_lwb_right_, found_;
while(right_ != common_upb_right_)
{
found_ = left.find(*right_++);
if(found_ != left.end())
return true; // found a common element
}
// found no common element
return false;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4996) //'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
#endif // I do guarantee here that I am using the parameters correctly :)
/** Function template <tt>lexicographical_equal</tt> implements
lexicographical equality. */
template<class SetType>
inline bool lexicographical_equal(const SetType& left, const SetType& right)
{
if(&left == &right)
return true;
else return left.iterative_size() == right.iterative_size()
&& std::equal(left.begin(), left.end(), right.begin());
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
} // namespace Set
}} // namespace icl boost
#endif

View File

@@ -0,0 +1,45 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2007-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_DETAIL_STD_SET_HPP_JOFA_101007
#define BOOST_ICL_DETAIL_STD_SET_HPP_JOFA_101007
#include <set>
#include <boost/config.hpp>
#include <boost/icl/type_traits/type_to_string.hpp>
#include <boost/icl/type_traits/is_set.hpp>
namespace boost{namespace icl
{
template <class Type>
struct is_set<std::set<Type> >
{
typedef is_set<std::set<Type> > type;
BOOST_STATIC_CONSTANT(bool, value = true);
};
template <class Type>
struct type_to_string<std::set<Type> >
{
static std::string apply()
{ return "set<"+ type_to_string<Type>::apply() +">"; }
};
template <class Type>
struct type_to_string<std::set<Type, std::greater<Type> > >
{
static std::string apply()
{ return "set<"+ type_to_string<Type>::apply() +" g>"; }
};
}} // namespace icl boost
#endif // BOOST_ICL_DETAIL_STD_SET_HPP_JOFA_101007

View File

@@ -0,0 +1,259 @@
/*-----------------------------------------------------------------------------+
Copyright (c) 2008-2009: 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_SUBSET_COMPARER_HPP_JOFA_090202
#define BOOST_ICL_SUBSET_COMPARER_HPP_JOFA_090202
#include <boost/mpl/and.hpp>
#include <boost/icl/type_traits/is_map.hpp>
#include <boost/icl/detail/notate.hpp>
#include <boost/icl/detail/relation_state.hpp>
#include <boost/icl/type_traits/identity_element.hpp>
#include <boost/icl/type_traits/codomain_type_of.hpp>
#include <boost/icl/type_traits/is_concept_equivalent.hpp>
#include <boost/icl/type_traits/is_element_container.hpp>
#include <boost/icl/concept/interval_set_value.hpp>
#include <boost/icl/concept/map_value.hpp>
namespace boost{namespace icl
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant
#endif
namespace Set
{
//------------------------------------------------------------------------------
template<class LeftT, class RightT>
struct settic_codomain_compare
{
static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
{
return inclusion_compare( co_value<LeftT>(left_),
co_value<RightT>(right_));
}
};
template<class LeftT, class RightT>
struct atomic_codomain_compare
{
static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
{
if(co_value<LeftT>(left_) == co_value<RightT>(right_))
return inclusion::equal;
else
return inclusion::unrelated;
}
};
template<class LeftT, class RightT>
struct empty_codomain_compare
{
static int apply(typename LeftT::const_iterator&, typename RightT::const_iterator&)
{
return inclusion::equal;
}
};
template<class LeftT, class RightT>
struct map_codomain_compare
{
static int apply(typename LeftT::const_iterator& left_, typename RightT::const_iterator& right_)
{
using namespace boost::mpl;
typedef typename LeftT::codomain_type LeftCodomainT;
typedef typename RightT::codomain_type RightCodomainT;
return
if_<
bool_<is_concept_equivalent<is_set,LeftCodomainT,
RightCodomainT>::value>,
settic_codomain_compare<LeftT,RightT>,
atomic_codomain_compare<LeftT,RightT>
>
::type::apply(left_, right_);
}
};
//------------------------------------------------------------------------------
template<class LeftT, class RightT>
class subset_comparer
{
private:
subset_comparer& operator = (const subset_comparer&);
public:
typedef typename LeftT::const_iterator LeftIterT;
typedef typename RightT::const_iterator RightIterT;
BOOST_STATIC_CONSTANT(bool,
_compare_codomain = (mpl::and_<is_map<LeftT>, is_map<RightT> >::value));
subset_comparer(const LeftT& left,
const RightT& right,
const LeftIterT& left_end,
const RightIterT& right_end)
: _left(left), _right(right),
_left_end(left_end), _right_end(right_end), _result(equal)
{}
enum{nextboth, stop};
enum
{
unrelated = inclusion::unrelated,
subset = inclusion::subset, // left is_subset_of right
superset = inclusion::superset, // left is_superset_of right
equal = inclusion::equal // equal = subset | superset
};
int result()const{ return _result; }
int co_compare(LeftIterT& left, RightIterT& right)
{
using namespace boost::mpl;
//CL typedef typename codomain_type_of<LeftT>::type LeftCodomainT;
//CL typedef typename codomain_type_of<RightT>::type RightCodomainT;
return
if_<
bool_<is_concept_equivalent<is_element_map,LeftT,RightT>::value>,
map_codomain_compare<LeftT,RightT>,
empty_codomain_compare<LeftT,RightT>
>
::type::apply(left,right);
}
int restrict_result(int state) { return _result &= state; }
int next_both(LeftIterT& left, RightIterT& right)
{
if(left == _left_end && right == _right_end)
return stop;
else if(left == _left_end)
{
restrict_result(subset);
return stop;
}
else if(right == _right_end)
{
restrict_result(superset);
return stop;
}
else if(typename LeftT::key_compare()(key_value<LeftT>(left), key_value<RightT>(right)))
{ // left: *left . . *joint_ left could be superset
// right: *right ... if joint_ exists
restrict_result(superset);
if(unrelated == _result)
return stop;
else
{
LeftIterT joint_ = _left.lower_bound(key_value<RightT>(right));
if( joint_ == _left.end()
|| typename LeftT::key_compare()(key_value<RightT>(right), key_value<LeftT>(joint_)))
{
_result = unrelated;
return stop;
}
else
left = joint_;
}
}
else if(typename LeftT::key_compare()(key_value<RightT>(right), key_value<LeftT>(left)))
{ // left: *left left could be subset
// right:*right . . .*joint_ if *joint_ exists
restrict_result(subset);
if(unrelated == _result)
return stop;
else
{
RightIterT joint_ = _right.lower_bound(key_value<LeftT>(left));
if( joint_ == _right.end()
|| typename LeftT::key_compare()(key_value<LeftT>(left), key_value<RightT>(joint_)))
{
_result = unrelated;
return stop;
}
else
right = joint_;
}
}
// left =key= right
if(_compare_codomain)
if(unrelated == restrict_result(co_compare(left,right)))
return stop;
++left;
++right;
return nextboth;
}
private:
const LeftT& _left;
const RightT& _right;
LeftIterT _left_end;
RightIterT _right_end;
int _result;
};
//------------------------------------------------------------------------------
// Subset/superset comparison on ranges of two interval container
//------------------------------------------------------------------------------
template<class LeftT, class RightT>
int subset_compare
(
const LeftT& left, //sub
const RightT& right, //super
typename LeftT::const_iterator left_begin,
typename LeftT::const_iterator left_end,
typename RightT::const_iterator right_begin,
typename RightT::const_iterator right_end
)
{
typedef subset_comparer<LeftT,RightT> Step;
Step step(left, right, left_end, right_end);
typename LeftT::const_iterator left_ = left_begin;
typename RightT::const_iterator right_ = right_begin;
int state = Step::nextboth;
while(state != Step::stop)
state = step.next_both(left_, right_);
return step.result();
}
template<class LeftT, class RightT>
int subset_compare(const LeftT& left, const RightT& right)
{
return subset_compare
(
left, right,
left.begin(), left.end(),
right.begin(), right.end()
);
}
} // namespace Set
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}} // namespace icl boost
#endif