summaryrefslogtreecommitdiff
path: root/zen/stl_tools.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/stl_tools.h')
-rw-r--r--zen/stl_tools.h37
1 files changed, 19 insertions, 18 deletions
diff --git a/zen/stl_tools.h b/zen/stl_tools.h
index 2726a09d..66af8551 100644
--- a/zen/stl_tools.h
+++ b/zen/stl_tools.h
@@ -68,10 +68,10 @@ template <class Iterator, class T, class CompLess>
Iterator binarySearch(Iterator first, Iterator last, const T& value, CompLess less);
//read-only variant of std::merge; input: two sorted ranges
-template <class Iterator, class FunctionLeftOnly, class FunctionBoth, class FunctionRightOnly>
+template <class Iterator, class FunctionLeftOnly, class FunctionBoth, class FunctionRightOnly, class Compare>
void mergeTraversal(Iterator first1, Iterator last1,
Iterator first2, Iterator last2,
- FunctionLeftOnly lo, FunctionBoth bo, FunctionRightOnly ro);
+ FunctionLeftOnly lo, FunctionBoth bo, FunctionRightOnly ro, Compare compare);
//why, oh why is there no std::optional<T>::get()???
template <class T> inline T* get( std::optional<T>& opt) { return opt ? &*opt : nullptr; }
@@ -255,31 +255,32 @@ BidirectionalIterator1 searchLast(const BidirectionalIterator1 first1, Bid
//---------------------------------------------------------------------------------------
//read-only variant of std::merge; input: two sorted ranges
-template <class Iterator, class FunctionLeftOnly, class FunctionBoth, class FunctionRightOnly> inline
-void mergeTraversal(Iterator first1, Iterator last1,
- Iterator first2, Iterator last2,
- FunctionLeftOnly lo, FunctionBoth bo, FunctionRightOnly ro)
+template <class Iterator, class FunctionLeftOnly, class FunctionBoth, class FunctionRightOnly, class Compare> inline
+void mergeTraversal(Iterator firstL, Iterator lastL,
+ Iterator firstR, Iterator lastR,
+ FunctionLeftOnly lo, FunctionBoth bo, FunctionRightOnly ro, Compare compare)
{
- auto itL = first1;
- auto itR = first2;
+ auto itL = firstL;
+ auto itR = firstR;
- auto finishLeft = [&] { std::for_each(itL, last1, lo); };
- auto finishRight = [&] { std::for_each(itR, last2, ro); };
+ auto finishLeft = [&] { std::for_each(itL, lastL, lo); };
+ auto finishRight = [&] { std::for_each(itR, lastR, ro); };
- if (itL == last1) return finishRight();
- if (itR == last2) return finishLeft ();
+ if (itL == lastL) return finishRight();
+ if (itR == lastR) return finishLeft ();
for (;;)
- if (itL->first < itR->first)
+ if (const std::weak_ordering cmp = compare(*itL, *itR);
+ cmp < 0)
{
lo(*itL);
- if (++itL == last1)
+ if (++itL == lastL)
return finishRight();
}
- else if (itR->first < itL->first)
+ else if (cmp > 0)
{
ro(*itR);
- if (++itR == last2)
+ if (++itR == lastR)
return finishLeft();
}
else
@@ -287,8 +288,8 @@ void mergeTraversal(Iterator first1, Iterator last1,
bo(*itL, *itR);
++itL; //
++itR; //increment BOTH before checking for end of range!
- if (itL == last1) return finishRight();
- if (itR == last2) return finishLeft ();
+ if (itL == lastL) return finishRight();
+ if (itR == lastR) return finishLeft ();
//simplify loop by placing both EOB checks at the beginning? => slightly slower
}
}
bgstack15