tconceptsv2.nim 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. discard """
  2. action: "run"
  3. output: '''
  4. B[system.int]
  5. A[system.string]
  6. A[array[0..0, int]]
  7. A[seq[int]]
  8. 100
  9. a
  10. b
  11. c
  12. a
  13. b
  14. c
  15. 1
  16. 2
  17. '''
  18. """
  19. import conceptsv2_helper
  20. block: # issue #24451
  21. type
  22. A = object
  23. x: int
  24. B[T] = object
  25. b: T
  26. AConcept = concept
  27. proc implementation(s: var Self, p1: B[int])
  28. proc implementation(r: var A, p1: B[int])=
  29. echo typeof(p1)
  30. proc accept(r: var AConcept)=
  31. r.implementation(B[int]())
  32. var a = A()
  33. a.accept()
  34. block: # typeclass
  35. type
  36. A[T] = object
  37. x: int
  38. AConcept = concept
  39. proc implementation(s: Self)
  40. proc implementation(r: A) =
  41. echo typeof(r)
  42. proc accept(r: AConcept) =
  43. r.implementation()
  44. var a = A[string]()
  45. a.accept()
  46. block:
  47. type
  48. SomethingLike[T] = concept
  49. proc len(s: Self): int
  50. proc `[]`(s: Self; index: int): T
  51. A[T] = object
  52. x: T
  53. proc initA(x: SomethingLike): auto =
  54. A[type x](x: x)
  55. var a: array[1, int]
  56. var s: seq[int]
  57. echo typeof(initA(a))
  58. echo typeof(initA(s))
  59. block:
  60. proc iGetShadowed(s: int)=
  61. discard
  62. proc spring(x: ShadowConcept)=
  63. discard
  64. let a = DummyFitsObj()
  65. spring(a)
  66. block:
  67. type
  68. Buffer = concept
  69. proc put(s: Self)
  70. ArrayBuffer[T: static int] = object
  71. proc put(x: ArrayBuffer)=discard
  72. proc p(a: Buffer)=discard
  73. var buffer = ArrayBuffer[5]()
  74. p(buffer)
  75. block: # composite typeclass matching
  76. type
  77. A[T] = object
  78. Buffer = concept
  79. proc put(s: Self, i: A)
  80. BufferImpl = object
  81. WritableImpl = object
  82. proc launch(a: var Buffer)=discard
  83. proc put(x: BufferImpl, i: A)=discard
  84. var a = BufferImpl()
  85. launch(a)
  86. block: # simple recursion
  87. type
  88. Buffer = concept
  89. proc put(s: var Self, i: auto)
  90. proc second(s: Self)
  91. Writable = concept
  92. proc put(w: var Buffer, s: Self)
  93. BufferImpl[T: static int] = object
  94. WritableImpl = object
  95. proc launch(a: var Buffer, b: Writable)= discard
  96. proc put[T](x: var BufferImpl, i: T)= discard
  97. proc second(x: BufferImpl)= discard
  98. proc put(x: var Buffer, y: WritableImpl)= discard
  99. var a = BufferImpl[5]()
  100. launch(a, WritableImpl())
  101. block: # more complex recursion
  102. type
  103. Buffer = concept
  104. proc put(s: var Self, i: auto)
  105. proc second(s: Self)
  106. Writable = concept
  107. proc put(w: var Buffer, s: Self)
  108. BufferImpl[T: static int] = object
  109. WritableImpl = object
  110. proc launch(a: var Buffer, b: Writable)= discard
  111. proc put[T](x: var Buffer, i: T)= discard
  112. proc put(x: var BufferImpl, i: object)= discard
  113. proc second(x: BufferImpl)= discard
  114. proc put(x: var Buffer, y: WritableImpl)= discard
  115. var a = BufferImpl[5]()
  116. launch(a, WritableImpl())
  117. block: # co-dependent concepts
  118. type
  119. Writable = concept
  120. proc w(b: var Buffer; s: Self): int
  121. Buffer = concept
  122. proc w(s: var Self; data: Writable): int
  123. SizedWritable = concept
  124. proc size(x: Self): int
  125. proc w(b: var Buffer, x: Self): int
  126. BufferImpl = object
  127. proc w(x: var BufferImpl, d: int): int = return 100
  128. proc size(d: int): int = sizeof(int)
  129. proc p(b: var Buffer, data: SizedWritable): int =
  130. b.w(data)
  131. var b = BufferImpl()
  132. echo p(b, 5)
  133. block: # indirect concept matching
  134. type
  135. Sizeable = concept
  136. proc size(s: Self): int
  137. Buffer = concept
  138. proc w(s: Self, data: Sizeable)
  139. Serializable = concept
  140. proc something(s: Self)
  141. proc w(b: Buffer, s: Self)
  142. BufferImpl = object
  143. ArrayImpl = object
  144. proc something(s: ArrayImpl)= discard
  145. proc size(s: ArrayImpl): int= discard
  146. proc w(x: BufferImpl, d: Sizeable)= discard
  147. proc spring(s: Buffer, data: Serializable)=discard
  148. spring(BufferImpl(), ArrayImpl())
  149. block: # instantiate even when generic params are the same
  150. type
  151. ArrayLike[T] = concept
  152. proc len(x: Self): int
  153. proc `[]`(b: Self, i: int): T
  154. proc p[T](x: ArrayLike[T])=
  155. for k in x:
  156. echo k
  157. # For this test to work the second call's instantiation has to be incompatible with the first on the back end
  158. p(['a','b','c'])
  159. p("abc")
  160. block: # reject improper generic variables in candidates
  161. type
  162. ArrayLike[T] = concept
  163. proc len(x: Self): int
  164. proc g(b: Self, i: int): T
  165. FreakString = concept
  166. proc len(x: Self): int
  167. proc characterSize(s: Self): int
  168. A = object
  169. proc g[T, H](s: T, i: H): H = default(T)
  170. proc len(s: A): int = discard
  171. proc characterSize(s: A): int = discard
  172. proc p(symbol: ArrayLike[char]): int = assert false
  173. proc p(symbol: FreakString): int=discard
  174. discard p(A())
  175. block: # typerel disambiguation by concept subset
  176. type
  177. ArrayLike[T] = concept
  178. proc len(x: Self): int
  179. proc characterSize(s: Self): int
  180. FreakString = concept
  181. proc len(x: Self): int
  182. proc characterSize(s: Self): int
  183. proc tieBreaker(s: Self, j: int): float
  184. A = object
  185. proc len(s: A): int = discard
  186. proc characterSize(s: A): int = discard
  187. proc tieBreaker(s: A, h: int):float = 0.0
  188. proc p(symbol: ArrayLike[char]): int = assert false
  189. proc p(symbol: FreakString): int=discard
  190. discard p(A())
  191. block: # tie break via sumGeneric
  192. type
  193. C1 = concept
  194. proc p1(x: Self, b: int)
  195. proc p2(x: Self, b: float)
  196. proc p3(x: Self, b: string)
  197. C2 = concept
  198. proc b1(x: Self, b: int)
  199. proc b2(x: Self, b: float)
  200. A = object
  201. proc p1(x: A, b: int)=discard
  202. proc p2(x: A, b: float)=discard
  203. proc p3(x: A, b: string)=discard
  204. proc b1(x: A, b: int)=discard
  205. proc b2(x: A, b: float)=discard
  206. proc p(symbol: C1): int = discard
  207. proc p(symbol: C2): int = assert false
  208. discard p(A())
  209. block: # not type
  210. type
  211. C1 = concept
  212. proc p(s: Self, a: int)
  213. C1Impl = object
  214. proc p(x: C1Impl, a: not float)= discard
  215. proc spring(x: C1)= discard
  216. spring(C1Impl())
  217. block: # not type parameterized
  218. type
  219. C1[T: not int] = concept
  220. proc p(s: Self, a: T)
  221. C1Impl = object
  222. proc p(x: C1Impl, a: float)= discard
  223. proc spring(x: C1)= discard
  224. spring(C1Impl())
  225. block: # typedesc
  226. type
  227. C1 = concept
  228. proc p(s: Self, a: typedesc[SomeInteger])
  229. C1Impl = object
  230. proc p(x: C1Impl, a: typedesc)= discard
  231. proc spring(x: C1)= discard
  232. spring(C1Impl())
  233. block: # or
  234. type
  235. C1 = concept
  236. proc p(s: Self, a: int | float)
  237. C1Impl = object
  238. proc p(x: C1Impl, a: int | float | string)= discard
  239. proc spring(x: C1)= discard
  240. spring(C1Impl())
  241. block: # or mixed generic param
  242. type
  243. C1 = concept
  244. proc p(s: Self, a: int | float)
  245. C1Impl = object
  246. proc p[T: string | float](x: C1Impl, a: int | T) = discard
  247. proc spring(x: C1)= discard
  248. spring(C1Impl())
  249. block: # or parameterized
  250. type
  251. C1[T: int | float | string] = concept
  252. proc p(s: Self, a: T)
  253. C1Impl = object
  254. proc p(x: C1Impl, a: int | float)= discard
  255. proc spring(x: C1)= discard
  256. spring(C1Impl())
  257. block: # unconstrained param
  258. type
  259. A = object
  260. C1[T] = concept
  261. proc p(s: Self, a: T)
  262. C1Impl = object
  263. proc p(x: C1Impl, a: A)= discard
  264. proc spring(x: C1)= discard
  265. spring(C1Impl())
  266. block: # unconstrained param sanity check
  267. type
  268. A = object
  269. C1[T: auto] = concept
  270. proc p(s: Self, a: T)
  271. C1Impl = object
  272. proc p(x: C1Impl, a: A)= discard
  273. proc spring(x: C1)= discard
  274. spring(C1Impl())
  275. block: # exact nested concept binding
  276. type
  277. Sizeable = concept
  278. proc size(s: Self): int
  279. Buffer = concept
  280. proc w(s: Self, data: Sizeable)
  281. Serializable = concept
  282. proc w(b: Buffer, s: Self)
  283. ArrayLike = concept
  284. proc len(s: Self): int
  285. ArrayImpl = object
  286. proc len(s: ArrayImpl): int = discard
  287. proc w(x: Buffer, d: ArrayLike)=discard
  288. proc spring(data: Serializable)=discard
  289. spring(ArrayImpl())
  290. block:
  291. type
  292. StaticallySized = concept
  293. proc staticSize(x: typedesc[Self]): int
  294. proc dynamicSize(x: Self): int
  295. DynamicallySized = concept
  296. proc dynamicSize(x: Self): int
  297. proc dynamicSize(a: SomeInteger): int = 5
  298. proc read[T: DynamicallySized](a: var T): int = 1
  299. proc read[T: SomeInteger](a: var T): int = 2
  300. var a: uint16
  301. assert read(a) == 2
  302. block:
  303. type
  304. A[X, Y] = object
  305. x: X
  306. y: Y
  307. C1 = concept
  308. proc p(z: var Self)
  309. C2 = concept
  310. proc g(x: var Self, y: int)
  311. C3 = C1 and C2
  312. C4 = concept
  313. proc h(x: Self): C3
  314. proc p[X, Y](z: var A[int, float]) = discard
  315. proc g[X, Y](z: var A[X, Y], y: int) = discard
  316. proc h[X, Y](z: A[X, Y]): A[X, Y] = discard
  317. proc spring(x: C4) = discard
  318. var d = A[int, float]()
  319. d.spring()
  320. block:
  321. type
  322. A[X, Y] = object
  323. x: X
  324. y: Y
  325. B = object
  326. C1 = concept
  327. proc p(z: var Self, d: A[int, float])
  328. proc p[X: int; Y: float](x: var B, y: A[X, Y]) = discard
  329. proc spring(x: var C1) = discard
  330. var d = B()
  331. d.spring()
  332. block:
  333. type
  334. A = object
  335. C1 = concept
  336. proc p(s: Self; x: auto)
  337. C2[T: int] = concept
  338. proc p(s: Self; x: T)
  339. Impl = object
  340. proc p(n: Impl; i: int) = discard
  341. proc spring(x: C1): int = 1
  342. proc spring(x: C2): int = 2
  343. assert spring(Impl()) == 2
  344. block:
  345. type
  346. C1[T] = concept
  347. proc p(s: var Self; x: T)
  348. FreakString = concept
  349. proc p(w: var C1; s: Self)
  350. proc a(x: Self)
  351. DynArray[CT, T] = object
  352. proc p[CT; T; W; ](w: C1[T]; o: DynArray[CT, T]): int = discard
  353. proc spring(s: auto) = discard
  354. proc spring(s: FreakString) = discard
  355. spring("hi")
  356. block:
  357. type
  358. RawWriter = concept
  359. proc write(s: Self; data: pointer; length: int)
  360. ArrayBuffer[N: static int] = object
  361. SeqBuffer = object
  362. CompatBuffer = ArrayBuffer | SeqBuffer
  363. proc write[T:CompatBuffer](a: var T; data: pointer; length: int) =
  364. discard
  365. proc spring(r:RawWriter, i: byte)=discard
  366. var s = ArrayBuffer[1500]()
  367. spring(s, 8.uint8)
  368. # this code fails inside a block for some reason
  369. type Indexable[T] = concept
  370. proc `[]`(t: Self, i: int): T
  371. proc len(t: Self): int
  372. iterator items[T](t: Indexable[T]): T =
  373. for i in 0 ..< t.len:
  374. yield t[i]
  375. type Enumerable[T] = concept
  376. iterator items(t: Self): T
  377. proc echoAll[T](t: Enumerable[T]) =
  378. for item in t:
  379. echo item
  380. type DummyIndexable[T] = distinct seq[T]
  381. proc `[]`[T](t: DummyIndexable[T], i: int): T =
  382. seq[T](t)[i]
  383. proc len[T](t: DummyIndexable[T]): int =
  384. seq[T](t).len
  385. let dummyIndexable = DummyIndexable(@[1, 2])
  386. echoAll(dummyIndexable)