1proc succ*[T: Ordinal](x: T, y = 1): T {.magic: "Succ", noSideEffect.} =
2  ## Returns the `y`-th successor (default: 1) of the value `x`.
3  ##
4  ## If such a value does not exist, `OverflowDefect` is raised
5  ## or a compile time error occurs.
6  runnableExamples:
7    assert succ(5) == 6
8    assert succ(5, 3) == 8
9
10proc pred*[T: Ordinal](x: T, y = 1): T {.magic: "Pred", noSideEffect.} =
11  ## Returns the `y`-th predecessor (default: 1) of the value `x`.
12  ##
13  ## If such a value does not exist, `OverflowDefect` is raised
14  ## or a compile time error occurs.
15  runnableExamples:
16    assert pred(5) == 4
17    assert pred(5, 3) == 2
18
19proc inc*[T: Ordinal](x: var T, y = 1) {.magic: "Inc", noSideEffect.} =
20  ## Increments the ordinal `x` by `y`.
21  ##
22  ## If such a value does not exist, `OverflowDefect` is raised or a compile
23  ## time error occurs. This is a short notation for: `x = succ(x, y)`.
24  runnableExamples:
25    var i = 2
26    inc(i)
27    assert i == 3
28    inc(i, 3)
29    assert i == 6
30
31proc dec*[T: Ordinal](x: var T, y = 1) {.magic: "Dec", noSideEffect.} =
32  ## Decrements the ordinal `x` by `y`.
33  ##
34  ## If such a value does not exist, `OverflowDefect` is raised or a compile
35  ## time error occurs. This is a short notation for: `x = pred(x, y)`.
36  runnableExamples:
37    var i = 2
38    dec(i)
39    assert i == 1
40    dec(i, 3)
41    assert i == -2
42
43
44
45# --------------------------------------------------------------------------
46# built-in operators
47
48when defined(nimNoZeroExtendMagic):
49  proc ze*(x: int8): int {.deprecated.} =
50    ## zero extends a smaller integer type to `int`. This treats `x` as
51    ## unsigned.
52    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
53    cast[int](uint(cast[uint8](x)))
54
55  proc ze*(x: int16): int {.deprecated.} =
56    ## zero extends a smaller integer type to `int`. This treats `x` as
57    ## unsigned.
58    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
59    cast[int](uint(cast[uint16](x)))
60
61  proc ze64*(x: int8): int64 {.deprecated.} =
62    ## zero extends a smaller integer type to `int64`. This treats `x` as
63    ## unsigned.
64    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
65    cast[int64](uint64(cast[uint8](x)))
66
67  proc ze64*(x: int16): int64 {.deprecated.} =
68    ## zero extends a smaller integer type to `int64`. This treats `x` as
69    ## unsigned.
70    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
71    cast[int64](uint64(cast[uint16](x)))
72
73  proc ze64*(x: int32): int64 {.deprecated.} =
74    ## zero extends a smaller integer type to `int64`. This treats `x` as
75    ## unsigned.
76    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
77    cast[int64](uint64(cast[uint32](x)))
78
79  proc ze64*(x: int): int64 {.deprecated.} =
80    ## zero extends a smaller integer type to `int64`. This treats `x` as
81    ## unsigned. Does nothing if the size of an `int` is the same as `int64`.
82    ## (This is the case on 64 bit processors.)
83    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
84    cast[int64](uint64(cast[uint](x)))
85
86  proc toU8*(x: int): int8 {.deprecated.} =
87    ## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
88    ## from `x`.
89    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
90    cast[int8](x)
91
92  proc toU16*(x: int): int16 {.deprecated.} =
93    ## treats `x` as unsigned and converts it to an `int16` by taking the last
94    ## 16 bits from `x`.
95    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
96    cast[int16](x)
97
98  proc toU32*(x: int64): int32 {.deprecated.} =
99    ## treats `x` as unsigned and converts it to an `int32` by taking the
100    ## last 32 bits from `x`.
101    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
102    cast[int32](x)
103
104elif not defined(js):
105  proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect, deprecated.}
106    ## zero extends a smaller integer type to `int`. This treats `x` as
107    ## unsigned.
108    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
109
110  proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect, deprecated.}
111    ## zero extends a smaller integer type to `int`. This treats `x` as
112    ## unsigned.
113    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
114
115  proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect, deprecated.}
116    ## zero extends a smaller integer type to `int64`. This treats `x` as
117    ## unsigned.
118    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
119
120  proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect, deprecated.}
121    ## zero extends a smaller integer type to `int64`. This treats `x` as
122    ## unsigned.
123    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
124
125  proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect, deprecated.}
126    ## zero extends a smaller integer type to `int64`. This treats `x` as
127    ## unsigned.
128    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
129
130  proc ze64*(x: int): int64 {.magic: "ZeIToI64", noSideEffect, deprecated.}
131    ## zero extends a smaller integer type to `int64`. This treats `x` as
132    ## unsigned. Does nothing if the size of an `int` is the same as `int64`.
133    ## (This is the case on 64 bit processors.)
134    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
135
136  proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect, deprecated.}
137    ## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
138    ## from `x`.
139    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
140
141  proc toU16*(x: int): int16 {.magic: "ToU16", noSideEffect, deprecated.}
142    ## treats `x` as unsigned and converts it to an `int16` by taking the last
143    ## 16 bits from `x`.
144    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
145
146  proc toU32*(x: int64): int32 {.magic: "ToU32", noSideEffect, deprecated.}
147    ## treats `x` as unsigned and converts it to an `int32` by taking the
148    ## last 32 bits from `x`.
149    ## **Deprecated since version 0.19.9**: Use unsigned integers instead.
150
151# integer calculations:
152proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
153  ## Unary `+` operator for an integer. Has no effect.
154proc `+`*(x: int8): int8 {.magic: "UnaryPlusI", noSideEffect.}
155proc `+`*(x: int16): int16 {.magic: "UnaryPlusI", noSideEffect.}
156proc `+`*(x: int32): int32 {.magic: "UnaryPlusI", noSideEffect.}
157proc `+`*(x: int64): int64 {.magic: "UnaryPlusI", noSideEffect.}
158
159proc `-`*(x: int): int {.magic: "UnaryMinusI", noSideEffect.}
160  ## Unary `-` operator for an integer. Negates `x`.
161proc `-`*(x: int8): int8 {.magic: "UnaryMinusI", noSideEffect.}
162proc `-`*(x: int16): int16 {.magic: "UnaryMinusI", noSideEffect.}
163proc `-`*(x: int32): int32 {.magic: "UnaryMinusI", noSideEffect.}
164proc `-`*(x: int64): int64 {.magic: "UnaryMinusI64", noSideEffect.}
165
166proc `not`*(x: int): int {.magic: "BitnotI", noSideEffect.} =
167  ## Computes the `bitwise complement` of the integer `x`.
168  runnableExamples:
169    assert not 0'u8 == 255
170    assert not 0'i8 == -1
171    assert not 1000'u16 == 64535
172    assert not 1000'i16 == -1001
173proc `not`*(x: int8): int8 {.magic: "BitnotI", noSideEffect.}
174proc `not`*(x: int16): int16 {.magic: "BitnotI", noSideEffect.}
175proc `not`*(x: int32): int32 {.magic: "BitnotI", noSideEffect.}
176proc `not`*(x: int64): int64 {.magic: "BitnotI", noSideEffect.}
177
178proc `+`*(x, y: int): int {.magic: "AddI", noSideEffect.}
179  ## Binary `+` operator for an integer.
180proc `+`*(x, y: int8): int8 {.magic: "AddI", noSideEffect.}
181proc `+`*(x, y: int16): int16 {.magic: "AddI", noSideEffect.}
182proc `+`*(x, y: int32): int32 {.magic: "AddI", noSideEffect.}
183proc `+`*(x, y: int64): int64 {.magic: "AddI", noSideEffect.}
184
185proc `-`*(x, y: int): int {.magic: "SubI", noSideEffect.}
186  ## Binary `-` operator for an integer.
187proc `-`*(x, y: int8): int8 {.magic: "SubI", noSideEffect.}
188proc `-`*(x, y: int16): int16 {.magic: "SubI", noSideEffect.}
189proc `-`*(x, y: int32): int32 {.magic: "SubI", noSideEffect.}
190proc `-`*(x, y: int64): int64 {.magic: "SubI", noSideEffect.}
191
192proc `*`*(x, y: int): int {.magic: "MulI", noSideEffect.}
193  ## Binary `*` operator for an integer.
194proc `*`*(x, y: int8): int8 {.magic: "MulI", noSideEffect.}
195proc `*`*(x, y: int16): int16 {.magic: "MulI", noSideEffect.}
196proc `*`*(x, y: int32): int32 {.magic: "MulI", noSideEffect.}
197proc `*`*(x, y: int64): int64 {.magic: "MulI", noSideEffect.}
198
199proc `div`*(x, y: int): int {.magic: "DivI", noSideEffect.} =
200  ## Computes the integer division.
201  ##
202  ## This is roughly the same as `math.trunc(x/y).int`.
203  runnableExamples:
204    assert (1 div 2) == 0
205    assert (2 div 2) == 1
206    assert (3 div 2) == 1
207    assert (7 div 3) == 2
208    assert (-7 div 3) == -2
209    assert (7 div -3) == -2
210    assert (-7 div -3) == 2
211proc `div`*(x, y: int8): int8 {.magic: "DivI", noSideEffect.}
212proc `div`*(x, y: int16): int16 {.magic: "DivI", noSideEffect.}
213proc `div`*(x, y: int32): int32 {.magic: "DivI", noSideEffect.}
214proc `div`*(x, y: int64): int64 {.magic: "DivI", noSideEffect.}
215
216proc `mod`*(x, y: int): int {.magic: "ModI", noSideEffect.} =
217  ## Computes the integer modulo operation (remainder).
218  ##
219  ## This is the same as `x - (x div y) * y`.
220  runnableExamples:
221    assert (7 mod 5) == 2
222    assert (-7 mod 5) == -2
223    assert (7 mod -5) == 2
224    assert (-7 mod -5) == -2
225proc `mod`*(x, y: int8): int8 {.magic: "ModI", noSideEffect.}
226proc `mod`*(x, y: int16): int16 {.magic: "ModI", noSideEffect.}
227proc `mod`*(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
228proc `mod`*(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
229
230when defined(nimOldShiftRight):
231  const shrDepMessage = "`shr` will become sign preserving."
232  proc `shr`*(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
233  proc `shr`*(x: int8, y: SomeInteger): int8 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
234  proc `shr`*(x: int16, y: SomeInteger): int16 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
235  proc `shr`*(x: int32, y: SomeInteger): int32 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
236  proc `shr`*(x: int64, y: SomeInteger): int64 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
237else:
238  proc `shr`*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
239    ## Computes the `shift right` operation of `x` and `y`, filling
240    ## vacant bit positions with the sign bit.
241    ##
242    ## **Note**: `Operator precedence <manual.html#syntax-precedence>`_
243    ## is different than in *C*.
244    ##
245    ## See also:
246    ## * `ashr func<#ashr,int,SomeInteger>`_ for arithmetic shift right
247    runnableExamples:
248      assert 0b0001_0000'i8 shr 2 == 0b0000_0100'i8
249      assert 0b0000_0001'i8 shr 1 == 0b0000_0000'i8
250      assert 0b1000_0000'i8 shr 4 == 0b1111_1000'i8
251      assert -1 shr 5 == -1
252      assert 1 shr 5 == 0
253      assert 16 shr 2 == 4
254      assert -16 shr 2 == -4
255  proc `shr`*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
256  proc `shr`*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
257  proc `shr`*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
258  proc `shr`*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
259
260
261proc `shl`*(x: int, y: SomeInteger): int {.magic: "ShlI", noSideEffect.} =
262  ## Computes the `shift left` operation of `x` and `y`.
263  ##
264  ## **Note**: `Operator precedence <manual.html#syntax-precedence>`_
265  ## is different than in *C*.
266  runnableExamples:
267    assert 1'i32 shl 4 == 0x0000_0010
268    assert 1'i64 shl 4 == 0x0000_0000_0000_0010
269proc `shl`*(x: int8, y: SomeInteger): int8 {.magic: "ShlI", noSideEffect.}
270proc `shl`*(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.}
271proc `shl`*(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.}
272proc `shl`*(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
273
274proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
275  ## Shifts right by pushing copies of the leftmost bit in from the left,
276  ## and let the rightmost bits fall off.
277  ##
278  ## Note that `ashr` is not an operator so use the normal function
279  ## call syntax for it.
280  ##
281  ## See also:
282  ## * `shr func<#shr,int,SomeInteger>`_
283  runnableExamples:
284    assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
285    assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
286    assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
287proc ashr*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
288proc ashr*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
289proc ashr*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
290proc ashr*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
291
292proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.} =
293  ## Computes the `bitwise and` of numbers `x` and `y`.
294  runnableExamples:
295    assert (0b0011 and 0b0101) == 0b0001
296    assert (0b0111 and 0b1100) == 0b0100
297proc `and`*(x, y: int8): int8 {.magic: "BitandI", noSideEffect.}
298proc `and`*(x, y: int16): int16 {.magic: "BitandI", noSideEffect.}
299proc `and`*(x, y: int32): int32 {.magic: "BitandI", noSideEffect.}
300proc `and`*(x, y: int64): int64 {.magic: "BitandI", noSideEffect.}
301
302proc `or`*(x, y: int): int {.magic: "BitorI", noSideEffect.} =
303  ## Computes the `bitwise or` of numbers `x` and `y`.
304  runnableExamples:
305    assert (0b0011 or 0b0101) == 0b0111
306    assert (0b0111 or 0b1100) == 0b1111
307proc `or`*(x, y: int8): int8 {.magic: "BitorI", noSideEffect.}
308proc `or`*(x, y: int16): int16 {.magic: "BitorI", noSideEffect.}
309proc `or`*(x, y: int32): int32 {.magic: "BitorI", noSideEffect.}
310proc `or`*(x, y: int64): int64 {.magic: "BitorI", noSideEffect.}
311
312proc `xor`*(x, y: int): int {.magic: "BitxorI", noSideEffect.} =
313  ## Computes the `bitwise xor` of numbers `x` and `y`.
314  runnableExamples:
315    assert (0b0011 xor 0b0101) == 0b0110
316    assert (0b0111 xor 0b1100) == 0b1011
317proc `xor`*(x, y: int8): int8 {.magic: "BitxorI", noSideEffect.}
318proc `xor`*(x, y: int16): int16 {.magic: "BitxorI", noSideEffect.}
319proc `xor`*(x, y: int32): int32 {.magic: "BitxorI", noSideEffect.}
320proc `xor`*(x, y: int64): int64 {.magic: "BitxorI", noSideEffect.}
321
322# unsigned integer operations:
323proc `not`*(x: uint): uint {.magic: "BitnotI", noSideEffect.}
324  ## Computes the `bitwise complement` of the integer `x`.
325proc `not`*(x: uint8): uint8 {.magic: "BitnotI", noSideEffect.}
326proc `not`*(x: uint16): uint16 {.magic: "BitnotI", noSideEffect.}
327proc `not`*(x: uint32): uint32 {.magic: "BitnotI", noSideEffect.}
328proc `not`*(x: uint64): uint64 {.magic: "BitnotI", noSideEffect.}
329
330proc `shr`*(x: uint, y: SomeInteger): uint {.magic: "ShrI", noSideEffect.}
331  ## Computes the `shift right` operation of `x` and `y`.
332proc `shr`*(x: uint8, y: SomeInteger): uint8 {.magic: "ShrI", noSideEffect.}
333proc `shr`*(x: uint16, y: SomeInteger): uint16 {.magic: "ShrI", noSideEffect.}
334proc `shr`*(x: uint32, y: SomeInteger): uint32 {.magic: "ShrI", noSideEffect.}
335proc `shr`*(x: uint64, y: SomeInteger): uint64 {.magic: "ShrI", noSideEffect.}
336
337proc `shl`*(x: uint, y: SomeInteger): uint {.magic: "ShlI", noSideEffect.}
338  ## Computes the `shift left` operation of `x` and `y`.
339proc `shl`*(x: uint8, y: SomeInteger): uint8 {.magic: "ShlI", noSideEffect.}
340proc `shl`*(x: uint16, y: SomeInteger): uint16 {.magic: "ShlI", noSideEffect.}
341proc `shl`*(x: uint32, y: SomeInteger): uint32 {.magic: "ShlI", noSideEffect.}
342proc `shl`*(x: uint64, y: SomeInteger): uint64 {.magic: "ShlI", noSideEffect.}
343
344proc `and`*(x, y: uint): uint {.magic: "BitandI", noSideEffect.}
345  ## Computes the `bitwise and` of numbers `x` and `y`.
346proc `and`*(x, y: uint8): uint8 {.magic: "BitandI", noSideEffect.}
347proc `and`*(x, y: uint16): uint16 {.magic: "BitandI", noSideEffect.}
348proc `and`*(x, y: uint32): uint32 {.magic: "BitandI", noSideEffect.}
349proc `and`*(x, y: uint64): uint64 {.magic: "BitandI", noSideEffect.}
350
351proc `or`*(x, y: uint): uint {.magic: "BitorI", noSideEffect.}
352  ## Computes the `bitwise or` of numbers `x` and `y`.
353proc `or`*(x, y: uint8): uint8 {.magic: "BitorI", noSideEffect.}
354proc `or`*(x, y: uint16): uint16 {.magic: "BitorI", noSideEffect.}
355proc `or`*(x, y: uint32): uint32 {.magic: "BitorI", noSideEffect.}
356proc `or`*(x, y: uint64): uint64 {.magic: "BitorI", noSideEffect.}
357
358proc `xor`*(x, y: uint): uint {.magic: "BitxorI", noSideEffect.}
359  ## Computes the `bitwise xor` of numbers `x` and `y`.
360proc `xor`*(x, y: uint8): uint8 {.magic: "BitxorI", noSideEffect.}
361proc `xor`*(x, y: uint16): uint16 {.magic: "BitxorI", noSideEffect.}
362proc `xor`*(x, y: uint32): uint32 {.magic: "BitxorI", noSideEffect.}
363proc `xor`*(x, y: uint64): uint64 {.magic: "BitxorI", noSideEffect.}
364
365proc `+`*(x, y: uint): uint {.magic: "AddU", noSideEffect.}
366  ## Binary `+` operator for unsigned integers.
367proc `+`*(x, y: uint8): uint8 {.magic: "AddU", noSideEffect.}
368proc `+`*(x, y: uint16): uint16 {.magic: "AddU", noSideEffect.}
369proc `+`*(x, y: uint32): uint32 {.magic: "AddU", noSideEffect.}
370proc `+`*(x, y: uint64): uint64 {.magic: "AddU", noSideEffect.}
371
372proc `-`*(x, y: uint): uint {.magic: "SubU", noSideEffect.}
373  ## Binary `-` operator for unsigned integers.
374proc `-`*(x, y: uint8): uint8 {.magic: "SubU", noSideEffect.}
375proc `-`*(x, y: uint16): uint16 {.magic: "SubU", noSideEffect.}
376proc `-`*(x, y: uint32): uint32 {.magic: "SubU", noSideEffect.}
377proc `-`*(x, y: uint64): uint64 {.magic: "SubU", noSideEffect.}
378
379proc `*`*(x, y: uint): uint {.magic: "MulU", noSideEffect.}
380  ## Binary `*` operator for unsigned integers.
381proc `*`*(x, y: uint8): uint8 {.magic: "MulU", noSideEffect.}
382proc `*`*(x, y: uint16): uint16 {.magic: "MulU", noSideEffect.}
383proc `*`*(x, y: uint32): uint32 {.magic: "MulU", noSideEffect.}
384proc `*`*(x, y: uint64): uint64 {.magic: "MulU", noSideEffect.}
385
386proc `div`*(x, y: uint): uint {.magic: "DivU", noSideEffect.}
387  ## Computes the integer division for unsigned integers.
388  ## This is roughly the same as `trunc(x/y)`.
389proc `div`*(x, y: uint8): uint8 {.magic: "DivU", noSideEffect.}
390proc `div`*(x, y: uint16): uint16 {.magic: "DivU", noSideEffect.}
391proc `div`*(x, y: uint32): uint32 {.magic: "DivU", noSideEffect.}
392proc `div`*(x, y: uint64): uint64 {.magic: "DivU", noSideEffect.}
393
394proc `mod`*(x, y: uint): uint {.magic: "ModU", noSideEffect.}
395  ## Computes the integer modulo operation (remainder) for unsigned integers.
396  ## This is the same as `x - (x div y) * y`.
397proc `mod`*(x, y: uint8): uint8 {.magic: "ModU", noSideEffect.}
398proc `mod`*(x, y: uint16): uint16 {.magic: "ModU", noSideEffect.}
399proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
400proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
401
402proc `+%`*(x, y: int): int {.inline.} =
403  ## Treats `x` and `y` as unsigned and adds them.
404  ##
405  ## The result is truncated to fit into the result.
406  ## This implements modulo arithmetic. No overflow errors are possible.
407  cast[int](cast[uint](x) + cast[uint](y))
408proc `+%`*(x, y: int8): int8 {.inline.}   = cast[int8](cast[uint8](x) + cast[uint8](y))
409proc `+%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) + cast[uint16](y))
410proc `+%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) + cast[uint32](y))
411proc `+%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) + cast[uint64](y))
412
413proc `-%`*(x, y: int): int {.inline.} =
414  ## Treats `x` and `y` as unsigned and subtracts them.
415  ##
416  ## The result is truncated to fit into the result.
417  ## This implements modulo arithmetic. No overflow errors are possible.
418  cast[int](cast[uint](x) - cast[uint](y))
419proc `-%`*(x, y: int8): int8 {.inline.}   = cast[int8](cast[uint8](x) - cast[uint8](y))
420proc `-%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) - cast[uint16](y))
421proc `-%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) - cast[uint32](y))
422proc `-%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) - cast[uint64](y))
423
424proc `*%`*(x, y: int): int {.inline.} =
425  ## Treats `x` and `y` as unsigned and multiplies them.
426  ##
427  ## The result is truncated to fit into the result.
428  ## This implements modulo arithmetic. No overflow errors are possible.
429  cast[int](cast[uint](x) * cast[uint](y))
430proc `*%`*(x, y: int8): int8 {.inline.}   = cast[int8](cast[uint8](x) * cast[uint8](y))
431proc `*%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) * cast[uint16](y))
432proc `*%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) * cast[uint32](y))
433proc `*%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) * cast[uint64](y))
434
435proc `/%`*(x, y: int): int {.inline.} =
436  ## Treats `x` and `y` as unsigned and divides them.
437  ##
438  ## The result is truncated to fit into the result.
439  ## This implements modulo arithmetic. No overflow errors are possible.
440  cast[int](cast[uint](x) div cast[uint](y))
441proc `/%`*(x, y: int8): int8 {.inline.}   = cast[int8](cast[uint8](x) div cast[uint8](y))
442proc `/%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) div cast[uint16](y))
443proc `/%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) div cast[uint32](y))
444proc `/%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) div cast[uint64](y))
445
446proc `%%`*(x, y: int): int {.inline.} =
447  ## Treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
448  ##
449  ## The result is truncated to fit into the result.
450  ## This implements modulo arithmetic. No overflow errors are possible.
451  cast[int](cast[uint](x) mod cast[uint](y))
452proc `%%`*(x, y: int8): int8 {.inline.}   = cast[int8](cast[uint8](x) mod cast[uint8](y))
453proc `%%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) mod cast[uint16](y))
454proc `%%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) mod cast[uint32](y))
455proc `%%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) mod cast[uint64](y))
456
457proc `+=`*[T: SomeInteger](x: var T, y: T) {.
458  magic: "Inc", noSideEffect.}
459  ## Increments an integer.
460
461proc `-=`*[T: SomeInteger](x: var T, y: T) {.
462  magic: "Dec", noSideEffect.}
463  ## Decrements an integer.
464
465proc `*=`*[T: SomeInteger](x: var T, y: T) {.
466  inline, noSideEffect.} =
467  ## Binary `*=` operator for integers.
468  x = x * y
469