summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-07-15 20:27:30 +0200
committerAraq <rumpf_a@web.de>2014-07-15 20:27:30 +0200
commit0251c081f69ee7e2814e08b657751a7c5bd93d1a (patch)
treebf9e7595e982a24ec793990d2874040bc724222f
parentc14e7565f8a3ef49568ea4f9d13a68b3fb54efb3 (diff)
parente0404609436eafdd7da79166fdb88a09d4f16451 (diff)
downloadNim-0251c081f69ee7e2814e08b657751a7c5bd93d1a.tar.gz
Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
-rw-r--r--lib/pure/algorithm.nim14
-rw-r--r--lib/pure/collections/sets.nim11
-rw-r--r--lib/pure/complex.nim39
-rw-r--r--lib/pure/os.nim80
-rw-r--r--lib/pure/strutils.nim8
-rw-r--r--tests/sets/tsets3.nim21
-rw-r--r--web/news.txt1
7 files changed, 161 insertions, 13 deletions
diff --git a/lib/pure/algorithm.nim b/lib/pure/algorithm.nim
index 86d329763..89c83a8a4 100644
--- a/lib/pure/algorithm.nim
+++ b/lib/pure/algorithm.nim
@@ -34,6 +34,20 @@ proc reverse*[T](a: var openArray[T]) =
   ## reverses the array `a`.
   reverse(a, 0, a.high)
 
+proc reversed*[T](a: openArray[T], first, last: int): seq[T] =
+  ## returns the reverse of the array `a[first..last]`.
+  result = newSeq[T](last - first + 1)
+  var x = first
+  var y = last
+  while x <= last:
+    result[x] = a[y]
+    dec(y)
+    inc(x)
+
+proc reversed*[T](a: openArray[T]): seq[T] =
+  ## returns the reverse of the array `a`.
+  reversed(a, 0, a.high)
+
 proc binarySearch*[T](a: openArray[T], key: T): int =
   ## binary search for `key` in `a`. Returns -1 if not found.
   var b = len(a)
diff --git a/lib/pure/collections/sets.nim b/lib/pure/collections/sets.nim
index 4ba67cb2e..f1eed0004 100644
--- a/lib/pure/collections/sets.nim
+++ b/lib/pure/collections/sets.nim
@@ -167,6 +167,13 @@ proc intersection*[A](s1, s2: TSet[A]): TSet[A] =
   for item in s1:
     if item in s2: incl(result, item)
 
+proc difference*[A](s1, s2: TSet[A]): TSet[A] =
+  ## returns a new set of all items that are contained in `s1`, but not in `s2`
+  result = initSet[A]()
+  for item in s1:
+    if not contains(s2, item):
+      incl(result, item)
+
 proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] =
   ## returns a new set of all items that are contained in either
   ## `s1` or `s2`, but not both
@@ -182,6 +189,10 @@ proc `*`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
   ## alias for `intersection`
   result = intersection(s1, s2)
 
+proc `-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
+  ## alias for `difference`
+  result = difference(s1, s2)
+
 proc `-+-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
   ## alias for `symmetricDifference`
   result = symmetricDifference(s1, s2)
diff --git a/lib/pure/complex.nim b/lib/pure/complex.nim
index df08ace72..1392b73aa 100644
--- a/lib/pure/complex.nim
+++ b/lib/pure/complex.nim
@@ -113,6 +113,45 @@ proc `*` *(x: TComplex, y: float): TComplex =
   result.im = x.im * y
 
 
