Quelklef / random-algorithms

so1TpzpOyCizrHpZWQc9
1 stars 0 forks source link

Static dispatch Two vs N coloring #2

Closed mratsim closed 6 years ago

mratsim commented 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])
Quelklef commented 6 years ago

Thank you very much!