ttuples_various.nim 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. discard """
  2. output: '''
  3. it's nil
  4. @[1, 2, 3]
  5. '''
  6. """
  7. import macros
  8. block anontuples:
  9. proc `^` (a, b: int): int =
  10. result = 1
  11. for i in 1..b: result = result * a
  12. var m = (0, 5)
  13. var n = (56, 3)
  14. m = (n[0] + m[1], m[1] ^ n[1])
  15. doAssert m == (61, 125)
  16. # also test we can produce unary anon tuples in a macro:
  17. macro mm(): untyped =
  18. result = newTree(nnkTupleConstr, newLit(13))
  19. proc nowTuple(): (int,) =
  20. result = (0,)
  21. doAssert nowTuple() == (Field0: 0)
  22. doAssert mm() == (Field0: 13)
  23. block unpack_asgn:
  24. proc foobar(): (int, int) = (2, 4)
  25. # test within a proc:
  26. proc pp(x: var int) =
  27. var y: int
  28. (y, x) = foobar()
  29. template pt(x) =
  30. var y: int
  31. (x, y) = foobar()
  32. # test within a generic:
  33. proc pg[T](x, y: var T) =
  34. pt(x)
  35. # test as a top level statement:
  36. var x, y, a, b: int
  37. # test for regression:
  38. (x, y) = (1, 2)
  39. (x, y) = fooBar()
  40. doAssert x == 2
  41. doAssert y == 4
  42. pp(a)
  43. doAssert a == 4
  44. pg(a, b)
  45. doAssert a == 2
  46. doAssert b == 0
  47. block unpack_const:
  48. const (a, ) = (1, )
  49. doAssert a == 1
  50. const (b, c) = (2, 3)
  51. doAssert b == 2
  52. doAssert c == 3
  53. # bug #10098
  54. const (x, y, z) = (4, 5, 6)
  55. doAssert x == 4
  56. doAssert y == 5
  57. doAssert z == 6
  58. # bug #10724
  59. block unpack_const_named:
  60. const (a, ) = (x: 1, )
  61. doAssert a == 1
  62. const (b, c) = (x: 2, y: 3)
  63. doAssert b == 2
  64. doAssert c == 3
  65. const (d, e, f) = (x: 4, y: 5, z: 6)
  66. doAssert d == 4
  67. doAssert e == 5
  68. doAssert f == 6
  69. block const_named:
  70. const x = block:
  71. (a: 1, b: 2, c: 3)
  72. doAssert x.a == 1
  73. doAssert x.b == 2
  74. doAssert x.c == 3
  75. block tuple_subscript:
  76. proc`[]` (t: tuple, key: string): string =
  77. for name, field in fieldPairs(t):
  78. if name == key:
  79. return $field
  80. return ""
  81. proc`[]` [A,B](t: tuple, key: string, op: (proc(x: A): B)): B =
  82. for name, field in fieldPairs(t):
  83. when field is A:
  84. if name == key:
  85. return op(field)
  86. proc`[]=`[T](t: var tuple, key: string, val: T) =
  87. for name, field in fieldPairs(t):
  88. when field is T:
  89. if name == key:
  90. field = val
  91. var tt = (a: 1, b: "str1")
  92. # test built in operator
  93. tt[0] = 5
  94. doAssert tt[0] == 5
  95. doAssert `[]`(tt, 0) == 5
  96. # test overloaded operator
  97. tt["b"] = "str2"
  98. doAssert tt["b"] == "str2"
  99. doAssert `[]`(tt, "b") == "str2"
  100. doAssert tt["b", proc(s: string): int = s.len] == 4
  101. block tuple_with_seq:
  102. template foo(s: string = "") =
  103. if s.len == 0:
  104. echo "it's nil"
  105. else:
  106. echo s
  107. foo
  108. # bug #2632
  109. proc takeTup(x: tuple[s: string;x: seq[int]]) =
  110. discard
  111. takeTup(("foo", @[]))
  112. #proc foobar(): () =
  113. proc f(xs: seq[int]) =
  114. discard
  115. proc g(t: tuple[n:int, xs:seq[int]]) =
  116. discard
  117. when true:
  118. f(@[]) # OK
  119. g((1,@[1])) # OK
  120. g((0,@[])) # NG
  121. # bug #2630
  122. type T = tuple[a: seq[int], b: int]
  123. var t: T = (@[1,2,3], 7)
  124. proc test(s: seq[int]): T =
  125. echo s
  126. (s, 7)
  127. t = test(t.a)
  128. block: # bug #22049
  129. type A = object
  130. field: tuple[a, b, c: seq[int]]
  131. func value(v: var A): var tuple[a, b, c: seq[int]] =
  132. v.field
  133. template get(v: A): tuple[a, b, c: seq[int]] = v.value
  134. var v = A(field: (@[1], @[2], @[3]))
  135. var (a, b, c) = v.get()
  136. doAssert a == @[1]
  137. doAssert b == @[2]
  138. doAssert c == @[3]
  139. block: # bug #22054
  140. type A = object
  141. field: tuple[a: int]
  142. func value(v: var A): var tuple[a: int] =
  143. v.field
  144. template get(v: A): tuple[a: int] = v.value
  145. var v = A(field: (a: 1314))
  146. doAssert get(v)[0] == 1314