tdistinct.nim 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. discard """
  2. targets: "c js"
  3. output: '''
  4. tdistinct
  5. 25
  6. false
  7. false
  8. false
  9. false
  10. Foo
  11. foo
  12. '''
  13. """
  14. echo "tdistinct"
  15. block tborrowdot:
  16. type
  17. Foo = object
  18. a, b: int
  19. s: string
  20. Bar {.borrow: `.`.} = distinct Foo
  21. var bb: ref Bar
  22. new bb
  23. bb.a = 90
  24. bb.s = "abc"
  25. block tcurrncy:
  26. template Additive(typ: untyped) =
  27. proc `+`(x, y: typ): typ {.borrow.}
  28. proc `-`(x, y: typ): typ {.borrow.}
  29. # unary operators:
  30. proc `+`(x: typ): typ {.borrow.}
  31. proc `-`(x: typ): typ {.borrow.}
  32. template Multiplicative(typ, base: untyped) =
  33. proc `*`(x: typ, y: base): typ {.borrow.}
  34. proc `*`(x: base, y: typ): typ {.borrow.}
  35. proc `div`(x: typ, y: base): typ {.borrow.}
  36. proc `mod`(x: typ, y: base): typ {.borrow.}
  37. template Comparable(typ: untyped) =
  38. proc `<`(x, y: typ): bool {.borrow.}
  39. proc `<=`(x, y: typ): bool {.borrow.}
  40. proc `==`(x, y: typ): bool {.borrow.}
  41. template DefineCurrency(typ, base: untyped) =
  42. type
  43. typ = distinct base
  44. Additive(typ)
  45. Multiplicative(typ, base)
  46. Comparable(typ)
  47. proc `$`(t: typ): string {.borrow.}
  48. DefineCurrency(TDollar, int)
  49. DefineCurrency(TEuro, int)
  50. echo($( 12.TDollar + 13.TDollar )) #OUT 25
  51. block tconsts:
  52. # bug #2641
  53. type MyChar = distinct char
  54. const c:MyChar = MyChar('a')
  55. type MyBool = distinct bool
  56. const b:MyBool = MyBool(true)
  57. type MyBoolSet = distinct set[bool]
  58. const bs:MyBoolSet = MyBoolSet({true})
  59. type MyCharSet= distinct set[char]
  60. const cs:MyCharSet = MyCharSet({'a'})
  61. type MyBoolSeq = distinct seq[bool]
  62. const bseq:MyBoolSeq = MyBoolSeq(@[true, false])
  63. type MyBoolArr = distinct array[3, bool]
  64. const barr:MyBoolArr = MyBoolArr([true, false, true])
  65. # bug #2760
  66. type
  67. DistTup = distinct tuple
  68. foo, bar: string
  69. const d: DistTup = DistTup((
  70. foo:"FOO", bar:"BAR"
  71. ))
  72. # bug #7167
  73. type Id = distinct range[0..3]
  74. proc `<=`(a, b: Id): bool {.borrow.}
  75. var xs: array[Id, bool]
  76. for x in xs: echo x # type mismatch: got (T) but expected 'bool'
  77. # bug #11715
  78. type FooD = distinct int
  79. proc `<=`(a, b: FooD): bool {.borrow.}
  80. for f in [FooD(0): "Foo"]: echo f
  81. block tRequiresInit:
  82. template accept(x) =
  83. static: doAssert compiles(x)
  84. template reject(x) =
  85. static: doAssert not compiles(x)
  86. type
  87. Foo = object
  88. x: string
  89. DistinctFoo {.requiresInit, borrow: `.`.} = distinct Foo
  90. DistinctString {.requiresInit.} = distinct string
  91. reject:
  92. var foo: DistinctFoo
  93. foo.x = "test"
  94. doAssert foo.x == "test"
  95. accept:
  96. let foo = DistinctFoo(Foo(x: "test"))
  97. doAssert foo.x == "test"
  98. reject:
  99. var s: DistinctString
  100. s = "test"
  101. doAssert string(s) == "test"
  102. accept:
  103. let s = DistinctString("test")
  104. doAssert string(s) == "test"
  105. block: #17322
  106. type
  107. A[T] = distinct string
  108. proc foo(a: var A) =
  109. a.string.add "foo"
  110. type
  111. B = distinct A[int]
  112. var b: B
  113. foo(A[int](b))
  114. echo A[int](b).string
  115. b.string.add "bar"
  116. assert b.string == "foobar"
  117. type Foo = distinct string
  118. proc main() = # proc instead of template because of MCS/UFCS.
  119. # xxx put everything here to test under RT + VM
  120. block: # bug #12282
  121. block:
  122. proc test() =
  123. var s: Foo
  124. s.string.add('c')
  125. doAssert s.string == "c" # was failing
  126. test()
  127. block:
  128. proc add(a: var Foo, b: char) {.borrow.}
  129. proc test() =
  130. var s: Foo
  131. s.add('c')
  132. doAssert s.string == "c" # was ok
  133. test()
  134. block:
  135. proc add(a: var Foo, b: char) {.borrow.}
  136. proc test() =
  137. var s: string
  138. s.Foo.add('c')
  139. doAssert s.string == "c" # was failing
  140. test()
  141. block: #18061
  142. type
  143. A = distinct (0..100)
  144. B = A(0) .. A(10)
  145. proc test(b: B) = discard
  146. let
  147. a = A(10)
  148. b = B(a)
  149. test(b)
  150. proc test(a: A) = discard
  151. discard cast[B](A(1))
  152. var c: B
  153. block: # bug #9423
  154. block:
  155. type Foo = seq[int]
  156. type Foo2 = distinct Foo
  157. template fn() =
  158. var a = Foo2(@[1])
  159. a.Foo.add 2
  160. doAssert a.Foo == @[1, 2]
  161. fn()
  162. block:
  163. type Stack[T] = distinct seq[T]
  164. proc newStack[T](): Stack[T] =
  165. Stack[T](newSeq[T]())
  166. proc push[T](stack: var Stack[T], elem: T) =
  167. seq[T](stack).add(elem)
  168. proc len[T](stack: Stack[T]): int =
  169. seq[T](stack).len
  170. proc fn() =
  171. var stack = newStack[int]()
  172. stack.push(5)
  173. doAssert stack.len == 1
  174. fn()
  175. static: main()
  176. main()