From 70d3573b9af6bdff64f261141ad87648a63f9404 Mon Sep 17 00:00:00 2001
From: Dmitri Naumov <github@naumov.de>
Date: Wed, 23 May 2018 13:29:38 +0200
Subject: [PATCH] [BL] Generalize quick sort to input iterators.

---
 BaseLib/quicksort.h | 48 ++++++++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 20 deletions(-)

diff --git a/BaseLib/quicksort.h b/BaseLib/quicksort.h
index eb3da1c9096..2bfb66e377a 100644
--- a/BaseLib/quicksort.h
+++ b/BaseLib/quicksort.h
@@ -20,37 +20,45 @@
 namespace BaseLib
 {
 
-/// @pre {end<=array.size() and perm.size()==array.size()}
-template <typename T1, typename T2 = std::size_t>
-void quicksort(T1* array, std::size_t beg, std::size_t end, T2* perm)
+/// @pre {first1 <= last1 and the second iterator can be incremented
+/// distance(first1, last1) times}
+template <typename It1, typename It2>
+void quicksort(It1 first1, It1 last1, It2 first2)
 {
-    assert (beg <= end);
+    using T1 = typename std::iterator_traits<It1>::value_type;
+    using T2 = typename std::iterator_traits<It2>::value_type;
 
-    // Zip input arrays.
     std::vector<std::pair<T1, T2>> data;
-    data.reserve(end-beg);
-    std::transform(array+beg, array+end, perm+beg,
-        std::back_inserter(data),
-        [](T1 const& t1, T2 const& t2)
-        {
-            return std::make_pair(t1, t2);
-        });
+    data.reserve(std::distance(first1, last1));
+    std::transform(
+        first1, last1, first2, std::back_inserter(data),
+        [](T1 const& t1, T2 const& t2) { return std::make_pair(t1, t2); });
 
     // Sort data using first element of the pair.
-    std::sort(data.begin(), data.end(),
-        [](std::pair<T1, T2> const& a, std::pair<T1, T2> const& b)
-        {
-            return (a.first < b.first);
-        });
+    std::sort(begin(data), end(data),
+              [](std::pair<T1, T2> const& a, std::pair<T1, T2> const& b) {
+                  return (a.first < b.first);
+              });
 
     // Unzip sorted data.
-    for (std::size_t i = 0; i < data.size(); i++)
+    for (auto const& pair : data)
     {
-        array[beg+i] = data[i].first;
-        perm[beg+i] = data[i].second;
+        *first1 = pair.first;
+        *first2 = pair.second;
+        ++first1;
+        ++first2;
     }
 }
 
+/// @pre {end<=array.size() and perm.size()==array.size()}
+template <typename T1, typename T2 = std::size_t>
+void quicksort(T1* array, std::size_t beg, std::size_t end, T2* perm)
+{
+    assert(beg <= end);
+
+    quicksort(array + beg, array + end, perm + beg);
+}
+
 template <typename T1, typename T2 = std::size_t>
 void quicksort(std::vector<T1>& array, std::size_t beg, std::size_t end, std::vector<T2>& perm)
 {
-- 
GitLab