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 { class BandedMatrix {
public: public:
enum { enum {

View File

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

View File

@ -1267,23 +1267,20 @@ public:
} }
std::string GetExtension() { std::string GetExtension() {
auto filters = gtkChooser->list_filters(); auto filters = gtkChooser->list_filters();
size_t filterIndex = int filterIndex = FindIndex(filters, gtkChooser->get_filter());
std::find(filters.begin(), filters.end(), gtkChooser->get_filter()) -
filters.begin(); if(filterIndex >= 0 && filterIndex < extensions.size()) {
if(filterIndex < extensions.size()) {
return extensions[filterIndex]; return extensions[filterIndex];
} else { } else {
return extensions.front(); return extensions.front();
} }
} }
void SetExtension(std::string extension) { void SetExtension(std::string extension) {
auto filters = gtkChooser->list_filters(); auto filters = gtkChooser->list_filters();
size_t extensionIndex = int extensionIndex = FindIndex(extensions, extension);
std::find(extensions.begin(), extensions.end(), extension) -
extensions.begin(); if(extensionIndex >= 0 && extensionIndex < filters.size()) {
if(extensionIndex < filters.size()) {
gtkChooser->set_filter(filters[extensionIndex]); gtkChooser->set_filter(filters[extensionIndex]);
} else { } else {
gtkChooser->set_filter(filters.front()); 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. // an endpoint with one of our edges.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool SEdgeList::ContainsEdgeFrom(const SEdgeList *sel) const { bool SEdgeList::ContainsEdgeFrom(const SEdgeList *sel) const {
for(const SEdge *se = l.First(); se; se = l.NextAfter(se)) { auto i = FindIndexIf(l, [&](const SEdge &se) { return sel->ContainsEdge(&se); });
if(sel->ContainsEdge(se)) return true; // did we find one?
} return i >= 0;
return false;
} }
bool SEdgeList::ContainsEdge(const SEdge *set) const { bool SEdgeList::ContainsEdge(const SEdge *set) const {
for(const SEdge *se = l.First(); se; se = l.NextAfter(se)) { auto i = FindIndexIf(l, [&](const SEdge &se) {
if((se->a).Equals(set->a) && (se->b).Equals(set->b)) return true; return ((se.a).Equals(set->a) && (se.b).Equals(set->b)) ||
if((se->b).Equals(set->a) && (se->a).Equals(set->b)) return true; ((se.b).Equals(set->a) && (se.a).Equals(set->b));
} });
return false; // did we find one?
return i >= 0;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -524,29 +524,19 @@ bool SPointList::ContainsPoint(Vector pt) const {
} }
int SPointList::IndexForPoint(Vector pt) const { int SPointList::IndexForPoint(Vector pt) const {
int i; return FindIndexIf(l, [&](SPoint const &p) { return pt.Equals(p.p); });
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;
} }
void SPointList::IncrementTagFor(Vector pt) { void SPointList::IncrementTagFor(Vector pt) {
SPoint *p; int i = IndexForPoint(pt);
for(p = l.First(); p; p = l.NextAfter(p)) { if(i < 0) {
if(pt.Equals(p->p)) { SPoint pa;
(p->tag)++; pa.p = pt;
return; 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) { void SPointList::Add(Vector pt) {

View File

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

View File

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