Created
May 20, 2014 00:41
-
-
Save flaviut/7f2a831516301ff0f890 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import exceptions | |
template checkBounds(idx, min, max: int) = | |
when not defined(release): | |
if idx < min or idx > max: | |
raiseException(errOutOfBounds, idx, min, max) | |
# TBuffer {{{ | |
type | |
TUncheckedArray {.unchecked.} [T] = array[0 .. 0, T] | |
TBuffer {.unchecked.} [T] = ref object | |
cap: int | |
data: TUncheckedArray[T] | |
proc newBufferRaw*[T](capacity: int): TBuffer[T] = | |
## Creates a new buffer with capacity `capacity`. Contents are undefined | |
result = TBuffer[T](cap: capacity, | |
data: cast[TUncheckedArray[T]]( | |
alloc(capacity * sizeof(T)))) | |
proc newBuffer*[T](capacity: int): TBuffer[T] = | |
## Creates a new zero-initialized buffer with capacity `capacity` | |
result = TBuffer[T](cap: capacity, | |
data: cast[TUncheckedArray[T]]( | |
alloc0(capacity * sizeof(T)))) | |
proc newBuffer*[IDX, T](arr: array[IDX, T]): TBuffer[T] = | |
result = newBufferRaw[T](len array) | |
for i, elem in arr: | |
result[i] = elem | |
proc `[]`*[T](arr: TBuffer[T], idx: int): T = | |
checkBounds(idx, 0, arr.cap-1) | |
result = arr.data[idx] | |
proc `[]=`*[T](arr: TBuffer[T], idx: int, val: T) = | |
checkBounds(idx, 0, arr.cap-1) | |
arr.data[idx] = val | |
proc copy*[T](arr: TBuffer[T]): TBuffer[T] = | |
let newPointer = alloc(sizeof[T] * arr.cap) | |
copyMem(newPointer, addr arr.data, sizeof[T] * arr.cap) | |
result = TBuffer(cap: arr.cap, data: cast[array[0..0, T]](newPointer)) | |
proc copy*[T](arr: TBuffer[T], first, last: int): TBuffer[T] = | |
## Copies the elements from `first`, inclusive, to `last`, exclusive | |
## For example, | |
## ``` {.testable, lang: "Nimrod".} | |
## | |
## ``` | |
discard | |
# }}} | |
# String {{{ | |
type | |
TFString = object | |
## No-bullshit, zero-terminated string type | |
## | |
## - Immutable (copy on write) | |
## - O(1) substrings | |
## - Created with FString("Foo") | |
low, high: int | |
str: TBuffer[char] | |
proc newFString*(size: int): TFString = | |
## Creates a new string with the given capacity | |
result = TFString(low: 0, | |
high: size, | |
str: newBuffer[char](size+1)) | |
proc `[]`*(a: TFString, idx: int): char = | |
## Returns the character at `idx`. | |
## Takes O(1) time | |
checkBounds(idx, a.low, a.high-1) | |
result = a.str[idx + a.low] | |
proc `[]=`*(a: TFString, idx: int, val: char): string = | |
## Returns a copy of the string with the character at `idx` replaced | |
## Takes O(N) time | |
checkBounds(idx, a.low, a.high-1) | |
proc FString*(s: string): TFString = | |
result = TFString(low: 0, | |
high: len s, | |
str: newBufferRaw[char](len(s)+1)) | |
for i, c in s: | |
result.str[i] = c | |
proc len*(s: TFString): int = | |
result = s.high - s.low | |
proc substr*(s: TFString, fromIdx, untilIdx: Natural): TFString = | |
## Takes a substring of `s` from `fromIdx` to `untilIdx`; `fromIdx` is | |
## inclusive, while `untilIdx` exclusive. | |
## Takes O(1) time | |
result = TFString(low: s.low + fromIdx, | |
high: s.high + untilIdx, | |
str: s.str) | |
iterator items*(s: TFString): char = | |
## Iterates through each character in the string | |
for i in 0 .. len(s)-1: | |
yield s[i] | |
iterator pairs*(s: TFString): tuple[i: int, c: char] = | |
## Iterates through each index and character in the string | |
for i in 0 .. len(s)-1: | |
yield (i, s[i]) | |
proc `==`*(a, b: TFString): bool = | |
## Determines if the two strings are equal. Not suitable for crypto purposes, | |
## it returns as soon as possible. | |
## Takes O(N) time | |
## ``` {.testable, lang: "Nimrod".} | |
## | |
## ``` | |
result = true | |
if a.low != b.low or | |
a.high != b.high or | |
a.str == b.str: | |
return false | |
for i, c in a: | |
if c != b[i]: | |
return false | |
# }}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment