Closed mratsim closed 6 years ago
import strutils, sequtils, math, macros template high[T: uint64](t: typedesc[T]): uint64 = not 0'u64 template low[T: uint64](t: typedesc[T]): uint64 = 0'u64 macro coloringImpl(N: static[int], S: untyped): untyped = if N == 2: result = nnkBracketExpr.newTree( ident("TwoColoring"), S ) else: result = nnkBracketExpr.newTree( ident("NColoring"), newIntLitNode(N), S ) type TwoColoring[S: static[int]] = array[S div 64, uint64] NColoring[C, S: static[int]] = array[S, range[0 .. C - 1]] Coloring[N, S: static[int]] = object data: coloringImpl(N, S) proc initNColoring(C, S: static[int]): NColoring[C, S] = discard proc initTwoColoring(S: static[int]): TwoColoring[S] = discard proc initColoring(N, S: static[int]): Coloring[N, S] = discard proc `+=`*[C, S](col: var NColoring[C, S], amt: uint64) = var overflow = amt for n in 0 ..< S: if overflow == 0: return let X = col[n] + overflow col[n] = X mod C overflow = X div C proc `+=`*[S](col: var TwoColoring[S], amt: uint64) = var overflow = amt for i in 0 ..< (S div 64): let prev = col[i] col[i] += overflow if overflow > uint64.high - prev: # If overflowed overflow = 1 else: break template exportWithUint64(function: untyped): untyped = proc `function`*(x: var Coloring, amt: uint64) {.inline.} = function(x.data, amt) exportWithUint64(`+=`) var a = initColoring(2, 256) import typetraits echo a.data.type.name a += 10 echo a # (data: [10, 0, 0, 0])
Thank you very much!