I’ve started work with boost:icl library which is really comprehensive and convenient. I’m using mostly two types of intervals from boost, boost::icl::interval_set and boost::icl::interval_map. Some times I have to manipulate with just interval part of both types, and I don’t interesting in doing replicate functions.
So here is my example:
template<typename T>
void UniqSegmentsInA(T &a,T &b,T &c,int max_gap=200)
{
typename T::iterator __it1 = a.begin();
typename T::iterator __it2 = b.begin();
bool _checking_=true;
while(__it1 != a.end() && __it2 != b.end())
{
typename T::interval_type __itv1 = getFirst(*__it1);
typename T::interval_type __itv2 = getFirst(*__it2);
if(__itv1.upper()>__itv2.upper())
{
/*if segments intersect and we should move second segment then segment A should not be included in output*/
if(intersects(T::interval_type::closed(__itv1.lower()-max_gap,__itv1.upper()+max_gap),__itv2)) _checking_=false;
__it2++;
}
else
{
if(!intersects(T::interval_type::closed(__itv1.lower()-max_gap,__itv1.upper()+max_gap),__itv2) && _checking_)
{
c.add((*__it1));
}
_checking_=true;
__it1++;
}
}
if(__it1 != a.end() && !_checking_) __it1++;
while(__it1 != a.end())
{
c.add(*__it1);
__it1++;
}
}
getFirst() is a helper function when it is a map then it returns .first when it is a set then just an iterator.
bicl::interval_map<int,int>::interval_type inline getFirst(bicl::interval_map<int,int>::segment_type a)
{
return a.first;
}
bicl::interval_set<int>::interval_type inline getFirst(bicl::interval_set<int>::segment_type a)
{
return a;
}
So this example works like expected. What I want to improve is getFirst() function and I don’t want hardcode types of domain and codomain in interval_map/set. I’ve tried something like this:
template<typename T>
typename bicl::interval_map<T,T>::interval_type inline getFirst(typename bicl::interval_map<T,T>::segment_type a)
{
return a.first;
}
Then I changed:
typename T::interval_type __itv1 = getFirst<typename T::domain_type>(*__it1);
typename T::interval_type __itv2 = getFirst<typename T::domain_type>(*__it2);
but it does not work and compiler gives an error:
src/Intersections.cpp:324:35: error: no matching function for call to ‘getFirst(const std::pair<const boost::icl::discrete_interval<int, std::less>, int>&)’
src/Intersections.cpp:324:35: note: candidates are:
src/Intersections.cpp:52:56: note: template<class T> typename boost::icl::interval_map<T, T>::interval_type getFirst(typename boost::icl::interval_map<T, T>::segment_type)
src/Intersections.cpp:57:56: note: boost::icl::interval_set<int>::interval_type getFirst(boost::icl::interval_set<int>::segment_type)
src/Intersections.cpp:57:56: note: no known conversion for argument 1 from ‘const std::pair<const boost::icl::discrete_interval<int, std::less>, int>’ to ‘boost::icl::interval_set<int>::segment_type {aka boost::icl::discrete_interval<int, std::less>}’
So question is, is it possible in this example do not hardcode domain and codomain types in getFirst() function?
Thanks,
Andrey
You can use the function template
for that purpose. It is defined in
like this