comparisons.nim 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. # comparison operators:
  2. proc `==`*[Enum: enum](x, y: Enum): bool {.magic: "EqEnum", noSideEffect.} =
  3. ## Checks whether values within the *same enum* have the same underlying value.
  4. runnableExamples:
  5. type
  6. Enum1 = enum
  7. field1 = 3, field2
  8. Enum2 = enum
  9. place1, place2 = 3
  10. var
  11. e1 = field1
  12. e2 = place2.ord.Enum1
  13. assert e1 == e2
  14. assert not compiles(e1 == place2) # raises error
  15. proc `==`*(x, y: pointer): bool {.magic: "EqRef", noSideEffect.} =
  16. ## Checks for equality between two `pointer` variables.
  17. runnableExamples:
  18. var # this is a wildly dangerous example
  19. a = cast[pointer](0)
  20. b = cast[pointer](nil)
  21. assert a == b # true due to the special meaning of `nil`/0 as a pointer
  22. proc `==`*(x, y: string): bool {.magic: "EqStr", noSideEffect.}
  23. ## Checks for equality between two `string` variables.
  24. proc `==`*(x, y: char): bool {.magic: "EqCh", noSideEffect.}
  25. ## Checks for equality between two `char` variables.
  26. proc `==`*(x, y: bool): bool {.magic: "EqB", noSideEffect.}
  27. ## Checks for equality between two `bool` variables.
  28. proc `==`*[T](x, y: set[T]): bool {.magic: "EqSet", noSideEffect.} =
  29. ## Checks for equality between two variables of type `set`.
  30. runnableExamples:
  31. assert {1, 2, 2, 3} == {1, 2, 3} # duplication in sets is ignored
  32. proc `==`*[T](x, y: ref T): bool {.magic: "EqRef", noSideEffect.}
  33. ## Checks that two `ref` variables refer to the same item.
  34. proc `==`*[T](x, y: ptr T): bool {.magic: "EqRef", noSideEffect.}
  35. ## Checks that two `ptr` variables refer to the same item.
  36. proc `==`*[T: proc](x, y: T): bool {.magic: "EqProc", noSideEffect.}
  37. ## Checks that two `proc` variables refer to the same procedure.
  38. proc `<=`*[Enum: enum](x, y: Enum): bool {.magic: "LeEnum", noSideEffect.}
  39. proc `<=`*(x, y: string): bool {.magic: "LeStr", noSideEffect.} =
  40. ## Compares two strings and returns true if `x` is lexicographically
  41. ## before `y` (uppercase letters come before lowercase letters).
  42. runnableExamples:
  43. let
  44. a = "abc"
  45. b = "abd"
  46. c = "ZZZ"
  47. assert a <= b
  48. assert a <= a
  49. assert not (a <= c)
  50. proc `<=`*(x, y: char): bool {.magic: "LeCh", noSideEffect.} =
  51. ## Compares two chars and returns true if `x` is lexicographically
  52. ## before `y` (uppercase letters come before lowercase letters).
  53. runnableExamples:
  54. let
  55. a = 'a'
  56. b = 'b'
  57. c = 'Z'
  58. assert a <= b
  59. assert a <= a
  60. assert not (a <= c)
  61. proc `<=`*[T](x, y: set[T]): bool {.magic: "LeSet", noSideEffect.} =
  62. ## Returns true if `x` is a subset of `y`.
  63. ##
  64. ## A subset `x` has all of its members in `y` and `y` doesn't necessarily
  65. ## have more members than `x`. That is, `x` can be equal to `y`.
  66. runnableExamples:
  67. let
  68. a = {3, 5}
  69. b = {1, 3, 5, 7}
  70. c = {2}
  71. assert a <= b
  72. assert a <= a
  73. assert not (a <= c)
  74. proc `<=`*(x, y: bool): bool {.magic: "LeB", noSideEffect.}
  75. proc `<=`*[T](x, y: ref T): bool {.magic: "LePtr", noSideEffect.}
  76. proc `<=`*(x, y: pointer): bool {.magic: "LePtr", noSideEffect.}
  77. proc `<`*[Enum: enum](x, y: Enum): bool {.magic: "LtEnum", noSideEffect.}
  78. proc `<`*(x, y: string): bool {.magic: "LtStr", noSideEffect.} =
  79. ## Compares two strings and returns true if `x` is lexicographically
  80. ## before `y` (uppercase letters come before lowercase letters).
  81. runnableExamples:
  82. let
  83. a = "abc"
  84. b = "abd"
  85. c = "ZZZ"
  86. assert a < b
  87. assert not (a < a)
  88. assert not (a < c)
  89. proc `<`*(x, y: char): bool {.magic: "LtCh", noSideEffect.} =
  90. ## Compares two chars and returns true if `x` is lexicographically
  91. ## before `y` (uppercase letters come before lowercase letters).
  92. runnableExamples:
  93. let
  94. a = 'a'
  95. b = 'b'
  96. c = 'Z'
  97. assert a < b
  98. assert not (a < a)
  99. assert not (a < c)
  100. proc `<`*[T](x, y: set[T]): bool {.magic: "LtSet", noSideEffect.} =
  101. ## Returns true if `x` is a strict or proper subset of `y`.
  102. ##
  103. ## A strict or proper subset `x` has all of its members in `y` but `y` has
  104. ## more elements than `y`.
  105. runnableExamples:
  106. let
  107. a = {3, 5}
  108. b = {1, 3, 5, 7}
  109. c = {2}
  110. assert a < b
  111. assert not (a < a)
  112. assert not (a < c)
  113. proc `<`*(x, y: bool): bool {.magic: "LtB", noSideEffect.}
  114. proc `<`*[T](x, y: ref T): bool {.magic: "LtPtr", noSideEffect.}
  115. proc `<`*[T](x, y: ptr T): bool {.magic: "LtPtr", noSideEffect.}
  116. proc `<`*(x, y: pointer): bool {.magic: "LtPtr", noSideEffect.}
  117. template `!=`*(x, y: untyped): untyped =
  118. ## Unequals operator. This is a shorthand for `not (x == y)`.
  119. not (x == y)
  120. template `>=`*(x, y: untyped): untyped =
  121. ## "is greater or equals" operator. This is the same as `y <= x`.
  122. y <= x
  123. template `>`*(x, y: untyped): untyped =
  124. ## "is greater" operator. This is the same as `y < x`.
  125. y < x
  126. proc `==`*(x, y: int): bool {.magic: "EqI", noSideEffect.}
  127. ## Compares two integers for equality.
  128. proc `==`*(x, y: int8): bool {.magic: "EqI", noSideEffect.}
  129. proc `==`*(x, y: int16): bool {.magic: "EqI", noSideEffect.}
  130. proc `==`*(x, y: int32): bool {.magic: "EqI", noSideEffect.}
  131. proc `==`*(x, y: int64): bool {.magic: "EqI", noSideEffect.}
  132. proc `<=`*(x, y: int): bool {.magic: "LeI", noSideEffect.}
  133. ## Returns true if `x` is less than or equal to `y`.
  134. proc `<=`*(x, y: int8): bool {.magic: "LeI", noSideEffect.}
  135. proc `<=`*(x, y: int16): bool {.magic: "LeI", noSideEffect.}
  136. proc `<=`*(x, y: int32): bool {.magic: "LeI", noSideEffect.}
  137. proc `<=`*(x, y: int64): bool {.magic: "LeI", noSideEffect.}
  138. proc `<`*(x, y: int): bool {.magic: "LtI", noSideEffect.}
  139. ## Returns true if `x` is less than `y`.
  140. proc `<`*(x, y: int8): bool {.magic: "LtI", noSideEffect.}
  141. proc `<`*(x, y: int16): bool {.magic: "LtI", noSideEffect.}
  142. proc `<`*(x, y: int32): bool {.magic: "LtI", noSideEffect.}
  143. proc `<`*(x, y: int64): bool {.magic: "LtI", noSideEffect.}
  144. proc `<=`*(x, y: uint): bool {.magic: "LeU", noSideEffect.}
  145. ## Returns true if `x <= y`.
  146. proc `<=`*(x, y: uint8): bool {.magic: "LeU", noSideEffect.}
  147. proc `<=`*(x, y: uint16): bool {.magic: "LeU", noSideEffect.}
  148. proc `<=`*(x, y: uint32): bool {.magic: "LeU", noSideEffect.}
  149. proc `<=`*(x, y: uint64): bool {.magic: "LeU", noSideEffect.}
  150. proc `<`*(x, y: uint): bool {.magic: "LtU", noSideEffect.}
  151. ## Returns true if `x < y`.
  152. proc `<`*(x, y: uint8): bool {.magic: "LtU", noSideEffect.}
  153. proc `<`*(x, y: uint16): bool {.magic: "LtU", noSideEffect.}
  154. proc `<`*(x, y: uint32): bool {.magic: "LtU", noSideEffect.}
  155. proc `<`*(x, y: uint64): bool {.magic: "LtU", noSideEffect.}
  156. proc `<=%`*(x, y: int): bool {.inline.} =
  157. ## Treats `x` and `y` as unsigned and compares them.
  158. ## Returns true if `unsigned(x) <= unsigned(y)`.
  159. cast[uint](x) <= cast[uint](y)
  160. proc `<=%`*(x, y: int8): bool {.inline.} = cast[uint8](x) <= cast[uint8](y)
  161. proc `<=%`*(x, y: int16): bool {.inline.} = cast[uint16](x) <= cast[uint16](y)
  162. proc `<=%`*(x, y: int32): bool {.inline.} = cast[uint32](x) <= cast[uint32](y)
  163. proc `<=%`*(x, y: int64): bool {.inline.} = cast[uint64](x) <= cast[uint64](y)
  164. proc `<%`*(x, y: int): bool {.inline.} =
  165. ## Treats `x` and `y` as unsigned and compares them.
  166. ## Returns true if `unsigned(x) < unsigned(y)`.
  167. cast[uint](x) < cast[uint](y)
  168. proc `<%`*(x, y: int8): bool {.inline.} = cast[uint8](x) < cast[uint8](y)
  169. proc `<%`*(x, y: int16): bool {.inline.} = cast[uint16](x) < cast[uint16](y)
  170. proc `<%`*(x, y: int32): bool {.inline.} = cast[uint32](x) < cast[uint32](y)
  171. proc `<%`*(x, y: int64): bool {.inline.} = cast[uint64](x) < cast[uint64](y)
  172. template `>=%`*(x, y: untyped): untyped = y <=% x
  173. ## Treats `x` and `y` as unsigned and compares them.
  174. ## Returns true if `unsigned(x) >= unsigned(y)`.
  175. template `>%`*(x, y: untyped): untyped = y <% x
  176. ## Treats `x` and `y` as unsigned and compares them.
  177. ## Returns true if `unsigned(x) > unsigned(y)`.
  178. proc `==`*(x, y: uint): bool {.magic: "EqI", noSideEffect.}
  179. ## Compares two unsigned integers for equality.
  180. proc `==`*(x, y: uint8): bool {.magic: "EqI", noSideEffect.}
  181. proc `==`*(x, y: uint16): bool {.magic: "EqI", noSideEffect.}
  182. proc `==`*(x, y: uint32): bool {.magic: "EqI", noSideEffect.}
  183. proc `==`*(x, y: uint64): bool {.magic: "EqI", noSideEffect.}
  184. {.push stackTrace: off.}
  185. proc min*(x, y: int): int {.magic: "MinI", noSideEffect.} =
  186. if x <= y: x else: y
  187. proc min*(x, y: int8): int8 {.magic: "MinI", noSideEffect.} =
  188. if x <= y: x else: y
  189. proc min*(x, y: int16): int16 {.magic: "MinI", noSideEffect.} =
  190. if x <= y: x else: y
  191. proc min*(x, y: int32): int32 {.magic: "MinI", noSideEffect.} =
  192. if x <= y: x else: y
  193. proc min*(x, y: int64): int64 {.magic: "MinI", noSideEffect.} =
  194. ## The minimum value of two integers.
  195. if x <= y: x else: y
  196. proc max*(x, y: int): int {.magic: "MaxI", noSideEffect.} =
  197. if y <= x: x else: y
  198. proc max*(x, y: int8): int8 {.magic: "MaxI", noSideEffect.} =
  199. if y <= x: x else: y
  200. proc max*(x, y: int16): int16 {.magic: "MaxI", noSideEffect.} =
  201. if y <= x: x else: y
  202. proc max*(x, y: int32): int32 {.magic: "MaxI", noSideEffect.} =
  203. if y <= x: x else: y
  204. proc max*(x, y: int64): int64 {.magic: "MaxI", noSideEffect.} =
  205. ## The maximum value of two integers.
  206. if y <= x: x else: y
  207. proc min*[T](x: openArray[T]): T =
  208. ## The minimum value of `x`. `T` needs to have a `<` operator.
  209. result = x[0]
  210. for i in 1..high(x):
  211. if x[i] < result: result = x[i]
  212. proc max*[T](x: openArray[T]): T =
  213. ## The maximum value of `x`. `T` needs to have a `<` operator.
  214. result = x[0]
  215. for i in 1..high(x):
  216. if result < x[i]: result = x[i]
  217. {.pop.} # stackTrace: off
  218. proc clamp*[T](x, a, b: T): T =
  219. ## Limits the value `x` within the interval [a, b].
  220. ## This proc is equivalent to but faster than `max(a, min(b, x))`.
  221. ##
  222. ## .. warning:: `a <= b` is assumed and will not be checked (currently).
  223. ##
  224. ## **See also:**
  225. ## `math.clamp` for a version that takes a `Slice[T]` instead.
  226. runnableExamples:
  227. assert (1.4).clamp(0.0, 1.0) == 1.0
  228. assert (0.5).clamp(0.0, 1.0) == 0.5
  229. assert 4.clamp(1, 3) == max(1, min(3, 4))
  230. if x < a: return a
  231. if x > b: return b
  232. return x
  233. proc `==`*[I, T](x, y: array[I, T]): bool =
  234. for f in low(x)..high(x):
  235. if x[f] != y[f]:
  236. return
  237. result = true
  238. proc `==`*[T](x, y: openArray[T]): bool =
  239. if x.len != y.len:
  240. return false
  241. for f in low(x)..high(x):
  242. if x[f] != y[f]:
  243. return false
  244. result = true
  245. proc `==`*[T](x, y: seq[T]): bool {.noSideEffect.} =
  246. ## Generic equals operator for sequences: relies on a equals operator for
  247. ## the element type `T`.
  248. when nimvm:
  249. if x.len == 0 and y.len == 0:
  250. return true
  251. else:
  252. when not defined(js):
  253. proc seqToPtr[T](x: seq[T]): pointer {.inline, noSideEffect.} =
  254. when defined(nimSeqsV2):
  255. result = cast[NimSeqV2[T]](x).p
  256. else:
  257. result = cast[pointer](x)
  258. if seqToPtr(x) == seqToPtr(y):
  259. return true
  260. else:
  261. var sameObject = false
  262. asm """`sameObject` = `x` === `y`"""
  263. if sameObject: return true
  264. if x.len != y.len:
  265. return false
  266. for i in 0..x.len-1:
  267. if x[i] != y[i]:
  268. return false
  269. return true