Leaving out mark type will search for next/previous of any type

This commit is based on work by Ronald Wampler.
This commit is contained in:
Allan Odgaard
2016-02-25 13:11:12 +07:00
parent 42b6c04089
commit e80f1ff49f

View File

@@ -39,32 +39,49 @@ namespace ng
std::pair<size_t, std::string> marks_t::next (size_t index, std::string const& markType) const
{
std::map<std::string, tree_t>::const_iterator m = _marks.find(markType);
if(m == _marks.end())
return std::pair<size_t, std::string>(0, NULL_STR);
auto from = markType == NULL_STR ? _marks.begin() : _marks.lower_bound(markType);
auto to = markType == NULL_STR ? _marks.end() : _marks.upper_bound(markType);
if(m->second.size() == 0)
return std::pair<size_t, std::string>(0, NULL_STR);
else if(m->second.size() == 1)
return *m->second.begin();
std::vector<std::pair<size_t, std::string>> candidates;
for(auto m = from; m != to; ++m)
{
if(m->second.empty())
continue;
tree_t::iterator it = m->second.upper_bound(index);
return *(it == m->second.end() ? m->second.begin() : it);
auto it = m->second.upper_bound(index);
candidates.push_back(it == m->second.end() ? *(m->second.begin()) : *it);
}
if(candidates.empty())
return std::make_pair(0, NULL_STR);
else if(candidates.size() == 1)
return candidates.front();
std::sort(candidates.begin(), candidates.end());
auto it = std::upper_bound(candidates.begin(), candidates.end(), index, [](size_t index, std::pair<size_t, std::string> const& mark){ return mark.first > index; });
return it == candidates.end() ? candidates.front() : *it;
}
std::pair<size_t, std::string> marks_t::prev (size_t index, std::string const& markType) const
{
std::map<std::string, tree_t>::const_iterator m = _marks.find(markType);
if(m == _marks.end())
return std::pair<size_t, std::string>(0, NULL_STR);
auto from = markType == NULL_STR ? _marks.begin() : _marks.lower_bound(markType);
auto to = markType == NULL_STR ? _marks.end() : _marks.upper_bound(markType);
if(m->second.size() == 0)
return std::pair<size_t, std::string>(0, NULL_STR);
else if(m->second.size() == 1)
return *m->second.begin();
std::vector<std::pair<size_t, std::string>> candidates;
for(auto m = from; m != to; ++m)
{
if(m->second.empty())
continue;
tree_t::iterator it = m->second.lower_bound(index);
return *(--(it == m->second.begin() ? m->second.end() : it));
auto it = m->second.lower_bound(index);
candidates.push_back(*(--(it == m->second.begin() ? m->second.end() : it)));
}
std::sort(candidates.begin(), candidates.end());
auto it = std::lower_bound(candidates.begin(), candidates.end(), index, [](std::pair<size_t, std::string> const& mark, size_t index){ return mark.first < index; });
return *(--(it == candidates.begin() ? candidates.end() : it));
}
std::multimap<size_t, std::pair<std::string, std::string>> marks_t::get_range (size_t from, size_t to) const