summary refs log tree commit diff stats
path: root/tests/concepts/tswizzle.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/concepts/tswizzle.nim')
-rw-r--r--tests/concepts/tswizzle.nim80
1 files changed, 80 insertions, 0 deletions
diff --git a/tests/concepts/tswizzle.nim b/tests/concepts/tswizzle.nim
new file mode 100644
index 000000000..07205d454
--- /dev/null
+++ b/tests/concepts/tswizzle.nim
@@ -0,0 +1,80 @@
+discard """
+  output: '''3
+[1, 3]
+[2, 1, 2]
+'''
+  disabled: "true"
+"""
+
+import macros, strutils
+
+template accept(e: expr) =
+  static: assert(compiles(e))
+
+template reject(e: expr) =
+  static: assert(not compiles(e))
+
+proc swizzleIdx(c: char): int =
+  return case c
+    of 'x': 0
+    of 'y': 1
+    of 'z': 2
+    of 'w': 3
+    of 'r': 0
+    of 'g': 1
+    of 'b': 2
+    of 'a': 3
+    else: 0
+
+proc isSwizzle(s: string): bool {.compileTime.} =
+  template trySet(name, set) =
+    block search:
+      for c in s:
+        if c notin set:
+          break search
+      return true
+
+  trySet coords, {'x', 'y', 'z', 'w'}
+  trySet colors, {'r', 'g', 'b', 'a'}
+
+  return false
+
+type
+  StringIsSwizzle = concept value
+    value.isSwizzle
+
+  SwizzleStr = static[string] and StringIsSwizzle
+
+proc foo(x: SwizzleStr) =
+  echo "sw"
+
+#foo("xx")
+reject foo("xe")
+
+type
+  Vec[N: static[int]; T] = array[N, T]
+
+when false:
+  proc card(x: Vec): int = x.N
+  proc `$`(x: Vec): string = x.repr.strip
+
+  macro `.`(x: Vec, swizzle: SwizzleStr): expr =
+    var
+      cardinality = swizzle.len
+      values = newNimNode(nnkBracket)
+      v = genSym()
+
+    for c in swizzle:
+      values.add newNimNode(nnkBracketExpr).add(
+        v, c.swizzleIdx.newIntLitNode)
+
+    return quote do:
+      let `v` = `x`
+      Vec[`cardinality`, `v`.T](`values`)
+
+var z = Vec([1, 2, 3])
+
+#echo z.card
+#echo z.xz
+#echo z.yxy
+