+proc `+=` *(x: var TComplex, y: TComplex) =
+  ## Add `y` to `x`.
+  x.re += y.re
+  x.im += y.im
+
+proc `+=` *(x: var TComplex, y: float) =
+  ## Add `y` to the complex number `x`.
+  x.re += y
+
+proc `-=` *(x: var TComplex, y: TComplex) =
+  ## Subtract `y` from `x`.
+  x.re -= y.re
+  x.im -= y.im
+
+proc `-=` *(x: var TComplex, y: float) =
+  ## Subtract `y` from the complex number `x`.
+  x.re -= y
+
+proc `*=` *(x: var TComplex, y: TComplex) =
+  ## Multiply `y` to `x`.
+  let im = x.im * y.re + x.re * y.im
+  x.re = x.re * y.re - x.im * y.im
+  x.im = im
+
+proc `*=` *(x: var TComplex, y: float) =
+  ## Multiply `y` to the complex number `x`.
+  x.re *= y
+  x.im *= y
+
+proc `/=` *(x: var TComplex, y: TComplex) =
+  ## Divide `x` by `y` in place.
+  x = x / y
+
+proc `/=` *(x : var TComplex, y: float) =
+  ## Divide complex `x` by float `y` in place.
+  x.re /= y
+  x.im /= y
+
+
 proc abs*(z: TComplex): float =
   ## Return the distance from (0,0) to `z`.
 
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 0b4538abc..380c9e6e7 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1560,7 +1560,52 @@ proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} =
   when defined(windows): return string(getEnv("TEMP")) & "\\"
   else: return "/tmp/"
 
-when defined(windows):
+when defined(nimdoc):
+  # Common forward declaration docstring block for parameter retrieval procs.
+  proc paramCount*(): int {.tags: [FReadIO].} =
+    ## Returns the number of `command line arguments`:idx: given to the
+    ## application.
+    ##
+    ## If your binary was called without parameters this will return zero.  You
+    ## can later query each individual paramater with `paramStr() <#paramStr>`_
+    ## or retrieve all of them in one go with `commandLineParams()
+    ## <#commandLineParams>`_.
+    ##
+    ## **Availability**: On Posix there is no portable way to get the command
+    ## line from a DLL and thus the proc isn't defined in this environment. You
+    ## can test for its availability with `defined() <system.html#defined>`_.
+    ## Example:
+    ##
+    ## .. code-block:: nimrod
+    ##   when defined(paramCount):
+    ##     # Use paramCount() here
+    ##   else:
+    ##     # Do something else!
+
+  proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} =
+    ## Returns the `i`-th `command line argument`:idx: given to the application.
+    ##
+    ## `i` should be in the range `1..paramCount()`, the `EInvalidIndex`
+    ## exception will be raised for invalid values.  Instead of iterating over
+    ## `paramCount() <#paramCount>`_ with this proc you can call the
+    ## convenience `commandLineParams() <#commandLineParams>`_.
+    ##
+    ## It is possible to call ``paramStr(0)`` but this will return OS specific
+    ## contents (usually the name of the invoked executable). You should avoid
+    ## this and call `getAppFilename() <#getAppFilename>`_ instead.
+    ##
+    ## **Availability**: On Posix there is no portable way to get the command
+    ## line from a DLL and thus the proc isn't defined in this environment. You
+    ## can test for its availability with `defined() <system.html#defined>`_.
+    ## Example:
+    ##
+    ## .. code-block:: nimrod
+    ##   when defined(paramStr):
+    ##     # Use paramStr() here
+    ##   else:
+    ##     # Do something else!
+
+elif defined(windows):
   # Since we support GUI applications with Nimrod, we sometimes generate
   # a WinMain entry proc. But a WinMain proc has no access to the parsed
   # command line arguments. The way to get them differs. Thus we parse them
@@ -1570,18 +1615,13 @@ when defined(windows):
     ownArgv {.threadvar.}: seq[string]
 
   proc paramCount*(): int {.rtl, extern: "nos$1", tags: [FReadIO].} =
-    ## Returns the number of `command line arguments`:idx: given to the
-    ## application.
+    # Docstring in nimdoc block.
     if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
     result = ownArgv.len-1
 
   proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1",
     tags: [FReadIO].} =
-    ## Returns the `i`-th `command line argument`:idx: given to the
-    ## application.
-    ##
-    ## `i` should be in the range `1..paramCount()`, else
-    ## the `EOutOfIndex` exception is raised.
+    # Docstring in nimdoc block.
     if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
     return TaintedString(ownArgv[i])
 
@@ -1592,13 +1632,31 @@ elif not defined(createNimRtl):
     cmdLine {.importc: "cmdLine".}: cstringArray
 
   proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} =
