Skip to content

Commit

Permalink
[dimension] adds overload for indexOf(start, end, ...
Browse files Browse the repository at this point in the history
which now takes takes (optionally) the ticks, and the RangeMatch arg
to control inclusive or exclusive range matching
  • Loading branch information
jgrewe committed May 7, 2020
1 parent 23b1483 commit f2eba0b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
20 changes: 20 additions & 0 deletions include/nix/Dimensions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,26 @@ class NIXAPI RangeDimension : public base::ImplContainer<base::IRangeDimension>
boost::optional<ndsize_t> indexOf(const double position, PositionMatch matching) const;


/**
* @brief Returns the start and end index of the given start and end
* positions. By default, the range includes the end position. This can be
* controlled via the RangeMatch enum.
*
*
* @param start The start position
* @param end The end position
* @param ticks std::vector<double> of ticks, if empty ({}) they are automatically retrieved
* @param range RangeMatch enum, controls whether end is included or not,
* defaults to RangeMatch::Inclusive
*
* @return Start and end indices returned in a boost::optional<std::pair>
* which is invalid if out of range.
*/
boost::optional<std::pair<ndsize_t, ndsize_t>> indexOf(double start, double end,
std::vector<double> ticks,
RangeMatch match = RangeMatch::Inclusive) const;


/**
* @brief Returns the index of the given position
*
Expand Down
41 changes: 24 additions & 17 deletions src/Dimensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,24 +404,7 @@ PositionInRange RangeDimension::positionInRange(const double position) const {
}


ndsize_t getIndex(const double position, std::vector<double> &ticks, bool lower_bound) {
if (position < *ticks.begin()) {
return 0;
} else if (position > *prev(ticks.end())) {
return prev(ticks.end()) - ticks.begin();
}
ndsize_t index;
if (lower_bound) {
std::vector<double>::iterator lower = std::lower_bound(ticks.begin(), ticks.end(), position);
index = lower - ticks.begin();
} else{
std::vector<double>::iterator upper = std::upper_bound(ticks.begin(), ticks.end(), position) - 1;
index = upper - ticks.begin();
}
return index;
}


boost::optional<ndsize_t> getIndex(const double position, std::vector<double> &ticks, PositionMatch matching) {
boost::optional<ndsize_t> idx;
// check easy cases first ...
Expand Down Expand Up @@ -475,6 +458,30 @@ boost::optional<ndsize_t> RangeDimension::indexOf(const double position, Positio
}


boost::optional<std::pair<ndsize_t, ndsize_t>> RangeDimension::indexOf(double start, double end,
std::vector<double> ticks,
RangeMatch match) const {
if (ticks.size() == 0) {
ticks = this->ticks();
}
boost::optional<std::pair<ndsize_t, ndsize_t>> range;
if (start > end){
std::swap(start, end);
}

boost::optional<ndsize_t> si = getIndex(start, ticks, PositionMatch::GreaterOrEqual);
if (!si) {
return range;
}
PositionMatch endMatching = (match == RangeMatch::Inclusive) ? PositionMatch::LessOrEqual : PositionMatch::Less;
boost::optional<ndsize_t> ei = getIndex(end, ticks, endMatching);
if (ei && *si <= *ei) {
range = std::pair<ndsize_t, ndsize_t>(*si, *ei);
}
return range;
}


ndsize_t RangeDimension::indexOf(const double position, bool less_or_equal) const {
vector<double> ticks = this->ticks();
PositionMatch matching = less_or_equal ? PositionMatch::LessOrEqual : PositionMatch::GreaterOrEqual;
Expand Down

0 comments on commit f2eba0b

Please sign in to comment.