-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbitwise.ts
94 lines (80 loc) · 3.74 KB
/
bitwise.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { int32 } from './integer'
import { AndMap, numeric, OrMap, XorMap } from './utils'
declare module './integer' {
export type And<A extends Integer, B extends Integer, R extends number[] = []> =
| A extends [number, ...infer X extends number[]]
? B extends [number, ...infer Y extends number[]]
? And<X, Y, [...R, AndMap[A[0]][B[0]]]>
: R
: R
export type Or<A extends Integer, B extends Integer, R extends number[] = []> =
| A extends [number, ...infer X extends number[]]
? B extends [number, ...infer Y extends number[]]
? Or<X, Y, [...R, OrMap[A[0]][B[0]]]>
: R
: R
export type Xor<A extends Integer, B extends Integer, R extends number[] = []> =
| A extends [number, ...infer X extends number[]]
? B extends [number, ...infer Y extends number[]]
? Xor<X, Y, [...R, XorMap[A[0]][B[0]]]>
: R
: R
export type LShift<A extends Integer, B extends number, C extends number[] = []> =
| C['length'] extends B
? A
: A extends [number, ...infer X extends number[]]
? LShift<[...X, 0], B, [...C, 0]>
: never
export type RShift<A extends Integer, B extends number, C extends number[] = []> =
| C['length'] extends B
? A
: A extends [...infer X extends number[], number]
? RShift<[A[0], ...X], B, [...C, 0]>
: never
export type URShift<A extends Integer, B extends number, C extends number[] = []> =
| C['length'] extends B
? A
: A extends [...infer X extends number[], number]
? RShift<[0, ...X], B, [...C, 0]>
: never
namespace int32 {
export type and<X extends numeric, Y extends numeric> = Decode<And<Encode<X>, Encode<Y>>>
export type or<X extends numeric, Y extends numeric> = Decode<Or<Encode<X>, Encode<Y>>>
export type xor<X extends numeric, Y extends numeric> = Decode<Xor<Encode<X>, Encode<Y>>>
export type lshift<X extends numeric, Y extends number> = Decode<LShift<Encode<X>, Y>>
export type rshift<X extends numeric, Y extends number> = Decode<RShift<Encode<X>, Y>>
export type urshift<X extends numeric, Y extends number> = Decode<URShift<Encode<X>, Y>>
}
namespace int64 {
export type and<X extends numeric, Y extends numeric> = Decode<And<Encode<X>, Encode<Y>>>
export type or<X extends numeric, Y extends numeric> = Decode<Or<Encode<X>, Encode<Y>>>
export type xor<X extends numeric, Y extends numeric> = Decode<Xor<Encode<X>, Encode<Y>>>
export type lshift<X extends numeric, Y extends number> = Decode<LShift<Encode<X>, Y>>
export type rshift<X extends numeric, Y extends number> = Decode<RShift<Encode<X>, Y>>
export type urshift<X extends numeric, Y extends number> = Decode<URShift<Encode<X>, Y>>
}
}
export type and<X extends number, Y extends number> = int32.and<X, Y>
export function and<X extends number, Y extends number>(x: X, y: Y): and<X, Y> {
return (x & y) as any
}
export type or<X extends number, Y extends number> = int32.or<X, Y>
export function or<X extends number, Y extends number>(x: X, y: Y): or<X, Y> {
return (x | y) as any
}
export type xor<X extends number, Y extends number> = int32.xor<X, Y>
export function xor<X extends number, Y extends number>(x: X, y: Y): xor<X, Y> {
return (x ^ y) as any
}
export type lshift<X extends number, Y extends number> = int32.lshift<X, Y>
export function lshift<X extends number, Y extends number>(x: X, y: Y): lshift<X, Y> {
return (x << y) as any
}
export type rshift<X extends number, Y extends number> = int32.rshift<X, Y>
export function rshift<X extends number, Y extends number>(x: X, y: Y): rshift<X, Y> {
return (x >> y) as any
}
export type urshift<X extends number, Y extends number> = int32.urshift<X, Y>
export function urshift<X extends number, Y extends number>(x: X, y: Y): urshift<X, Y> {
return (x >>> y) as any
}