tconcepts_issues.nim 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. discard """
  2. output: '''
  3. 20.0 USD
  4. Printable
  5. true
  6. true
  7. true
  8. true
  9. true
  10. f
  11. 0
  12. 10
  13. 10
  14. 5
  15. ()
  16. false
  17. 10
  18. true
  19. true
  20. true
  21. true
  22. p has been called.
  23. p has been called.
  24. implicit generic
  25. generic
  26. false
  27. true
  28. -1
  29. Meow
  30. '''
  31. """
  32. import macros, typetraits, os, posix
  33. block t5983:
  34. const currencies = ["USD", "EUR"] # in real code 120 currencies
  35. type USD = distinct float # in real code 120 types generates using macro
  36. type EUR = distinct float
  37. type CurrencyAmount = concept c
  38. type t = c.type
  39. const name = c.type.name
  40. name in currencies
  41. proc `$`(x: CurrencyAmount): string =
  42. $float(x) & " " & x.name
  43. let amount = 20.USD
  44. echo amount
  45. block t3414:
  46. type
  47. View[T] = concept v
  48. v.empty is bool
  49. v.front is T
  50. popFront v
  51. proc find(view: View; target: View.T): View =
  52. result = view
  53. while not result.empty:
  54. if view.front == target:
  55. return
  56. mixin popFront
  57. popFront result
  58. proc popFront[T](s: var seq[T]) = discard
  59. proc empty[T](s: seq[T]): bool = false
  60. var s1 = @[1, 2, 3]
  61. let s2 = s1.find(10)
  62. type
  63. Obj1[T] = object
  64. v: T
  65. converter toObj1[T](t: T): Obj1[T] =
  66. return Obj1[T](v: t)
  67. block t976:
  68. type
  69. int1 = distinct int
  70. int2 = distinct int
  71. int1g = concept x
  72. x is int1
  73. int2g = concept x
  74. x is int2
  75. proc take[T: int1g](value: int1) =
  76. when T is int2:
  77. static: error("killed in take(int1)")
  78. proc take[T: int2g](vale: int2) =
  79. when T is int1:
  80. static: error("killed in take(int2)")
  81. var i1: int1 = 1.int1
  82. var i2: int2 = 2.int2
  83. take[int1](i1)
  84. take[int2](i2)
  85. template reject(e) =
  86. static: assert(not compiles(e))
  87. reject take[string](i2)
  88. reject take[int1](i2)
  89. # bug #6249
  90. type
  91. Obj2 = ref object
  92. PrintAble = concept x
  93. $x is string
  94. proc `$`[T](nt: Obj1[T]): string =
  95. when T is PrintAble: result = "Printable"
  96. else: result = "Non Printable"
  97. echo Obj2()
  98. block t1128:
  99. type
  100. TFooContainer[T] = object
  101. TContainer[T] = concept var c
  102. foo(c, T)
  103. proc foo[T](c: var TFooContainer[T], val: T) =
  104. discard
  105. proc bar(c: var TContainer) =
  106. discard
  107. var fooContainer: TFooContainer[int]
  108. echo fooContainer is TFooContainer # true.
  109. echo fooContainer is TFooContainer[int] # true.
  110. fooContainer.bar()
  111. block t5642:
  112. type DataTable = concept x
  113. x is object
  114. for f in fields(x):
  115. f is seq
  116. type Students = object
  117. id : seq[int]
  118. name : seq[string]
  119. age: seq[int]
  120. proc nrow(dt: DataTable) : Natural =
  121. var totalLen = 0
  122. for f in fields(dt):
  123. totalLen += f.len
  124. return totalLen
  125. let
  126. stud = Students(id: @[1,2,3], name: @["Vas", "Pas", "NafNaf"], age: @[10,16,32])
  127. doAssert nrow(stud) == 9
  128. import t5888lib/ca, t5888lib/opt
  129. block t5888:
  130. type LocalCA = ca.CA
  131. proc f(c: CA) =
  132. echo "f"
  133. echo c.x
  134. var o = new(Opt)
  135. echo o is CA
  136. echo o is LocalCA
  137. echo o is ca.CA
  138. o.f()
  139. import json
  140. block t5968:
  141. type
  142. Enumerable[T] = concept e
  143. for it in e:
  144. it is T
  145. proc cmap[T, G](e: Enumerable[T], fn: proc(t: T): G): seq[G] =
  146. result = @[]
  147. for it in e: result.add(fn(it))
  148. var x = %["hello", "world"]
  149. var z = x.cmap(proc(it: JsonNode): string = it.getStr & "!")
  150. assert z == @["hello!", "world!"]
  151. import sugar
  152. block t6462:
  153. type
  154. FilterMixin[T] = ref object
  155. test: (T) -> bool
  156. trans: (T) -> T
  157. SeqGen[T] = ref object
  158. fil: FilterMixin[T]
  159. WithFilter[T] = concept a
  160. a.fil is FilterMixin[T]
  161. proc test[T](a: WithFilter[T]): (T) -> bool =
  162. a.fil.test
  163. var s = SeqGen[int](fil: FilterMixin[int](test: nil, trans: nil))
  164. doAssert s.test() == nil
  165. block t6770:
  166. type GA = concept c
  167. c.a is int
  168. type A = object
  169. a: int
  170. type AA = object
  171. case exists: bool
  172. of true:
  173. a: int
  174. else:
  175. discard
  176. proc print(inp: GA) =
  177. echo inp.a
  178. let failing = AA(exists: true, a: 10)
  179. let working = A(a:10)
  180. print(working)
  181. print(failing)
  182. block t7952:
  183. type
  184. HasLen = concept iter
  185. len(iter) is int
  186. proc echoLen(x: HasLen) =
  187. echo len(x)
  188. echoLen([1, 2, 3, 4, 5])
  189. block t8280:
  190. type
  191. Iterable[T] = concept x
  192. for elem in x:
  193. elem is T
  194. proc max[A](iter: Iterable[A]): A =
  195. discard
  196. type
  197. MyType = object
  198. echo max(@[MyType()])
  199. import math
  200. block t3452:
  201. type
  202. Node = concept n
  203. `==`(n, n) is bool
  204. Graph1 = concept g
  205. type N = Node
  206. distance(g, N, N) is float
  207. Graph2 = concept g
  208. distance(g, Node, Node) is float
  209. Graph3 = concept g
  210. var x: Node
  211. distance(g, x, x) is float
  212. XY = tuple[x, y: int]
  213. MyGraph = object
  214. points: seq[XY]
  215. static:
  216. assert XY is Node
  217. proc distance( g: MyGraph, a, b: XY): float =
  218. sqrt( pow(float(a.x - b.x), 2) + pow(float(a.y - b.y), 2) )
  219. static:
  220. assert MyGraph is Graph1
  221. assert MyGraph is Graph2
  222. assert MyGraph is Graph3
  223. block t6691:
  224. type
  225. ConceptA = concept c
  226. ConceptB = concept c
  227. c.myProc(ConceptA)
  228. Obj = object
  229. proc myProc(obj: Obj, x: ConceptA) = discard
  230. echo Obj is ConceptB
  231. block t6782:
  232. type
  233. Reader = concept c
  234. c.read(openarray[byte], int, int) is int
  235. Rdr = concept c
  236. c.rd(openarray[byte], int, int) is int
  237. type TestFile = object
  238. proc read(r: TestFile, dest: openarray[byte], offset: int, limit: int): int =
  239. result = 0
  240. proc rd(r: TestFile, dest: openarray[byte], offset: int, limit: int): int =
  241. result = 0
  242. doAssert TestFile is Reader
  243. doAssert TestFile is Rdr
  244. block t7114:
  245. type
  246. MyConcept = concept x
  247. x.close() # error, doesn't work
  248. MyConceptImplementer = object
  249. proc close(self: MyConceptImplementer) = discard
  250. proc takeConcept(window: MyConcept) =
  251. discard
  252. takeConcept(MyConceptImplementer())
  253. block t7510:
  254. type
  255. A[T] = concept a
  256. a.x is T
  257. B[T] = object
  258. x: T
  259. proc getx(v: A): v.T = v.x
  260. var v = B[int32](x: 10)
  261. echo v.getx
  262. block misc_issues:
  263. # https://github.com/nim-lang/Nim/issues/1147
  264. type TTest = object
  265. vals: seq[int]
  266. proc add(self: var TTest, val: int) =
  267. self.vals.add(val)
  268. type CAddable = concept x
  269. x[].add(int)
  270. echo((ref TTest) is CAddable) # true
  271. # https://github.com/nim-lang/Nim/issues/1570
  272. type ConcretePointOfFloat = object
  273. x, y: float
  274. type ConcretePoint[Value] = object
  275. x, y: Value
  276. type AbstractPointOfFloat = concept p
  277. p.x is float and p.y is float
  278. let p1 = ConcretePointOfFloat(x: 0, y: 0)
  279. let p2 = ConcretePoint[float](x: 0, y: 0)
  280. echo p1 is AbstractPointOfFloat # true
  281. echo p2 is AbstractPointOfFloat # true
  282. echo p2.x is float and p2.y is float # true
  283. # https://github.com/nim-lang/Nim/issues/2018
  284. type ProtocolFollower = concept
  285. true # not a particularly involved protocol
  286. type ImplementorA = object
  287. type ImplementorB = object
  288. proc p[A: ProtocolFollower, B: ProtocolFollower](a: A, b: B) =
  289. echo "p has been called."
  290. p(ImplementorA(), ImplementorA())
  291. p(ImplementorA(), ImplementorB())
  292. # https://github.com/nim-lang/Nim/issues/2423
  293. proc put[T](c: seq[T], x: T) = echo "generic"
  294. proc put(c: seq) = echo "implicit generic"
  295. type
  296. Container[T] = concept c
  297. put(c)
  298. put(c, T)
  299. proc c1(x: Container) = echo "implicit generic"
  300. c1(@[1])
  301. proc c2[T](x: Container[T]) = echo "generic"
  302. c2(@[1])
  303. # https://github.com/nim-lang/Nim/issues/2882
  304. type
  305. Paper = object
  306. name: string
  307. Bendable = concept x
  308. bend(x is Bendable)
  309. proc bend(p: Paper): Paper = Paper(name: "bent-" & p.name)
  310. var paper = Paper(name: "red")
  311. echo paper is Bendable
  312. type
  313. A = concept self
  314. size(self) is int
  315. B = object
  316. proc size(self: B): int =
  317. return -1
  318. proc size(self: A): int =
  319. return 0
  320. let b = B()
  321. echo b is A
  322. echo b.size()
  323. # https://github.com/nim-lang/Nim/issues/7125
  324. type
  325. Thing = concept x
  326. x.hello is string
  327. Cat = object
  328. proc hello(d: Cat): string = "Meow"
  329. proc sayHello(c: Thing) = echo(c.hello)
  330. var a: Thing = Cat()
  331. a.sayHello()