summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorpqflx3 <jamestodd@protonmail.com>2018-10-09 11:25:25 +0000
committerAndreas Rumpf <rumpf_a@web.de>2018-10-09 13:25:25 +0200
commitb90b45b01bba1f3fc241a96abd4ae5c8c314bb92 (patch)
tree65b35fb0134346dd31c0d9c3a51a777e5bc81305
parentbc557e4c6abcfe2909a7e7edfa000211aab14e4c (diff)
downloadNim-b90b45b01bba1f3fc241a96abd4ae5c8c314bb92.tar.gz
Add algorithm.[sort,sorted,isSorted] overloads using 'system.cmp'. (#8778)
* Add algorithm.[sort,sorted,isSorted] overloads using 'system.cmp'. Fixes 8684.

* Change signatures to 'func'. Improve overload sort doc comments
-rw-r--r--lib/pure/algorithm.nim38
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 81badfae6..aea005ff1 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -227,7 +227,7 @@ proc merge[T](a, b: var openArray[T], lo, m, hi: int,
   else:
     if k < j: copyMem(addr(a[k]), addr(b[i]), sizeof(T)*(j-k))
 
-proc sort*[T](a: var openArray[T],
+func sort*[T](a: var openArray[T],
               cmp: proc (x, y: T): int {.closure.},
               order = SortOrder.Ascending) =
   ## Default Nim sort (an implementation of merge sort). The sorting
@@ -235,9 +235,9 @@ proc sort*[T](a: var openArray[T],
   ## be O(n log n).
   ## The current implementation uses an iterative
   ## mergesort to achieve this. It uses a temporary sequence of
-  ## length ``a.len div 2``. Currently Nim does not support a
-  ## sensible default argument for ``cmp``, so you have to provide one
-  ## of your own. However, the ``system.cmp`` procs can be used:
+  ## length ``a.len div 2``. If you do not wish to provide your own
+  ## ``cmp``, you may use ``system.cmp`` or instead call the overloaded
+  ## version of ``sort``, which uses ``system.cmp``.
   ##
   ## .. code-block:: nim
   ##
@@ -267,14 +267,31 @@ proc sort*[T](a: var openArray[T],
       dec(m, s*2)
     s = s*2
 
-proc sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.},
+func sort*[T](a: var openArray[T], order = SortOrder.Ascending) =
+  ## Sort an openarray in-place with a default lexicographical ordering.
+  runnableExamples:
+    var s = @[1,3,2,5,4]
+    s.sort
+    doAssert a == @[1,2,3,4,5]
+  sort(a, system.cmp, order)
+
+func sorted*[T](a: openArray[T], cmp: proc(x, y: T): int {.closure.},
                 order = SortOrder.Ascending): seq[T] =
-  ## returns `a` sorted by `cmp` in the specified `order`.
+  ## Returns `a` sorted by `cmp` in the specified `order`.
   result = newSeq[T](a.len)
   for i in 0 .. a.high:
     result[i] = a[i]
   sort(result, cmp, order)
 
+func sorted*[T](a: openArray[T], order = SortOrder.Ascending): seq[T] =
+  ## Returns `a` sorted with default lexicographical ordering
+  runnableExamples:
+    let orig = @[2,3,1,2]
+    let copy = orig.sorted()
+    doAssert orig == @[2,3,1,2]
+    doAssert copy == @[1,2,2,3]
+  return sorted(a, system.cmp, order)
+
 template sortedByIt*(seq1, op: untyped): untyped =
   ## Convenience template around the ``sorted`` proc to reduce typing.
   ##
@@ -308,7 +325,7 @@ template sortedByIt*(seq1, op: untyped): untyped =
     result = cmp(a, b))
   result
 
-proc isSorted*[T](a: openarray[T],
+func isSorted*[T](a: openArray[T],
                  cmp: proc(x, y: T): int {.closure.},
                  order = SortOrder.Ascending): bool =
   ## Checks to see whether `a` is already sorted in `order`
@@ -319,6 +336,13 @@ proc isSorted*[T](a: openarray[T],
     if cmp(a[i],a[i+1]) * order > 0:
       return false
 
+func isSorted*[T](a: openArray[T], order = SortOrder.Ascending): bool =
+  ## Checks whether `a` is sorted with a default lexicographical ordering
+  runnableExamples:
+    let test = @[1,1,2,3,5,8]
+    doAssert test.isSorted()
+  result = isSorted(a, system.cmp, order)
+
 proc product*[T](x: openArray[seq[T]]): seq[seq[T]] =
   ## produces the Cartesian product of the array. Warning: complexity
   ## may explode.