summary refs log blame commit diff stats
path: root/tests/concepts/tswizzle.nim
blob: 07205d454f7556afd111a47958b99e2667739544 (plain) (tree)
1
2
3
4
5
6




              
                  














                                 
             


             
             

           
                                                 








                                     
 

              
    
                                 






                                                 
          

                
    

                                      


                                         
 




                                                
 


                                                
 


                                         


                      


            
 
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