Add free FindIndex/FindIndexIf and use it. NFC.

These are generic and work with List and IdList,
as well as vector<> and raw arrays.
pull/460/head
Ryan Pavlik 2019-08-20 15:32:43 -05:00
parent 64c0f62b92
commit e2281adc78
6 changed files with 79 additions and 72 deletions

View File

@ -544,6 +544,42 @@ public:
};
// Uniform API for FindIndex
template<typename ContainerType, typename ValueType>
inline int FindIndex(const ContainerType &container, const ValueType &val) {
using std::begin;
using std::end;
const auto b = begin(container);
const auto e = end(container);
auto it = std::find(b, e, val);
if(it == e) {
// Not found, so return negative to indicate that.
return -1;
}
return std::distance(b, it);
}
// Overload for IdList.
template<typename ValueType, typename HandleType>
inline int FindIndex(const IdList<ValueType, HandleType> &container, const HandleType &handle) {
return container.IndexOf(handle);
}
// Uniform API for FindIndexIf
template<typename ContainerType, typename PredType>
inline int FindIndexIf(const ContainerType &container, PredType &&predicate) {
using std::begin;
using std::end;
const auto b = begin(container);
const auto e = end(container);
auto it = std::find_if(b, e, std::forward<PredType &&>(predicate));
if(it == e) {
// Not found, so return negative to indicate that.
return -1;
}
return std::distance(b, it);
}
class BandedMatrix {
public:
enum {

View File

@ -140,25 +140,17 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
[](const hGroup &ha, const hGroup &hb) {
return SK.GetGroup(ha)->order < SK.GetGroup(hb)->order;
});
switch(type) {
case Generate::DIRTY: {
first = INT_MAX;
last = 0;
// Start from the first dirty group, and solve until the active group,
// since all groups after the active group are hidden.
// Not using range-for because we're tracking the indices.
for(i = 0; i < SK.groupOrder.n; i++) {
Group *g = SK.GetGroup(SK.groupOrder[i]);
if((!g->clean) || !g->IsSolvedOkay()) {
first = min(first, i);
}
if(g->h == SS.GW.activeGroup) {
last = i;
}
}
if(first == INT_MAX || last == 0) {
first = FindIndexIf(SK.groupOrder, [](hGroup const &hg) {
Group *g = SK.GetGroup(hg);
return (!g->clean) || !g->IsSolvedOkay();
});
last = FindIndex(SK.groupOrder, SS.GW.activeGroup);
if(first < 0 || last < 0) {
// All clean; so just regenerate the entities, and don't solve anything.
first = -1;
last = -1;
@ -179,13 +171,11 @@ void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox)
break;
case Generate::UNTIL_ACTIVE: {
for(i = 0; i < SK.groupOrder.n; i++) {
if(SK.groupOrder[i] == SS.GW.activeGroup)
break;
}
first = 0;
last = i;
last = FindIndex(SK.groupOrder, SS.GW.activeGroup);
if(last < 0) {
last = SK.groupOrder.n;
}
break;
}
}

View File

@ -1267,23 +1267,20 @@ public:
}
std::string GetExtension() {
auto filters = gtkChooser->list_filters();
size_t filterIndex =
std::find(filters.begin(), filters.end(), gtkChooser->get_filter()) -
filters.begin();
if(filterIndex < extensions.size()) {
auto filters = gtkChooser->list_filters();
int filterIndex = FindIndex(filters, gtkChooser->get_filter());
if(filterIndex >= 0 && filterIndex < extensions.size()) {
return extensions[filterIndex];
} else {
return extensions.front();
}
}
void SetExtension(std::string extension) {
auto filters = gtkChooser->list_filters();
size_t extensionIndex =
std::find(extensions.begin(), extensions.end(), extension) -
extensions.begin();
if(extensionIndex < filters.size()) {
auto filters = gtkChooser->list_filters();
int extensionIndex = FindIndex(extensions, extension);
if(extensionIndex >= 0 && extensionIndex < filters.size()) {
gtkChooser->set_filter(filters[extensionIndex]);
} else {
gtkChooser->set_filter(filters.front());

View File

@ -313,17 +313,17 @@ int SEdgeList::AnyEdgeCrossings(Vector a, Vector b, Vector *ppi, SPointList *spl
// an endpoint with one of our edges.
//-----------------------------------------------------------------------------
bool SEdgeList::ContainsEdgeFrom(const SEdgeList *sel) const {
for(const SEdge *se = l.First(); se; se = l.NextAfter(se)) {
if(sel->ContainsEdge(se)) return true;
}
return false;
auto i = FindIndexIf(l, [&](const SEdge &se) { return sel->ContainsEdge(&se); });
// did we find one?
return i >= 0;
}
bool SEdgeList::ContainsEdge(const SEdge *set) const {
for(const SEdge *se = l.First(); se; se = l.NextAfter(se)) {
if((se->a).Equals(set->a) && (se->b).Equals(set->b)) return true;
if((se->b).Equals(set->a) && (se->a).Equals(set->b)) return true;
}
return false;
auto i = FindIndexIf(l, [&](const SEdge &se) {
return ((se.a).Equals(set->a) && (se.b).Equals(set->b)) ||
((se.b).Equals(set->a) && (se.a).Equals(set->b));
});
// did we find one?
return i >= 0;
}
//-----------------------------------------------------------------------------
@ -524,29 +524,19 @@ bool SPointList::ContainsPoint(Vector pt) const {
}
int SPointList::IndexForPoint(Vector pt) const {
int i;
for(i = 0; i < l.n; i++) {
const SPoint *p = &(l[i]);
if(pt.Equals(p->p)) {
return i;
}
}
// Not found, so return negative to indicate that.
return -1;
return FindIndexIf(l, [&](SPoint const &p) { return pt.Equals(p.p); });
}
void SPointList::IncrementTagFor(Vector pt) {
SPoint *p;
for(p = l.First(); p; p = l.NextAfter(p)) {
if(pt.Equals(p->p)) {
(p->tag)++;
return;
}
int i = IndexForPoint(pt);
if(i < 0) {
SPoint pa;
pa.p = pt;
pa.tag = 1;
l.Add(&pa);
} else {
l[i].tag++;
}
SPoint pa;
pa.p = pt;
pa.tag = 1;
l.Add(&pa);
}
void SPointList::Add(Vector pt) {

View File

@ -319,15 +319,12 @@ void SurfaceRenderer::OutputInPaintOrder() {
int aZIndex = a.second,
bZIndex = b.second;
size_t aLayerIndex =
std::find(std::begin(stackup), std::end(stackup), aLayer) - std::begin(stackup);
size_t bLayerIndex =
std::find(std::begin(stackup), std::end(stackup), bLayer) - std::begin(stackup);
auto aLayerIndex = FindIndex(stackup, aLayer);
auto bLayerIndex = FindIndex(stackup, bLayer);
if(aLayerIndex == bLayerIndex) {
return aZIndex < bZIndex;
} else {
return aLayerIndex < bLayerIndex;
}
return aLayerIndex < bLayerIndex;
});
auto last = std::unique(paintOrder.begin(), paintOrder.end());

View File

@ -924,15 +924,12 @@ struct CompareDrawCall {
Canvas::Layer::FRONT
};
int aLayerIndex =
std::find(std::begin(stackup), std::end(stackup), a->GetLayer()) - std::begin(stackup);
int bLayerIndex =
std::find(std::begin(stackup), std::end(stackup), b->GetLayer()) - std::begin(stackup);
int aLayerIndex = FindIndex(stackup, a->GetLayer());
int bLayerIndex = FindIndex(stackup, b->GetLayer());
if(aLayerIndex == bLayerIndex) {
return a->GetZIndex() < b->GetZIndex();
} else {
return aLayerIndex < bLayerIndex;
}
return aLayerIndex < bLayerIndex;
}
};