-    if i < cmdCount and i >= 0: return TaintedString($cmdLine[i])
+    # Docstring in nimdoc block.
+    if i < cmdCount and i >= 0: result = TaintedString($cmdLine[i])
     raise newException(EInvalidIndex, "invalid index")
 
-  proc paramCount*(): int {.tags: [FReadIO].} = return cmdCount-1
+  proc paramCount*(): int {.tags: [FReadIO].} =
+    # Docstring in nimdoc block.
+    result = cmdCount-1
 
-when defined(paramCount):
+when defined(paramCount) or defined(nimdoc):
   proc commandLineParams*(): seq[TaintedString] =
+    ## Convenience proc which returns the command line parameters.
+    ##
+    ## This returns **only** the parameters. If you want to get the application
+    ## executable filename, call `getAppFilename() <#getAppFilename>`_.
+    ##
+    ## **Availability**: On Posix there is no portable way to get the command
+    ## line from a DLL and thus the proc isn't defined in this environment. You
+    ## can test for its availability with `defined() <system.html#defined>`_.
+    ## Example:
+    ##
+    ## .. code-block:: nimrod
+    ##   when defined(commandLineParams):
+    ##     # Use commandLineParams() here
+    ##   else:
+    ##     # Do something else!
     result = @[]
     for i in 1..paramCount():
       result.add(paramStr(i))
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim
index e642f6a99..51392ba50 100644
--- a/lib/pure/strutils.nim
+++ b/lib/pure/strutils.nim
@@ -535,7 +535,12 @@ proc wordWrap*(s: string, maxLineWidth = 80,
   ## word wraps `s`.
   result = newStringOfCap(s.len + s.len shr 6)
   var spaceLeft = maxLineWidth
+  var lastSep = ""
   for word, isSep in tokenize(s, seps):
+    if isSep:
+      lastSep = word
+      spaceLeft = spaceLeft - len(word)
+      continue
     if len(word) > spaceLeft:
       if splitLongWords and len(word) > maxLineWidth:
         result.add(substr(word, 0, spaceLeft-1))
@@ -554,7 +559,8 @@ proc wordWrap*(s: string, maxLineWidth = 80,
         result.add(word)
     else:
       spaceLeft = spaceLeft - len(word)
-      result.add(word)
+      result.add(lastSep & word)
+      lastSep.setLen(0)
 
 proc unindent*(s: string, eatAllIndent = false): string {.
                noSideEffect, rtl, extern: "nsuUnindent".} =
diff --git a/tests/sets/tsets3.nim b/tests/sets/tsets3.nim
index d2b15d72d..f599f8e7d 100644
--- a/tests/sets/tsets3.nim
+++ b/tests/sets/tsets3.nim
@@ -74,8 +74,27 @@ block symmetricDifference:
   assert((s3 -+- s3) == initSet[int]())
   assert((s3 -+- s1) == s1_s3)
 
+block difference:
+  let
+    s1_s2 = difference(s1, s2)
+    s1_s3 = difference(s1, s3)
+    s2_s3 = s2 - s3
+
+  assert s1_s2.len == 2
+  assert s1_s3.len == 5
+  assert s2_s3.len == 3
+
+  for i in s1:
+    assert i in s1_s2 xor i in s2
+    assert i in s1_s3 xor i in s3
+  for i in s2:
+    assert i in s2_s3 xor i in s3
+
+  assert((s2 - s2) == initSet[int]())
+  assert((s1 - s3 - s1) == s1 -+- s3)
+
 block disjoint:
   assert(not disjoint(s1, s2))
   assert disjoint(s1, s3)
   assert(not disjoint(s2, s3))
-  assert(not disjoint(s2, s2))
\ No newline at end of file
+  assert(not disjoint(s2, s2))
diff --git a/web/news.txt b/web/news.txt
index aa91a83c4..a8d525443 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -24,6 +24,7 @@ News
   - Added module ``cpuinfo``.
   - Added module ``threadpool``.
   - ``sequtils.distnct`` has been renamed to ``sequtils.deduplicate``.
+  - Added ``algorithm.reversed``
 
 
 2014-04-21 Version 0.9.4 released