diff --git a/stew/base10.nim b/stew/base10.nim index 39de452..aa6c3b2 100644 --- a/stew/base10.nim +++ b/stew/base10.nim @@ -1,4 +1,4 @@ -## Copyright (c) 2021-2023 Status Research & Development GmbH +## Copyright (c) 2021-2024 Status Research & Development GmbH ## Licensed under either of ## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) ## * MIT license ([LICENSE-MIT](LICENSE-MIT)) @@ -10,7 +10,7 @@ ## ## Encoding procedures are adopted versions of C functions described here: ## # https://www.facebook.com/notes/facebook-engineering/three-optimization-tips-for-c/10151361643253920 -import results +import pkg/results export results {.push raises: [].} @@ -39,7 +39,7 @@ type data*: array[maxLen(Base10, T), byte] len*: int8 # >= 1 when holding valid unsigned integer -proc decode*[A: byte|char, T: SomeUnsignedInt]( +func decode*[A: byte|char, T: SomeUnsignedInt]( B: typedesc[Base10], t: typedesc[T], src: openArray[A]): Result[T, cstring] = ## Convert base10 encoded string or array of bytes to unsigned integer. @@ -62,7 +62,7 @@ proc decode*[A: byte|char, T: SomeUnsignedInt]( v = (v shl 3) + (v shl 1) + T(d) ok(v) -proc encodedLength*(B: typedesc[Base10], value: SomeUnsignedInt): int8 = +func encodedLength*(B: typedesc[Base10], value: SomeUnsignedInt): int8 = ## Procedure returns number of characters needed to encode integer ``value``. when type(value) is uint8: if value < 10'u8: @@ -132,7 +132,7 @@ proc encodedLength*(B: typedesc[Base10], value: SomeUnsignedInt): int8 = return 11'i8 + (if value >= P11: 1'i8 else: 0) return 12'i8 + B.encodedLength(value div P12) -proc encode[A: byte|char](B: typedesc[Base10], value: SomeUnsignedInt, +func encode[A: byte|char](B: typedesc[Base10], value: SomeUnsignedInt, output: var openArray[A], length: int8): Result[int8, cstring] = const Digits = cstring( @@ -175,25 +175,25 @@ proc encode[A: byte|char](B: typedesc[Base10], value: SomeUnsignedInt, output[next - 1] = byte(Digits[index]) ok(length) -proc encode*[A: byte|char](B: typedesc[Base10], value: SomeUnsignedInt, +func encode*[A: byte|char](B: typedesc[Base10], value: SomeUnsignedInt, output: var openArray[A]): Result[int8, cstring] = ## Encode integer value to array of characters or bytes. B.encode(value, output, B.encodedLength(value)) -proc toString*(B: typedesc[Base10], value: SomeUnsignedInt): string = +func toString*(B: typedesc[Base10], value: SomeUnsignedInt): string = ## Encode integer value ``value`` to string. var buf = newString(B.encodedLength(value)) # Buffer of proper size is allocated, so error is not possible discard B.encode(value, buf, int8(len(buf))) buf -proc toBytes*[I: SomeUnsignedInt](B: typedesc[Base10], v: I): Base10Buf[I] {. +func toBytes*[I: SomeUnsignedInt](B: typedesc[Base10], v: I): Base10Buf[I] {. noinit.} = ## Encode integer value ``value`` to array of bytes. let res = B.encode(v, result.data, B.encodedLength(v)) result.len = int8(res.get()) -proc toBytes*[I: SomeUnsignedInt](v: I, B: typedesc[Base10]): Base10Buf[I] {. +func toBytes*[I: SomeUnsignedInt](v: I, B: typedesc[Base10]): Base10Buf[I] {. noinit.} = ## Encode integer value ``value`` to array of bytes. let res = B.encode(v, result.data, B.encodedLength(v)) diff --git a/stew/interval_set.nim b/stew/interval_set.nim index 298165c..0f4045b 100644 --- a/stew/interval_set.nim +++ b/stew/interval_set.nim @@ -1,6 +1,6 @@ # Nimbus - Types, data structures and shared utilities used in network sync # -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -108,11 +108,12 @@ ## isomorpic to a subclass of `S`. ## -import - "."/[results, sorted_set] - {.push raises: [].} +import + pkg/results, + "."/sorted_set + export `isRed=`, `linkLeft=`, @@ -282,25 +283,25 @@ template scalarOne(): untyped = ## the value `1` from the scalar data type (S.default + 1) -proc blk[P,S](kvp: DataRef[P,S]): BlockRef[S] = +func blk[P,S](kvp: DataRef[P,S]): BlockRef[S] = kvp.data -proc left[P,S](kvp: DataRef[P,S]): P = +func left[P,S](kvp: DataRef[P,S]): P = kvp.key -proc right[P,S](kvp: DataRef[P,S]): P = +func right[P,S](kvp: DataRef[P,S]): P = kvp.key + kvp.blk.size -proc len[P,S](kvp: DataRef[P,S]): S = +func len[P,S](kvp: DataRef[P,S]): S = kvp.data.size # ----- -proc new[P,S](T: type Segm[P,S]; left, right: P): T = +func new[P,S](T: type Segm[P,S]; left, right: P): T = ## Constructor using `[left,right)` points representation T(start: left, size: right - left) -proc brew[P,S](T: type Segm[P,S]; left, right: P): Result[T,void] = +func brew[P,S](T: type Segm[P,S]; left, right: P): Result[T,void] = ## Constructor providing `[left, max(left,right)-left)` (if any.) if high(P) <= left: return err() @@ -313,39 +314,39 @@ proc brew[P,S](T: type Segm[P,S]; left, right: P): Result[T,void] = (high(P) - left) ok(T(start: left, size: length)) -proc left[P,S](iv: Segm[P,S]): P = +func left[P,S](iv: Segm[P,S]): P = iv.start -proc right[P,S](iv: Segm[P,S]): P = +func right[P,S](iv: Segm[P,S]): P = iv.start + iv.size -proc len[P,S](iv: Segm[P,S]): S = +func len[P,S](iv: Segm[P,S]): S = iv.size # ------ -proc incPt[P,S](a: var P; n: S) = +func incPt[P,S](a: var P; n: S) = ## Might not be generally available for point `P` and scalar `S` a = a + n -proc maxPt[P](a, b: P): P = +func maxPt[P](a, b: P): P = ## Instead of max() which might not be generally available if a < b: b else: a -proc minPt[P](a, b: P): P = +func minPt[P](a, b: P): P = ## Instead of min() which might not be generally available if a < b: a else: b # ------ -proc new[P,S](T: type Interval[P,S]; kvp: DataRef[P,S]): T = +func new[P,S](T: type Interval[P,S]; kvp: DataRef[P,S]): T = T(least: kvp.left, last: kvp.right - scalarOne) # ------------------------------------------------------------------------------ # Private helpers # ------------------------------------------------------------------------------ -proc overlapOrLeftJoin[P,S](ds: Desc[P,S]; l, r: P): Rc[P,S] = +func overlapOrLeftJoin[P,S](ds: Desc[P,S]; l, r: P): Rc[P,S] = ## Find and return ## * either the rightmost interval `[a,b)` which overlaps `r` ## * or `[a,b)` with `b==l` @@ -358,11 +359,11 @@ proc overlapOrLeftJoin[P,S](ds: Desc[P,S]; l, r: P): Rc[P,S] = return ok(rc.value) err() -proc overlapOrLeftJoin[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Rc[P,S] = +func overlapOrLeftJoin[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Rc[P,S] = ds.overlapOrLeftJoin(iv.left, iv.right) -proc overlap[P,S](ds: Desc[P,S]; l, r: P): Rc[P,S] = +func overlap[P,S](ds: Desc[P,S]; l, r: P): Rc[P,S] = ## Find and return the rightmost `[l,r)` overlapping interval `[a,b)`. doAssert l < r let rc = ds.leftPos.lt(r) # search for `max(a) < r` @@ -373,14 +374,14 @@ proc overlap[P,S](ds: Desc[P,S]; l, r: P): Rc[P,S] = return ok(rc.value) err() -proc overlap[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Rc[P,S] = +func overlap[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Rc[P,S] = ds.overlap(iv.left, iv.right) # ------------------------------------------------------------------------------ # Private transfer function helpers # ------------------------------------------------------------------------------ -proc findInlet[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Segm[P,S] = +func findInlet[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Segm[P,S] = ## Find largest sub-segment of `iv` fully contained in another segment ## of the argument database. ## @@ -400,7 +401,7 @@ proc findInlet[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Segm[P,S] = Segm[P,S].new(maxPt(p.left,iv.left), minPt(p.right,iv.right)) -proc merge[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Segm[P,S] = +func merge[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Segm[P,S] = ## Merges argument interval into into database and returns ## the segment really added (if any) @@ -513,7 +514,7 @@ proc merge[P,S](ds: Desc[P,S]; iv: Segm[P,S]): Segm[P,S] = # s: [--------------) -proc deleteInlet[P,S](ds: Desc[P,S]; iv: Segm[P,S]) = +func deleteInlet[P,S](ds: Desc[P,S]; iv: Segm[P,S]) = ## Delete fully contained interval if not ds.isNil and 0 < iv.len: @@ -560,7 +561,7 @@ proc deleteInlet[P,S](ds: Desc[P,S]; iv: Segm[P,S]) = # Private transfer() function implementation for merge/reduce # ------------------------------------------------------------------------------ -proc transferImpl[P,S](src, trg: Desc[P,S]; iv: Segm[P,S]): S = +func transferImpl[P,S](src, trg: Desc[P,S]; iv: Segm[P,S]): S = ## From the `src` argument database, delete the data segment/interval ## `[start,start+length)` and merge it into the `trg` argument database. ## Not both arguments `src` and `trg` must be `nil`. @@ -592,7 +593,7 @@ proc transferImpl[P,S](src, trg: Desc[P,S]; iv: Segm[P,S]): S = # Private covered() function implementation # ------------------------------------------------------------------------------ -proc coveredImpl[P,S](ds: IntervalSetRef[P,S]; start: P; length: S): S = +func coveredImpl[P,S](ds: IntervalSetRef[P,S]; start: P; length: S): S = ## Calulate the accumulated size of the interval `[start,start+length)` ## covered by intervals in the set `ds`. The result cannot exceed the ## argument `length` (of course.) @@ -644,12 +645,12 @@ proc coveredImpl[P,S](ds: IntervalSetRef[P,S]; start: P; length: S): S = # Public constructor, clone, etc. # ------------------------------------------------------------------------------ -proc init*[P,S](T: type IntervalSetRef[P,S]): T = +func init*[P,S](T: type IntervalSetRef[P,S]): T = ## Interval set constructor. new result result.leftPos.init() -proc clone*[P,S](ds: IntervalSetRef[P,S]): IntervalSetRef[P,S] = +func clone*[P,S](ds: IntervalSetRef[P,S]): IntervalSetRef[P,S] = ## Return a copy of the interval list. Beware, this might be slow as it ## needs to copy every interval record. result = Desc[P,S].init() @@ -666,7 +667,7 @@ proc clone*[P,S](ds: IntervalSetRef[P,S]): IntervalSetRef[P,S] = # optional clean up, see comments on the destroy() directive walk.destroy -proc `==`*[P,S](a, b: IntervalSetRef[P,S]): bool = +func `==`*[P,S](a, b: IntervalSetRef[P,S]): bool = ## Compare interval sets for equality. Beware, this can be slow. Every ## interval record has to be checked. if a.ptsCount == b.ptsCount and @@ -686,13 +687,13 @@ proc `==`*[P,S](a, b: IntervalSetRef[P,S]): bool = # optional clean up, see comments on the destroy() directive aWalk.destroy() -proc clear*[P,S](ds: IntervalSetRef[P,S]) = +func clear*[P,S](ds: IntervalSetRef[P,S]) = ## Clear the interval set. ds.ptsCount = scalarZero ds.lastHigh = false ds.leftPos.clear() -proc new*[P,S](T: type Interval[P,S]; minPt, maxPt: P): T = +func new*[P,S](T: type Interval[P,S]; minPt, maxPt: P): T = ## Create interval `[minPt,max(minPt,maxPt)]` Interval[P,S](least: minPt, last: max(minPt, maxPt)) @@ -700,7 +701,7 @@ proc new*[P,S](T: type Interval[P,S]; minPt, maxPt: P): T = # Public interval operations add, remove, erc. # ------------------------------------------------------------------------------ -proc merge*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = +func merge*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = ## For the argument interval `I` implied as `[minPt,max(minPt,maxPt)]`, ## merge `I` with the intervals of the argument set `ds`. The function ## returns the accumulated number of points that were added to some @@ -720,12 +721,12 @@ proc merge*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = else: result = scalarZero -proc merge*[P,S](ds: IntervalSetRef[P,S]; iv: Interval[P,S]): S = +func merge*[P,S](ds: IntervalSetRef[P,S]; iv: Interval[P,S]): S = ## Variant of `merge()` ds.merge(iv.least, iv.last) -proc reduce*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = +func reduce*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = ## For the argument interval `I` implied as `[minPt,max(minPt,maxPt)]`, ## remove the points from `I` from intervals of the argument set `ds`. ## The function returns the accumulated number of elements removed (i.e. @@ -745,12 +746,12 @@ proc reduce*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = else: result = scalarZero -proc reduce*[P,S](ds: IntervalSetRef[P,S]; iv: Interval[P,S]): S = +func reduce*[P,S](ds: IntervalSetRef[P,S]; iv: Interval[P,S]): S = ## Variant of `reduce()` ds.reduce(iv.least, iv.last) -proc covered*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = +func covered*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = ## For the argument interval `I` implied as `[minPt,max(minPt,maxPt)]`, ## calulate the accumulated points `I` contained in some interval in the ## set `ds`. The return value is the same as that for `reduce()` (only @@ -765,12 +766,12 @@ proc covered*[P,S](ds: IntervalSetRef[P,S]; minPt, maxPt: P): S = else: result = scalarZero -proc covered*[P,S](ds: IntervalSetRef[P,S]; iv: Interval[P,S]): S = +func covered*[P,S](ds: IntervalSetRef[P,S]; iv: Interval[P,S]): S = ## Variant of `covered()` ds.covered(iv.least, iv.last) -proc ge*[P,S](ds: IntervalSetRef[P,S]; minPt: P): IntervalRc[P,S] = +func ge*[P,S](ds: IntervalSetRef[P,S]; minPt: P): IntervalRc[P,S] = ## Find smallest interval in the set `ds` with start point (i.e. minimal ## value in the interval as a set) greater or equal the argument `minPt`. let rc = ds.leftPos.ge(minPt) @@ -785,11 +786,11 @@ proc ge*[P,S](ds: IntervalSetRef[P,S]; minPt: P): IntervalRc[P,S] = return ok(Interval[P,S].new(high(P),high(P))) err() -proc ge*[P,S](ds: IntervalSetRef[P,S]): IntervalRc[P,S] = +func ge*[P,S](ds: IntervalSetRef[P,S]): IntervalRc[P,S] = ## Find the interval with the least elements of type `P` (if any.) ds.ge(low(P)) -proc le*[P,S](ds: IntervalSetRef[P,S]; maxPt: P): IntervalRc[P,S] = +func le*[P,S](ds: IntervalSetRef[P,S]; maxPt: P): IntervalRc[P,S] = ## Find largest interval in the set `ds` with end point (i.e. maximal ## value in the interval as a set) smaller or equal to the argument `maxPt`. let rc = ds.leftPos.le(maxPt) @@ -818,12 +819,12 @@ proc le*[P,S](ds: IntervalSetRef[P,S]; maxPt: P): IntervalRc[P,S] = return ok(Interval[P,S].new(high(P),high(P))) err() -proc le*[P,S](ds: IntervalSetRef[P,S]): IntervalRc[P,S] = +func le*[P,S](ds: IntervalSetRef[P,S]): IntervalRc[P,S] = ## Find the interval with the largest elements of type `P` (if any.) ds.le(high(P)) -proc envelope*[P,S](ds: IntervalSetRef[P,S]; pt: P): IntervalRc[P,S] = +func envelope*[P,S](ds: IntervalSetRef[P,S]; pt: P): IntervalRc[P,S] = ## Find the interval that contains the argument point `pt` (if any) let rc = ds.leftPos.le(pt) if rc.isOk: @@ -838,7 +839,7 @@ proc envelope*[P,S](ds: IntervalSetRef[P,S]; pt: P): IntervalRc[P,S] = err() -proc delete*[P,S](ds: IntervalSetRef[P,S]; minPt: P): IntervalRc[P,S] = +func delete*[P,S](ds: IntervalSetRef[P,S]; minPt: P): IntervalRc[P,S] = ## Find the interval `[minPt,maxPt]` for some point `maxPt` in the interval ## set `ds` and remove it from `ds`. The function returns the deleted ## interval (if any.) @@ -915,21 +916,21 @@ iterator decreasing*[P,S]( # Public interval operators # ------------------------------------------------------------------------------ -proc `==`*[P,S](iv, jv: Interval[P,S]): bool = +func `==`*[P,S](iv, jv: Interval[P,S]): bool = ## Compare intervals for equality iv.least == jv.least and iv.last == jv.last -proc `==`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): bool = +func `==`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): bool = ## Variant of `==` if iv.isOk: return iv.value == jv -proc `==`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): bool = +func `==`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): bool = ## Variant of `==` if jv.isOk: return iv == jv.value -proc `==`*[P,S](iv, jv: IntervalRc[P,S]): bool = +func `==`*[P,S](iv, jv: IntervalRc[P,S]): bool = ## Variant of `==` if iv.isOk: if jv.isOk: @@ -941,7 +942,7 @@ proc `==`*[P,S](iv, jv: IntervalRc[P,S]): bool = # ------ -proc `*`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = +func `*`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = ## Intersect itervals `iv` and `jv` if this operation results in a ## non-emty interval. Note that the `*` operation is associative, i.e. ## :: @@ -953,19 +954,19 @@ proc `*`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = maxPt(jv.least,iv.least), minPt(jv.last,iv.last))) err() -proc `*`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): IntervalRc[P,S] = +func `*`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): IntervalRc[P,S] = ## Variant of `*` if iv.isOk: return iv.value * jv err() -proc `*`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): IntervalRc[P,S] = +func `*`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): IntervalRc[P,S] = ## Variant of `*` if jv.isOk: return iv * jv.value err() -proc `*`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = +func `*`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = ## Variant of `*` if iv.isOk and jv.isOk: return iv.value * jv.value @@ -973,7 +974,7 @@ proc `*`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = # ------ -proc `+`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = +func `+`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = ## Merge intervals `iv` and `jv` if this operation results in an interval. ## Note that the `+` operation is *not* associative, i.e. ## :: @@ -997,19 +998,19 @@ proc `+`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = err() -proc `+`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): IntervalRc[P,S] = +func `+`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): IntervalRc[P,S] = ## Variant of `+` if iv.isOk: return iv.value + jv err() -proc `+`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): IntervalRc[P,S] = +func `+`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): IntervalRc[P,S] = ## Variant of `+` if jv.isOk: return iv + jv.value err() -proc `+`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = +func `+`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = ## Variant of `+` if iv.isOk and jv.isOk: return iv.value + jv.value @@ -1017,7 +1018,7 @@ proc `+`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = # ------ -proc `-`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = +func `-`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = ## Return the interval `iv` reduced by elements of `jv` if this operation ## results in a non-empty interval. ## Note that the `-` operation is *not* associative, i.e. @@ -1074,19 +1075,19 @@ proc `-`*[P,S](iv, jv: Interval[P,S]): IntervalRc[P,S] = err() -proc `-`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): IntervalRc[P,S] = +func `-`*[P,S](iv: IntervalRc[P,S]; jv: Interval[P,S]): IntervalRc[P,S] = ## Variant of `-` if iv.isOk: return iv.value - jv err() -proc `-`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): IntervalRc[P,S] = +func `-`*[P,S](iv: Interval[P,S]; jv: IntervalRc[P,S]): IntervalRc[P,S] = ## Variant of `-` if jv.isOk: return iv - jv.value err() -proc `-`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = +func `-`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = ## Variant of `-` if iv.isOk and jv.isOk: return iv.value - jv.valu @@ -1096,7 +1097,7 @@ proc `-`*[P,S](iv, jv: IntervalRc[P,S]): IntervalRc[P,S] = # Public getters # ------------------------------------------------------------------------------ -proc len*[P,S](iv: Interval[P,S]): S = +func len*[P,S](iv: Interval[P,S]): S = ## Cardinality (ie. length) of argument interval `iv`. If the argument ## interval `iv` is `[low(P),high(P)]`, the return value will be the scalar ## *zero* (there are no empty intervals in this implementation.) @@ -1105,15 +1106,15 @@ proc len*[P,S](iv: Interval[P,S]): S = else: (iv.last - iv.least) + scalarOne -proc minPt*[P,S](iv: Interval[P,S]): P = +func minPt*[P,S](iv: Interval[P,S]): P = ## Left end, smallest point of `P` contained in the interval iv.least -proc maxPt*[P,S](iv: Interval[P,S]): P = +func maxPt*[P,S](iv: Interval[P,S]): P = ## Right end, largest point of `P` contained in the interval iv.last -proc total*[P,S](ds: IntervalSetRef[P,S]): S = +func total*[P,S](ds: IntervalSetRef[P,S]): S = ## Accumulated size covered by intervals in the interval set `ds`. ## ## In the special case when there is only the single interval @@ -1126,7 +1127,7 @@ proc total*[P,S](ds: IntervalSetRef[P,S]): S = else: ds.ptsCount + scalarOne -proc chunks*[P,S](ds: IntervalSetRef[P,S]): int = +func chunks*[P,S](ds: IntervalSetRef[P,S]): int = ## Number of disjunkt intervals (aka chunks) in the interval set `ds`. result = ds.leftPos.len if ds.lastHigh: @@ -1138,7 +1139,7 @@ proc chunks*[P,S](ds: IntervalSetRef[P,S]): int = # Public debugging functions # ------------------------------------------------------------------------------ -proc `$`*[P,S](p: DataRef[P,S]): string = +func `$`*[P,S](p: DataRef[P,S]): string = ## Needed by `ds.verify()` for printing error messages "[" & $p.left & "," & $p.right & ")" diff --git a/stew/io.nim b/stew/io.nim index c21a254..5f8be33 100644 --- a/stew/io.nim +++ b/stew/io.nim @@ -1,3 +1,5 @@ +{.deprecated: "use https://nim-lang.org/docs/syncio.html#writeFile%2Cstring%2CopenArray%5Bbyte%5D directly".} + when not compiles(writeFile("filename", @[byte(1)])): proc writeFile*(filename: string, content: openArray[byte]) = ## Opens a file named `filename` for writing. Then writes the @@ -11,4 +13,3 @@ when not compiles(writeFile("filename", @[byte(1)])): close(f) else: raise newException(IOError, "cannot open: " & filename) - diff --git a/stew/io2.nim b/stew/io2.nim index 6cbc135..edf2940 100644 --- a/stew/io2.nim +++ b/stew/io2.nim @@ -1,4 +1,4 @@ -## Copyright (c) 2020-2023 Status Research & Development GmbH +## Copyright (c) 2020-2024 Status Research & Development GmbH ## Licensed under either of ## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) ## * MIT license ([LICENSE-MIT](LICENSE-MIT)) @@ -12,8 +12,8 @@ {.push raises: [].} -import algorithm -import results +import std/algorithm +import pkg/results export results when defined(windows): diff --git a/stew/keyed_queue.nim b/stew/keyed_queue.nim index 13ce8a7..4f9f0eb 100644 --- a/stew/keyed_queue.nim +++ b/stew/keyed_queue.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -22,12 +22,12 @@ ## semantics, this means that `=` performs a deep copy of the allocated queue ## which is refered to the deep copy semantics of the underlying table driver. -import std/tables, results +{.push raises: [].} + +import std/tables, pkg/results export results -{.push raises: [].} - type KeyedQueueItem*[K, V] = object ## Data value container as stored in the queue. diff --git a/stew/keyed_queue/kq_debug.nim b/stew/keyed_queue/kq_debug.nim index 353838e..f19e2d0 100644 --- a/stew/keyed_queue/kq_debug.nim +++ b/stew/keyed_queue/kq_debug.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -12,10 +12,12 @@ ## ============================= ## +{.push raises: [].} + import std/tables, - ../keyed_queue, - ../results + results, + ../keyed_queue type KeyedQueueInfo* = enum ##\ @@ -31,13 +33,11 @@ type kQVfyPrvNxtExpected kQVfyFirstExpected -{.push raises: [].} - # ------------------------------------------------------------------------------ # Public functions, debugging # ------------------------------------------------------------------------------ -proc `$`*[K,V](item: KeyedQueueItem[K,V]): string = +func `$`*[K,V](item: KeyedQueueItem[K,V]): string = ## Pretty print data container item. ## ## :CAVEAT: @@ -51,8 +51,8 @@ proc `$`*[K,V](item: KeyedQueueItem[K,V]): string = else: "(" & $item.value & ", link[" & $item.prv & "," & $item.kNxt & "])" -proc verify*[K,V](rq: var KeyedQueue[K,V]): Result[void,(K,V,KeyedQueueInfo)] - {.gcsafe,raises: [KeyError].} = +func verify*[K,V](rq: var KeyedQueue[K,V]): Result[void,(K,V,KeyedQueueInfo)] + {.raises: [KeyError].} = ## Check for consistency. Returns an error unless the argument ## queue `rq` is consistent. let tabLen = rq.tab.len @@ -97,7 +97,7 @@ proc verify*[K,V](rq: var KeyedQueue[K,V]): Result[void,(K,V,KeyedQueueInfo)] ok() -proc dumpLinkedKeys*[K,V](rq: var KeyedQueue[K,V]): string = +func dumpLinkedKeys*[K,V](rq: var KeyedQueue[K,V]): string = ## Dump the linked key list. This function depends on the `$` operator ## for converting a `K` type into a string if 0 < rq.tab.len: diff --git a/stew/shims/os.nim b/stew/shims/os.nim deleted file mode 100644 index bb2fe57..0000000 --- a/stew/shims/os.nim +++ /dev/null @@ -1,3 +0,0 @@ -{.deprecated: "use std/os".} -import std/os -export os diff --git a/stew/sorted_set.nim b/stew/sorted_set.nim index 3b6d197..cf0ae0a 100644 --- a/stew/sorted_set.nim +++ b/stew/sorted_set.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -47,9 +47,12 @@ ## rc = w.next ## # optional clean up, see comments on the destroy() directive ## walk.destroy -## + +{.push raises: [].} + import std/[tables], + pkg/results, ./sorted_set/[rbtree_delete, rbtree_desc, rbtree_find, @@ -57,8 +60,7 @@ import rbtree_insert, rbtree_reset, rbtree_verify, - rbtree_walk], - ./results + rbtree_walk] export RbInfo, @@ -93,18 +95,18 @@ type # Private helpers # ------------------------------------------------------------------------------ -proc slstCmp[K,V](casket: SortedSetItemRef[K,V]; key: K): int = +func slstCmp[K,V](casket: SortedSetItemRef[K,V]; key: K): int = casket.key.cmp(key) -proc slstMkc[K,V](key: K): SortedSetItemRef[K,V] = +func slstMkc[K,V](key: K): SortedSetItemRef[K,V] = SortedSetItemRef[K,V](key: key) -proc slstClup[K,V](c: var SortedSetItemRef[K,V]) = +func slstClup[K,V](c: var SortedSetItemRef[K,V]) = # ... some smart stuff here? c = nil # GC hint (if any, todo?) -proc slstLt[K,V](a, b: SortedSetItemRef[K,V]): bool = +func slstLt[K,V](a, b: SortedSetItemRef[K,V]): bool = ## Debugging only a.slstCmp(b.key) < 0 @@ -116,22 +118,22 @@ proc slstPr(code: RbInfo; ctxInfo: string) = # Public functions, constructor # ------------------------------------------------------------------------------ -proc init*[K,V](sl: var SortedSet[K,V]) = +func init*[K,V](sl: var SortedSet[K,V]) = ## Constructor for sorted list with key type `K` and data type `V` sl.tree = newRbTreeRef[SortedSetItemRef[K,V],K]( cmp = proc(c: SortedSetItemRef[K,V]; k: K): int = c.slstCmp(k), mkc = proc(k: K): SortedSetItemRef[K,V] = slstMkc[K,V](k)) -proc init*[K,V](T: type SortedSet[K,V]): T = +func init*[K,V](T: type SortedSet[K,V]): T = ## Variant of `init()` result.init -proc move*[K,V](sl: var SortedSet[K,V]): SortedSet[K,V] = +func move*[K,V](sl: var SortedSet[K,V]): SortedSet[K,V] = ## Return a shallow copy of the argument list `sl`, then reset `sl`. result.tree = sl.tree sl.init -proc clear*[K,V](sl: var SortedSet[K,V]) = +func clear*[K,V](sl: var SortedSet[K,V]) = ## Reset list descriptor to its inital value. This function also de-registers ## and flushes all traversal descriptors of type `SortedSetWalkRef`. sl.tree.rbTreeReset(clup = proc(c: var SortedSetItemRef[K,V]) = c.slstClup) @@ -140,15 +142,15 @@ proc clear*[K,V](sl: var SortedSet[K,V]) = # Public functions, getter, converter # ------------------------------------------------------------------------------ -proc key*[K,V](data: SortedSetItemRef[K,V]): K = +func key*[K,V](data: SortedSetItemRef[K,V]): K = ## Getter, extracts the key from the data container item. data.key -proc len*[K,V](sl: var SortedSet[K,V]): int = +func len*[K,V](sl: var SortedSet[K,V]): int = ## Number of list elements sl.tree.size -proc toSortedSetResult*[K,V](key: K; data: V): SortedSetResult[K,V] = +func toSortedSetResult*[K,V](key: K; data: V): SortedSetResult[K,V] = ## Helper, chreate `ok()` result ok(SortedSetItemRef[K,V](key: key, data: data)) @@ -156,24 +158,24 @@ proc toSortedSetResult*[K,V](key: K; data: V): SortedSetResult[K,V] = # Public functions, list operations # ------------------------------------------------------------------------------ -proc insert*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func insert*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Insert `key`, returns data container item with the `key`. Function fails ## if `key` exists in the list. sl.tree.rbTreeInsert(key) -proc findOrInsert*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func findOrInsert*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Insert or find `key`, returns data container item with the `key`. This ## function always succeeds (unless there is s problem with the list.) result = sl.tree.rbTreeInsert(key) if result.isErr: return sl.tree.rbTreeFindEq(key) -proc delete*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func delete*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Delete `key` from list and return the data container item that was ## holding the `key` if it was deleted. sl.tree.rbTreeDelete(key) -proc flush*[K,V](sl: var SortedSet[K,V]) = +func flush*[K,V](sl: var SortedSet[K,V]) = ## Flush the sorted list, i.e. delete all entries. This function is ## more efficient than running a `delete()` loop. sl.tree.rbTreeFlush(clup = proc(c: var SortedSetItemRef[K,V]) = c.slstClup) @@ -182,27 +184,27 @@ proc flush*[K,V](sl: var SortedSet[K,V]) = # Public functions, query functions # ------------------------------------------------------------------------------ -proc eq*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func eq*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Find `key` in list, returns data container item with the `key` if it ## exists. sl.tree.rbTreeFindEq(key) -proc le*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func le*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Find data container iten with *largest* key *less or equal* the argument ## `key` in list and return it if found. sl.tree.rbTreeFindLe(key) -proc lt*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func lt*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Find data container item with *largest* key *less than* the argument ## `key` in list and return it if found. sl.tree.rbTreeFindLt(key) -proc ge*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func ge*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Find data container item with *smallest* key *greater or equal* the ## argument `key` in list and return it if found. sl.tree.rbTreeFindGe(key) -proc gt*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = +func gt*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = ## Find data container item with *smallest* key *greater than* the argument ## `key` in list and return it if found. sl.tree.rbTreeFindGt(key) @@ -211,12 +213,12 @@ proc gt*[K,V](sl: var SortedSet[K,V]; key: K): SortedSetResult[K,V] = # Public functions, walk/traversal functions # ------------------------------------------------------------------------------ -proc init*[K,V](T: type SortedSetWalkRef[K,V]; sl: var SortedSet[K,V]): T = +func init*[K,V](T: type SortedSetWalkRef[K,V]; sl: var SortedSet[K,V]): T = ## Open traversal descriptor on list and register it on the 'SortedSet` ## descriptor. sl.tree.newRbWalk -proc destroy*[K,V](w: SortedSetWalkRef[K,V]) = +func destroy*[K,V](w: SortedSetWalkRef[K,V]) = ## De-register and close the traversal descriptor. This function renders ## the descriptor unusable, so it must be disposed of. ## @@ -227,7 +229,7 @@ proc destroy*[K,V](w: SortedSetWalkRef[K,V]) = ## rewound or destroyed. w.rbWalkDestroy -proc first*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = +func first*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## Rewind the traversal descriptor to the *least* list key and return ## the corresponding data container item. ## @@ -235,7 +237,7 @@ proc first*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## list operations are reset. w.rbWalkFirst -proc last*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = +func last*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## Rewind the traversal descriptor to the *greatest* list key and return ## the corresponding data container item. ## @@ -243,14 +245,14 @@ proc last*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## list operations are reset. w.rbWalkLast -proc this*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = +func this*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## Retrieve the *current* data container item. This is the same one retrieved ## last with any of the traversal functions returning the data container item. ## ## Note that the current node becomes unavailable if it was recently deleted. w.rbWalkCurrent -proc next*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = +func next*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## Move the traversal descriptor to the next *greater* key and return the ## corresponding data container item. If this is the first call after ## `newWalk()`, then `w.first` is called implicitly. @@ -259,7 +261,7 @@ proc next*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## causing this function to fail so that a rewind is needed. w.rbWalkNext -proc prev*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = +func prev*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = ## Move the traversal descriptor to the next *smaller* key and return the ## corresponding data container item . If this is the first call after ## `newWalk()`, then `w.last` is called implicitly. @@ -272,7 +274,7 @@ proc prev*[K,V](w: SortedSetWalkRef[K,V]): SortedSetResult[K,V] = # Public helpers, debugging # ------------------------------------------------------------------------------ -proc `$`*[K,V](casket: SortedSetItemRef[K,V]): string = +func `$`*[K,V](casket: SortedSetItemRef[K,V]): string = ## Pretty printer ## ## :CAVEAT: @@ -284,7 +286,7 @@ proc `$`*[K,V](casket: SortedSetItemRef[K,V]): string = return "nil" "(" & $casket.key & "," & $casket.data & ")" -proc `$`*[K,V](rc: SortedSetResult[K,V]): string = +func `$`*[K,V](rc: SortedSetResult[K,V]): string = ## Pretty printer ## ## :CAVEAT: diff --git a/stew/sorted_set/rbtree_delete.nim b/stew/sorted_set/rbtree_delete.nim index a2d8b09..26f633f 100644 --- a/stew/sorted_set/rbtree_delete.nim +++ b/stew/sorted_set/rbtree_delete.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -8,18 +8,18 @@ # at your option. This file may not be copied, modified, or distributed except # according to those terms. -import - ./rbtree_desc, - ./rbtree_rotate, - ../results - {.push raises: [].} +import + results, + ./rbtree_desc, + ./rbtree_rotate + # ------------------------------------------------------------------------------ # Public # ------------------------------------------------------------------------------ -proc rbTreeDelete*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = +func rbTreeDelete*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = ## Generic red-black tree function, removes a node from the red-black tree. ## The node to be removed wraps a data container `casket` matching the ## argument `key`, i.e. `rbt.cmp(casket,key) == 0`. diff --git a/stew/sorted_set/rbtree_desc.nim b/stew/sorted_set/rbtree_desc.nim index 686e93a..3833035 100644 --- a/stew/sorted_set/rbtree_desc.nim +++ b/stew/sorted_set/rbtree_desc.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -67,9 +67,11 @@ # anyone who has modified the code through # a header comment, such as this one.typedef +{.push raises: [].} + import - std/[tables], - ../results + results, + std/[tables] const rbTreeReBalancedFlag* = 1 @@ -176,7 +178,7 @@ type # Public functions, constructor # ------------------------------------------------------------------------------ -proc newRbTreeRef*[C,K](cmp: RbCmpFn[C,K]; mkc: RbMkcFn[C,K]): RbTreeRef[C,K] = +func newRbTreeRef*[C,K](cmp: RbCmpFn[C,K]; mkc: RbMkcFn[C,K]): RbTreeRef[C,K] = ## Constructor. Create generic red-black tree descriptor for data container ## type `C` and key type `K`. Details about the function arguments `cmpFn` ## and `mkcFn` are documented with the type definitions of `RbCmpFn` and @@ -188,7 +190,7 @@ proc newRbTreeRef*[C,K](cmp: RbCmpFn[C,K]; mkc: RbMkcFn[C,K]): RbTreeRef[C,K] = walks: initTable[uint,RbWalkRef[C,K]](1)) -proc newWalkId*[C,K](rbt: RbTreeRef[C,K]): uint {.inline.} = +func newWalkId*[C,K](rbt: RbTreeRef[C,K]): uint {.inline.} = ## Generate new free walk ID, returns zero in (theoretical) case all other ## IDs are exhausted. for id in rbt.walkIdGen .. high(type rbt.walkIdGen): @@ -205,12 +207,12 @@ proc newWalkId*[C,K](rbt: RbTreeRef[C,K]): uint {.inline.} = # Public handlers # ------------------------------------------------------------------------------ -proc cmp*[C,K](rbt: RbTreeRef[C,K]; casket: C; key: K): int {.inline.} = +func cmp*[C,K](rbt: RbTreeRef[C,K]; casket: C; key: K): int {.inline.} = ## See introduction for an explanation of opaque argument types `C` and `D`, ## and the type definition for `RbCmpFn` for properties of this function. rbt.cmpFn(casket, key) -proc mkc*[C,K](rbt: RbTreeRef[C,K]; key: K): C {.inline.} = +func mkc*[C,K](rbt: RbTreeRef[C,K]; key: K): C {.inline.} = ## See introduction for an explanation of opaque argument/return types `C` ## and `D`, and the type definition for `RbMkdFn` for properties of this ## function. @@ -220,15 +222,15 @@ proc mkc*[C,K](rbt: RbTreeRef[C,K]; key: K): C {.inline.} = # Public getters # ------------------------------------------------------------------------------ -proc linkLeft*[C](node: RbNodeRef[C]): RbNodeRef[C] {.inline.} = +func linkLeft*[C](node: RbNodeRef[C]): RbNodeRef[C] {.inline.} = ## Getter, shortcut for `node.link[rbLeft]` node.link[rbLeft] -proc linkRight*[C](node: RbNodeRef[C]): RbNodeRef[C] {.inline.} = +func linkRight*[C](node: RbNodeRef[C]): RbNodeRef[C] {.inline.} = ## Getter, shortcut for `node.link[rbRight]` node.link[rbRight] -proc isRed*[C](node: RbNodeRef[C]): bool {.inline.} = +func isRed*[C](node: RbNodeRef[C]): bool {.inline.} = ## Getter, `true` if node colour is read. not node.isNil and node.redColour @@ -236,15 +238,15 @@ proc isRed*[C](node: RbNodeRef[C]): bool {.inline.} = # Public setters # ------------------------------------------------------------------------------ -proc `linkLeft=`*[C](node, child: RbNodeRef[C]) {.inline.} = +func `linkLeft=`*[C](node, child: RbNodeRef[C]) {.inline.} = ## Getter, shortcut for `node.link[rbLeft] = child` node.link[rbLeft] = child -proc `linkRight=`*[C](node, child: RbNodeRef[C]) {.inline.} = +func `linkRight=`*[C](node, child: RbNodeRef[C]) {.inline.} = ## Getter, shortcut for `node.link[rbRight] = child` node.link[rbRight] = child -proc `isRed=`*[C](node: RbNodeRef[C]; value: bool) {.inline.} = +func `isRed=`*[C](node: RbNodeRef[C]; value: bool) {.inline.} = ## Setter, `true` sets red node colour. node.redColour = value @@ -252,11 +254,11 @@ proc `isRed=`*[C](node: RbNodeRef[C]; value: bool) {.inline.} = # Public helpers: `rbDir` as array index # ------------------------------------------------------------------------------ -proc `not`*(d: RbDir): RbDir {.inline.} = +func `not`*(d: RbDir): RbDir {.inline.} = ## Opposite direction of argument `d`. if d == rbLeft: rbRight else: rbLeft -proc toDir*(b: bool): RbDir {.inline.} = +func toDir*(b: bool): RbDir {.inline.} = ## Convert to link diection `rbLeft` (false) or `rbRight` (true). if b: rbRight else: rbLeft @@ -264,7 +266,7 @@ proc toDir*(b: bool): RbDir {.inline.} = # Public pretty printer # ------------------------------------------------------------------------------ -proc `$`*[C](node: RbNodeRef[C]): string = +func `$`*[C](node: RbNodeRef[C]): string = ## Pretty printer, requres `$()` for type `C` to be known. if node.isNil: return "nil" @@ -276,7 +278,7 @@ proc `$`*[C](node: RbNodeRef[C]): string = "left=" & $node.linkLeft & "," & "right=" & $node.linkRight & ")" -proc `$`*[C,K](rbt: RbTreeRef[C,K]): string = +func `$`*[C,K](rbt: RbTreeRef[C,K]): string = ## Pretty printer if rbt.isNil: return "nil" @@ -285,7 +287,7 @@ proc `$`*[C,K](rbt: RbTreeRef[C,K]): string = "gen=" & $rbt.walkIdGen & "," & "root=" & $rbt.root & "]" -proc `$`*[C,K](w: RbWalkRef[C,K]): string = +func `$`*[C,K](w: RbWalkRef[C,K]): string = ## Pretty printer if w.isNil: return "nil" diff --git a/stew/sorted_set/rbtree_find.nim b/stew/sorted_set/rbtree_find.nim index 1274f0f..8e2521d 100644 --- a/stew/sorted_set/rbtree_find.nim +++ b/stew/sorted_set/rbtree_find.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -8,17 +8,17 @@ # at your option. This file may not be copied, modified, or distributed except # according to those terms. -import - ./rbtree_desc, - ../results - {.push raises: [].} +import + results, + ./rbtree_desc + # ----------------------------------------------------------------------- ------ # Public # ------------------------------------------------------------------------------ -proc rbTreeFindEq*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = +func rbTreeFindEq*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = ## Generic red-black tree function. Search for a data container `casket` of ## type `C` in the red black tree which matches the argument `key`, ## i.e. `rbt.cmp(casket,key) == 0`. If found, this data container `casket` is @@ -51,7 +51,7 @@ proc rbTreeFindEq*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = return err(rbNotFound) -proc rbTreeFindGe*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = +func rbTreeFindGe*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = ## Generic red-black tree function. Search for the *smallest* data container ## `casket` of type `C` which is *greater or equal* to the specified argument ## `key` in the red black-tree. If such a data container is found in the @@ -109,7 +109,7 @@ proc rbTreeFindGe*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = return err(rbNotFound) -proc rbTreeFindGt*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = +func rbTreeFindGt*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = ## Generic red-black tree function. Search for the *smallest* data container ## of type `C` which is *strictly greater* than the specified argument `key` ## in the red-black tree. @@ -148,7 +148,7 @@ proc rbTreeFindGt*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = return err(rbNotFound) -proc rbTreeFindLe*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = +func rbTreeFindLe*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = ## Generic red-black tree function. Search for the *greatest* data container ## of type `C` which is *less than or equal* to the specified argument ## `key` in the red-black tree. @@ -190,7 +190,7 @@ proc rbTreeFindLe*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = return err(rbNotFound) -proc rbTreeFindLt*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = +func rbTreeFindLt*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = ## Generic red-black tree function. Search for the *greatest* data container ## of type `C` which is *strictly less* than the specified argument `key` in ## the red-black tree. diff --git a/stew/sorted_set/rbtree_insert.nim b/stew/sorted_set/rbtree_insert.nim index 73b7998..2d7b1ba 100644 --- a/stew/sorted_set/rbtree_insert.nim +++ b/stew/sorted_set/rbtree_insert.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -8,25 +8,25 @@ # at your option. This file may not be copied, modified, or distributed except # according to those terms. -import - ./rbtree_desc, - ./rbtree_rotate, - ../results - {.push raises: [].} +import + results, + ./rbtree_desc, + ./rbtree_rotate + # ----------------------------------------------------------------------- ------ # Private functions # ------------------------------------------------------------------------------ -proc insertRoot[C,K](rbt: RbTreeRef[C,K]; key: K): C {.inline.} = +func insertRoot[C,K](rbt: RbTreeRef[C,K]; key: K): C {.inline.} = ## Insert item `x` into an empty tree. rbt.root = RbNodeRef[C]( casket: rbt.mkc(key)) rbt.size = 1 rbt.root.casket -proc insertNode[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] {.inline.} = +func insertNode[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] {.inline.} = ## Insert item `key` into a non-empty tree. doAssert not rbt.root.isNil @@ -108,7 +108,7 @@ proc insertNode[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] {.inline.} = # Public # ------------------------------------------------------------------------------ -proc rbTreeInsert*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = +func rbTreeInsert*[C,K](rbt: RbTreeRef[C,K]; key: K): RbResult[C] = ## Generic red-black tree function, inserts a data container `casket` derived ## from argument `key` into the red-black tree. ## diff --git a/stew/sorted_set/rbtree_verify.nim b/stew/sorted_set/rbtree_verify.nim index 4009ded..8fd9f29 100644 --- a/stew/sorted_set/rbtree_verify.nim +++ b/stew/sorted_set/rbtree_verify.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -8,9 +8,11 @@ # at your option. This file may not be copied, modified, or distributed except # according to those terms. +{.push raises: [].} + import - ./rbtree_desc, - ../results + results, + ./rbtree_desc type RbLtFn*[C] = ##\ @@ -40,7 +42,7 @@ type # Private # ------------------------------------------------------------------------------ -proc pp[C](n: RbNodeRef[C]): string = +func pp[C](n: RbNodeRef[C]): string = if n.isNil: return "nil" result = $n.casket diff --git a/stew/sorted_set/rbtree_walk.nim b/stew/sorted_set/rbtree_walk.nim index 754c18d..7dcddad 100644 --- a/stew/sorted_set/rbtree_walk.nim +++ b/stew/sorted_set/rbtree_walk.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2018-2023 Status Research & Development GmbH +# Copyright (c) 2018-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -8,18 +8,18 @@ # at your option. This file may not be copied, modified, or distributed except # according to those terms. -import - std/[tables], - ./rbtree_desc, - ../results - {.push raises: [].} +import + results, + std/[tables], + ./rbtree_desc + # ----------------------------------------------------------------------- ------ # Priv # ------------------------------------------------------------------------------ -proc walkMove[C,K](w: RbWalkRef[C,K]; dir: RbDir): RbResult[C] = +func walkMove[C,K](w: RbWalkRef[C,K]; dir: RbDir): RbResult[C] = ## Traverse a red black tree in the user-specified direction. ## ## :Returns: @@ -62,7 +62,7 @@ proc walkMove[C,K](w: RbWalkRef[C,K]; dir: RbDir): RbResult[C] = return err(rbEndOfWalk) -proc walkStart[C,K](w: RbWalkRef[C,K]; dir: RbDir): RbResult[C] = +func walkStart[C,K](w: RbWalkRef[C,K]; dir: RbDir): RbResult[C] = ## Rewind the traversal position to the left-most or-right-most position ## as defined by the function argument `dir`. After successfully rewinding, ## the desriptor is in `start` position (see `walkClearDirty()`). @@ -94,7 +94,7 @@ proc walkStart[C,K](w: RbWalkRef[C,K]; dir: RbDir): RbResult[C] = return ok(w.node.casket) -proc walkClearDirtyFlags[C,K](w: RbWalkRef[C,K]): bool = +func walkClearDirtyFlags[C,K](w: RbWalkRef[C,K]): bool = ## Clear dirty flag if all traversal descriptors are in `start` postion. if w.tree.dirty != 0: for u in w.tree.walks.values: @@ -110,7 +110,7 @@ proc walkClearDirtyFlags[C,K](w: RbWalkRef[C,K]): bool = # Public constructor/desctructor # ------------------------------------------------------------------------------ -proc newRbWalk*[C,K](rbt: RbTreeRef[C,K]): RbWalkRef[C,K] = +func newRbWalk*[C,K](rbt: RbTreeRef[C,K]): RbWalkRef[C,K] = ## Generic red-black tree function, creates a new traversal descriptor on the ## argument red-black tree `rbt`. ## @@ -127,7 +127,7 @@ proc newRbWalk*[C,K](rbt: RbTreeRef[C,K]): RbWalkRef[C,K] = rbt.walks[result.id] = result # register in parent descriptor -proc rbWalkDestroy*[C,K](w: RbWalkRef[C,K]) = +func rbWalkDestroy*[C,K](w: RbWalkRef[C,K]) = ## Explicit destructor for current walk descriptor `w`. Clears the descriptor ## argument `w`. ## @@ -142,7 +142,7 @@ proc rbWalkDestroy*[C,K](w: RbWalkRef[C,K]) = w.path = @[] w[].reset -proc rbWalkDestroyAll*[C,K](rbt: RbTreeRef[C,K]) = +func rbWalkDestroyAll*[C,K](rbt: RbTreeRef[C,K]) = ## Apply `rbWalkDestroy()` to all registered walk descriptors. for w in rbt.walks.values: w.tree = nil # notify GC (if any, todo?) @@ -151,7 +151,7 @@ proc rbWalkDestroyAll*[C,K](rbt: RbTreeRef[C,K]) = w[].reset # clear rbt.walks = initTable[uint,RbWalkRef[C,K]](1) -proc rbWalkDestroyAll*[C,K](w: RbWalkRef[C,K]) = +func rbWalkDestroyAll*[C,K](w: RbWalkRef[C,K]) = ## Variant of `rbWalkDestroyAll()` if not w.tree.isNil: w.tree.rbWalkDestroyAll @@ -160,7 +160,7 @@ proc rbWalkDestroyAll*[C,K](w: RbWalkRef[C,K]) = # Public functions: rewind # ------------------------------------------------------------------------------ -proc rbWalkFirst*[C,K](w: RbWalkRef[C,K]): RbResult[C] = +func rbWalkFirst*[C,K](w: RbWalkRef[C,K]): RbResult[C] = ## Move to the beginning of the tree (*smallest* item) and return the ## corresponding data container of type `C`. ## @@ -181,7 +181,7 @@ proc rbWalkFirst*[C,K](w: RbWalkRef[C,K]): RbResult[C] = return w.walkStart(rbLeft) -proc rbWalkLast*[C,K](w: RbWalkRef[C,K]): RbResult[C] = +func rbWalkLast*[C,K](w: RbWalkRef[C,K]): RbResult[C] = ## Move to the end of the tree (*greatest* item) and return the corresponding ## data container of type `C`. ## @@ -205,7 +205,7 @@ proc rbWalkLast*[C,K](w: RbWalkRef[C,K]): RbResult[C] = # Public functions: traversal, get data entry # ------------------------------------------------------------------------------ -proc rbWalkCurrent*[C,K](w: RbWalkRef[C,K]): RbResult[C] = +func rbWalkCurrent*[C,K](w: RbWalkRef[C,K]): RbResult[C] = ## Retrieves the data container of type `C` for the current node. Note that ## the current node becomes unavailable if it was recently deleted. ## @@ -222,7 +222,7 @@ proc rbWalkCurrent*[C,K](w: RbWalkRef[C,K]): RbResult[C] = -proc rbWalkNext*[C,K](w: RbWalkRef[C,K]): RbResult[C] = +func rbWalkNext*[C,K](w: RbWalkRef[C,K]): RbResult[C] = ## Traverse to the next value in ascending order and return the corresponding ## data container of type `C`. If this is the first call after `newRbWalk()`, ## then `rbWalkFirst()` is called implicitly. @@ -253,7 +253,7 @@ proc rbWalkNext*[C,K](w: RbWalkRef[C,K]): RbResult[C] = return w.walkStart(rbLeft) # minimum index item -proc rbWalkPrev*[C,K](w: RbWalkRef[C,K]): RbResult[C] = +func rbWalkPrev*[C,K](w: RbWalkRef[C,K]): RbResult[C] = ## Traverse to the next value in descending order and return the ## corresponding data container of type `C`. If this is the first call ## after `newRbWalk()`, then `rbWalkLast()` is called implicitly. diff --git a/tests/test_helper.nim b/tests/test_helper.nim index dfc0173..3cceb56 100644 --- a/tests/test_helper.nim +++ b/tests/test_helper.nim @@ -1,11 +1,12 @@ -# Copyright (c) 2020-2022 Status Research & Development GmbH +# Copyright (c) 2020-2024 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license: http://opensource.org/licenses/MIT # * Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 # at your option. This file may not be copied, modified, or distributed except according to those terms. import std/[os, strutils] -import ../stew/io2, ../stew/results +import pkg/results +import ../stew/io2 proc lockFileFlags(path: string, flags: set[OpenFlags], lockType: LockType): IoResult[void] =