#ifndef theplu_yat_utility_segment_set
#define theplu_yat_utility_segment_set
// $Id: SegmentSet.h 2820 2012-08-30 00:47:58Z peter $
/*
Copyright (C) 2010 Peter Johansson
Copyright (C) 2012 Jari Häkkinen
This file is part of the yat library, http://dev.thep.lu.se/yat
The yat library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
The yat library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with yat. If not, see .
*/
#include "Segment.h"
#include "SegmentTree.h"
#include "stl_utility.h"
#include "yat_assert.h"
#include
#include
namespace theplu {
namespace yat {
namespace utility {
/**
\brief a set of Segments
A container that holds a set of Segment. The Segments cannot overlap.
\since new in yat 0.7
*/
template >
class SegmentSet
: public SegmentTree,
SegmentCompare >,
Compare,
Identity&> >
{
typedef SegmentSet me;
public:
/**
\brief creates a set with no segments
*/
SegmentSet(void) {}
/**
insert \a segment into set. If there is no gap between \a
segment and neighboring segments the segments are merged.
*/
typename me::const_iterator
insert_merge(const typename me::value_type& segment)
{
std::pair p =
this->overlap_range(segment);
if (p.first==p.second) { // no overlap between set and segment
return this->container_.insert(p.first, segment);
}
/*
p.first last p.second
---> ---> ---> --->
----------------------->
segment
*/
Compare comp;
typename me::iterator last=p.second;
YAT_ASSERT(last==this->end() || compare(segment, *last));
YAT_ASSERT(last!=this->begin()); // last!=p.first
--last;
YAT_ASSERT(compare_3way(segment, *last)==0);
Segment segment2(std::min(p.first->begin(),
segment.begin(), comp),
std::max(last->end(), segment.end(), comp));
this->container_.erase(p.first, p.second);
// FIXME: use a better hint than end()
return this->container_.insert(this->end(), segment2);
}
private:
// using compiler generated copying
//SegmentSet(const SegmentSet&);
//SegmentSet& operator=(const SegmentSet&);
};
}}}
#endif