comparisons.nim 11 KB

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