16 template <
class Scalar,
typename Value>
23 : start(
std::min(s, e))
24 , stop(
std::max(s, e))
28 template <
class Scalar,
typename Value>
33 template <
class Scalar,
typename Value>
38 template <
class Scalar,
typename Value>
39 std::ostream& operator<<(std::ostream& out, const Interval<Scalar, Value>& i) {
40 out <<
"Interval(" << i.start <<
", " << i.stop <<
"): " << i.value;
44 template <
class Scalar,
class Value>
69 std::unique_ptr<IntervalTree>
clone()
const {
70 return std::unique_ptr<IntervalTree>(
new IntervalTree(*
this));
74 : intervals(other.intervals)
91 std::size_t maxbucket = 512, Scalar leftextent = 0, Scalar rightextent = 0)
95 const auto minmaxStop = std::minmax_element(ivals.begin(), ivals.end(), IntervalStopCmp());
96 const auto minmaxStart = std::minmax_element(ivals.begin(), ivals.end(), IntervalStartCmp());
98 center = (minmaxStart.first->start + minmaxStop.second->stop) / 2;
100 if (leftextent == 0 && rightextent == 0) {
102 std::sort(ivals.begin(), ivals.end(), IntervalStartCmp());
104 assert(std::is_sorted(ivals.begin(), ivals.end(), IntervalStartCmp()));
106 if (depth == 0 || (ivals.size() < minbucket && ivals.size() < maxbucket)) {
107 std::sort(ivals.begin(), ivals.end(), IntervalStartCmp());
115 if (leftextent || rightextent) {
117 rightp = rightextent;
119 leftp = ivals.front().start;
120 rightp = std::max_element(ivals.begin(), ivals.end(), IntervalStopCmp())->
stop;
126 for (
typename interval_vector::const_iterator i = ivals.begin(); i != ivals.end(); ++i) {
129 lefts.push_back(interval);
131 rights.push_back(interval);
135 intervals.push_back(interval);
139 if (!lefts.empty()) {
142 if (!rights.empty()) {
151 template <
class UnaryFunction>
153 if (!intervals.empty() && !(stop < intervals.front().start)) {
154 for (
auto& i : intervals) {
159 left->visit_near(start, stop, f);
162 right->visit_near(start, stop, f);
167 template <
class UnaryFunction>
169 visit_overlapping(pos, pos, f);
173 template <
class UnaryFunction>
181 visit_near(start, stop, filterF);
185 template <
class UnaryFunction>
192 visit_near(start, stop, filterF);
198 result.emplace_back(interval);
206 result.push_back(interval);
215 if (!intervals.empty()) {
224 template <
class UnaryFunction>
235 std::pair<Scalar, Scalar>
extent()
const {
237 std::pair<Scalar, Scalar>
x{std::numeric_limits<Scalar>::max(),
238 std::numeric_limits<Scalar>::min()};
240 x.first = std::min(
x.first, interval.
start);
241 x.second = std::max(
x.second, interval.
stop);
254 std::pair<bool, std::pair<Scalar, Scalar>>
is_valid()
const {
255 const auto minmaxStop =
256 std::minmax_element(intervals.begin(), intervals.end(), IntervalStopCmp());
257 const auto minmaxStart =
258 std::minmax_element(intervals.begin(), intervals.end(), IntervalStartCmp());
260 std::pair<bool, std::pair<Scalar, Scalar>>
result = {
261 true, {std::numeric_limits<Scalar>::max(), std::numeric_limits<Scalar>::min()}};
262 if (!intervals.empty()) {
263 result.second.first = std::min(result.second.first, minmaxStart.first->start);
264 result.second.second = std::min(result.second.second, minmaxStop.second->stop);
267 auto valid =
left->is_valid();
268 result.first &= valid.first;
269 result.second.first = std::min(result.second.first, valid.second.first);
270 result.second.second = std::min(result.second.second, valid.second.second);
274 if (valid.second.second >=
center) {
275 result.first =
false;
280 auto valid =
right->is_valid();
281 result.first &= valid.first;
282 result.second.first = std::min(result.second.first, valid.second.first);
283 result.second.second = std::min(result.second.second, valid.second.second);
287 if (valid.second.first <=
center) {
288 result.first =
false;
292 if (!std::is_sorted(intervals.begin(), intervals.end(), IntervalStartCmp())) {
293 result.first =
false;
300 std::unique_ptr<IntervalTree>
left;
301 std::unique_ptr<IntervalTree>
right;
std::unique_ptr< IntervalTree > left
bool operator()(const interval &a, const interval &b)
span_CONFIG_SIZE_TYPE size_t
IntervalTree & operator=(const IntervalTree &other)
interval_vector find_overlapping(const Scalar &start, const Scalar &stop) const
std::pair< Scalar, Scalar > extent() const
std::vector< interval > interval_vector
Value intervalStop(const Interval< Scalar, Value > &i)
void visit_overlapping(const Scalar &pos, UnaryFunction f) const
#define assert(condition)
void for_each(index_sequence< Is... >, Tuple &&tup, F &&f) FMT_NOEXCEPT
static int sort(lua_State *L)
IntervalTree(const IntervalTree &other)
IntervalTree(interval_vector &&ivals, std::size_t depth=16, std::size_t minbucket=64, std::size_t maxbucket=512, Scalar leftextent=0, Scalar rightextent=0)
void visit_all(UnaryFunction f) const
std::pair< bool, std::pair< Scalar, Scalar > > is_valid() const
const T & move(const T &v)
bool operator()(const interval &a, const interval &b)
const T & first(const T &value, const Tail &...)
void visit_overlapping(const Scalar &start, const Scalar &stop, UnaryFunction f) const
void visit_near(const Scalar &start, const Scalar &stop, UnaryFunction f) const
Value intervalStart(const Interval< Scalar, Value > &i)
std::unique_ptr< IntervalTree > clone() const
interval_vector find_contained(const Scalar &start, const Scalar &stop) const
interval_vector intervals
void visit_contained(const Scalar &start, const Scalar &stop, UnaryFunction f) const
Interval(const Scalar &s, const Scalar &e, const Value &v)
std::unique_ptr< IntervalTree > right