summary refs log tree commit diff stats
path: root/tests/concepts/tconcepts_issues.nim
diff options
context:
space:
mode:
Diffstat (limited to 'tests/concepts/tconcepts_issues.nim')
-rw-r--r--tests/concepts/tconcepts_issues.nim197
1 files changed, 142 insertions, 55 deletions
diff --git a/tests/concepts/tconcepts_issues.nim b/tests/concepts/tconcepts_issues.nim
index 65f6d4660..c6d0267c5 100644
--- a/tests/concepts/tconcepts_issues.nim
+++ b/tests/concepts/tconcepts_issues.nim
@@ -1,7 +1,6 @@
 discard """
   output: '''
 20.0 USD
-Printable
 true
 true
 true
@@ -27,6 +26,8 @@ false
 true
 -1
 Meow
+10 0.0
+1 2.0
 '''
 joinable: false
 """
@@ -76,55 +77,6 @@ block t3414:
   let s2 = s1.find(10)
 
 
-
-type
-  Obj1[T] = object
-      v: T
-converter toObj1[T](t: T): Obj1[T] =
-  return Obj1[T](v: t)
-block t976:
-  type
-    int1 = distinct int
-    int2 = distinct int
-    int1g = concept x
-      x is int1
-    int2g = concept x
-      x is int2
-
-  proc take[T: int1g](value: int1) =
-    when T is int2:
-      static: error("killed in take(int1)")
-
-  proc take[T: int2g](vale: int2) =
-    when T is int1:
-      static: error("killed in take(int2)")
-
-  var i1: int1 = 1.int1
-  var i2: int2 = 2.int2
-
-  take[int1](i1)
-  take[int2](i2)
-
-  template reject(e) =
-    static: assert(not compiles(e))
-
-  reject take[string](i2)
-  reject take[int1](i2)
-
-  # bug #6249
-  type
-      Obj2 = ref object
-      PrintAble = concept x
-          $x is string
-
-  proc `$`[T](nt: Obj1[T]): string =
-      when T is PrintAble: result = "Printable"
-      else: result = "Non Printable"
-
-  echo Obj2()
-
-
-
 block t1128:
   type
     TFooContainer[T] = object
@@ -324,15 +276,15 @@ block t6691:
 block t6782:
   type
     Reader = concept c
-      c.read(openarray[byte], int, int) is int
+      c.read(openArray[byte], int, int) is int
     Rdr = concept c
-      c.rd(openarray[byte], int, int) is int
+      c.rd(openArray[byte], int, int) is int
 
   type TestFile = object
 
-  proc read(r: TestFile, dest: openarray[byte], offset: int, limit: int): int =
+  proc read(r: TestFile, dest: openArray[byte], offset: int, limit: int): int =
       result = 0
-  proc rd(r: TestFile, dest: openarray[byte], offset: int, limit: int): int =
+  proc rd(r: TestFile, dest: openArray[byte], offset: int, limit: int): int =
       result = 0
 
   doAssert TestFile is Reader
@@ -397,7 +349,7 @@ block misc_issues:
   echo p2.x is float and p2.y is float # true
 
   # https://github.com/nim-lang/Nim/issues/2018
-  type ProtocolFollower = concept
+  type ProtocolFollower = concept c
     true # not a particularly involved protocol
 
   type ImplementorA = object
@@ -467,3 +419,138 @@ block misc_issues:
   # anyway and will be an error soon.
   var a: Cat = Cat()
   a.sayHello()
+
+
+# bug #16897
+
+type
+  Fp[N: static int, T] = object
+    big: array[N, T]
+
+type
+  QuadraticExt* = concept x
+    ## Quadratic Extension concept (like complex)
+    type BaseField = auto
+    x.c0 is BaseField
+    x.c1 is BaseField
+var address = pointer(nil)
+proc prod(r: var QuadraticExt, b: QuadraticExt) =
+  if address == nil:
+    address = addr b
+    prod(r, b)
+  else:
+    assert address == addr b
+
+type
+  Fp2[N: static int, T] {.byref.} = object
+    c0, c1: Fp[N, T]
+
+# This should be passed by reference,
+# but concepts do not respect the 24 bytes rule
+# or `byref` pragma.
+var r, b: Fp2[6, uint64]
+
+prod(r, b)
+
+
+block: # bug #21263
+  type
+    DateDayFraction = concept # no T, an atom
+      proc date(a: Self): int
+      proc fraction(b: Self): float
+    Date = distinct int
+    DateDayFractionImpl = object
+      date : int
+      fraction : float
+
+  proc date(a: Date): int = a.int
+  proc fraction(a:Date): float = 0.0
+
+  proc date(a: DateDayFractionImpl): int = a.date
+  proc fraction(b: DateDayFractionImpl): float = b.fraction
+
+
+  proc print(a: DateDayFraction) =
+    echo a.date, " ", a.fraction
+
+  print(10.Date) # ok
+  print(DateDayFractionImpl(date: 1, fraction: 2))  # error
+
+import sets
+import deques
+
+type AnyTree[V] = concept t, type T
+  for v in t.leaves(V):
+    v is V
+
+type BreadthOrder[V] = ref object
+  frontier: Deque[V]
+  visited: HashSet[V]
+
+proc expand[V, T](order: ref BreadthOrder[T], tree: AnyTree[V], node: V, transform: (V) -> (T)) =
+  for leaf in tree.leaves(node):
+    if not order.visited.containsOrIncl(transform(leaf)):
+      order.frontier.addLast(transform(leaf))
+
+proc hasNext[V](order: ref BreadthOrder[V]): bool =
+  order.frontier.len > 0
+
+proc init[V](_: typedesc[BreadthOrder]): ref BreadthOrder[V] =
+  result.new()
+  result[] = BreadthOrder[V](frontier: initDeque[V](), visited: initHashSet[V]())
+
+proc popNext[V](order: ref BreadthOrder[V]): V =
+  order.frontier.popFirst()
+
+type LevelNode[V] = tuple
+  depth: uint
+  node: V
+
+proc depthOf*[V](orderType: typedesc[BreadthOrder], tree: AnyTree[V], root, goal: V): uint =
+  if root == goal:
+    return 0
+  var order = init[LevelNode[V]](orderType)
+  order.expand(tree, root, (leaf) => (1.uint, leaf))
+  while order.hasNext():
+    let depthNode: LevelNode[V] = order.popNext()
+    if depthNode.node == goal:
+      return depthNode.depth
+    order.expand(tree, depthNode.node, (leaf) => (depthNode.depth + 1, leaf))
+
+type CappedStringTree = ref object
+  symbols: string
+  cap: Natural
+
+iterator leaves*(t: CappedStringTree, s: string): string =
+  if s.len < t.cap:
+    for c in t.symbols:
+      yield s & c
+
+block: # bug #12852
+  var tree = CappedStringTree(symbols: "^v><", cap: 5)
+
+  doAssert BreadthOrder.depthOf(tree, "", ">>>") == 3
+
+block: #bug #22723
+  type
+    Node  = concept n, type T 
+      for i in n.children:
+        i is T
+      n.parent is T
+
+    Nd = ref object
+      parent: Nd
+      children: seq[Nd]
+
+  proc addChild(parent, child: Node) =
+    parent.children.add(child)
+    child.parent = parent
+
+  proc foo =
+    var
+      a = Nd()
+      b = Nd()
+    a.addChild(b)
+    doAssert a.children.len == 1
+
+  foo()