Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
This commit is contained in:
commit
0251c081f6
7 changed files with 161 additions and 13 deletions
|
|
@ -34,6 +34,20 @@ proc reverse*[T](a: var openArray[T]) =
|
||||||
## reverses the array `a`.
|
## reverses the array `a`.
|
||||||
reverse(a, 0, a.high)
|
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 =
|
proc binarySearch*[T](a: openArray[T], key: T): int =
|
||||||
## binary search for `key` in `a`. Returns -1 if not found.
|
## binary search for `key` in `a`. Returns -1 if not found.
|
||||||
var b = len(a)
|
var b = len(a)
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,13 @@ proc intersection*[A](s1, s2: TSet[A]): TSet[A] =
|
||||||
for item in s1:
|
for item in s1:
|
||||||
if item in s2: incl(result, item)
|
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] =
|
proc symmetricDifference*[A](s1, s2: TSet[A]): TSet[A] =
|
||||||
## returns a new set of all items that are contained in either
|
## returns a new set of all items that are contained in either
|
||||||
## `s1` or `s2`, but not both
|
## `s1` or `s2`, but not both
|
||||||
|
|
@ -182,6 +189,10 @@ proc `*`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
|
||||||
## alias for `intersection`
|
## alias for `intersection`
|
||||||
result = intersection(s1, s2)
|
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.} =
|
proc `-+-`*[A](s1, s2: TSet[A]): TSet[A] {.inline.} =
|
||||||
## alias for `symmetricDifference`
|
## alias for `symmetricDifference`
|
||||||
result = symmetricDifference(s1, s2)
|
result = symmetricDifference(s1, s2)
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,45 @@ proc `*` *(x: TComplex, y: float): TComplex =
|
||||||
result.im = x.im * y
|
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 =
|
proc abs*(z: TComplex): float =
|
||||||
## Return the distance from (0,0) to `z`.
|
## Return the distance from (0,0) to `z`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1560,7 +1560,52 @@ proc getTempDir*(): string {.rtl, extern: "nos$1", tags: [FReadEnv].} =
|
||||||
when defined(windows): return string(getEnv("TEMP")) & "\\"
|
when defined(windows): return string(getEnv("TEMP")) & "\\"
|
||||||
else: return "/tmp/"
|
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
|
# Since we support GUI applications with Nimrod, we sometimes generate
|
||||||
# a WinMain entry proc. But a WinMain proc has no access to the parsed
|
# 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
|
# command line arguments. The way to get them differs. Thus we parse them
|
||||||
|
|
@ -1570,18 +1615,13 @@ when defined(windows):
|
||||||
ownArgv {.threadvar.}: seq[string]
|
ownArgv {.threadvar.}: seq[string]
|
||||||
|
|
||||||
proc paramCount*(): int {.rtl, extern: "nos$1", tags: [FReadIO].} =
|
proc paramCount*(): int {.rtl, extern: "nos$1", tags: [FReadIO].} =
|
||||||
## Returns the number of `command line arguments`:idx: given to the
|
# Docstring in nimdoc block.
|
||||||
## application.
|
|
||||||
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
|
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
|
||||||
result = ownArgv.len-1
|
result = ownArgv.len-1
|
||||||
|
|
||||||
proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1",
|
proc paramStr*(i: int): TaintedString {.rtl, extern: "nos$1",
|
||||||
tags: [FReadIO].} =
|
tags: [FReadIO].} =
|
||||||
## Returns the `i`-th `command line argument`:idx: given to the
|
# Docstring in nimdoc block.
|
||||||
## application.
|
|
||||||
##
|
|
||||||
## `i` should be in the range `1..paramCount()`, else
|
|
||||||
## the `EOutOfIndex` exception is raised.
|
|
||||||
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
|
if isNil(ownArgv): ownArgv = parseCmdLine($getCommandLine())
|
||||||
return TaintedString(ownArgv[i])
|
return TaintedString(ownArgv[i])
|
||||||
|
|
||||||
|
|
@ -1592,13 +1632,31 @@ elif not defined(createNimRtl):
|
||||||
cmdLine {.importc: "cmdLine".}: cstringArray
|
cmdLine {.importc: "cmdLine".}: cstringArray
|
||||||
|
|
||||||
proc paramStr*(i: int): TaintedString {.tags: [FReadIO].} =
|
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")
|
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] =
|
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 = @[]
|
result = @[]
|
||||||
for i in 1..paramCount():
|
for i in 1..paramCount():
|
||||||
result.add(paramStr(i))
|
result.add(paramStr(i))
|
||||||
|
|
|
||||||
|
|
@ -535,7 +535,12 @@ proc wordWrap*(s: string, maxLineWidth = 80,
|
||||||
## word wraps `s`.
|
## word wraps `s`.
|
||||||
result = newStringOfCap(s.len + s.len shr 6)
|
result = newStringOfCap(s.len + s.len shr 6)
|
||||||
var spaceLeft = maxLineWidth
|
var spaceLeft = maxLineWidth
|
||||||
|
var lastSep = ""
|
||||||
for word, isSep in tokenize(s, seps):
|
for word, isSep in tokenize(s, seps):
|
||||||
|
if isSep:
|
||||||
|
lastSep = word
|
||||||
|
spaceLeft = spaceLeft - len(word)
|
||||||
|
continue
|
||||||
if len(word) > spaceLeft:
|
if len(word) > spaceLeft:
|
||||||
if splitLongWords and len(word) > maxLineWidth:
|
if splitLongWords and len(word) > maxLineWidth:
|
||||||
result.add(substr(word, 0, spaceLeft-1))
|
result.add(substr(word, 0, spaceLeft-1))
|
||||||
|
|
@ -554,7 +559,8 @@ proc wordWrap*(s: string, maxLineWidth = 80,
|
||||||
result.add(word)
|
result.add(word)
|
||||||
else:
|
else:
|
||||||
spaceLeft = spaceLeft - len(word)
|
spaceLeft = spaceLeft - len(word)
|
||||||
result.add(word)
|
result.add(lastSep & word)
|
||||||
|
lastSep.setLen(0)
|
||||||
|
|
||||||
proc unindent*(s: string, eatAllIndent = false): string {.
|
proc unindent*(s: string, eatAllIndent = false): string {.
|
||||||
noSideEffect, rtl, extern: "nsuUnindent".} =
|
noSideEffect, rtl, extern: "nsuUnindent".} =
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,25 @@ block symmetricDifference:
|
||||||
assert((s3 -+- s3) == initSet[int]())
|
assert((s3 -+- s3) == initSet[int]())
|
||||||
assert((s3 -+- s1) == s1_s3)
|
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:
|
block disjoint:
|
||||||
assert(not disjoint(s1, s2))
|
assert(not disjoint(s1, s2))
|
||||||
assert disjoint(s1, s3)
|
assert disjoint(s1, s3)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ News
|
||||||
- Added module ``cpuinfo``.
|
- Added module ``cpuinfo``.
|
||||||
- Added module ``threadpool``.
|
- Added module ``threadpool``.
|
||||||
- ``sequtils.distnct`` has been renamed to ``sequtils.deduplicate``.
|
- ``sequtils.distnct`` has been renamed to ``sequtils.deduplicate``.
|
||||||
|
- Added ``algorithm.reversed``
|
||||||
|
|
||||||
|
|
||||||
2014-04-21 Version 0.9.4 released
|
2014-04-21 Version 0.9.4 released
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue