xref: /aosp_15_r20/external/starlark-go/starlark/int_generic.go (revision 4947cdc739c985f6d86941e22894f5cefe7c9e9a)
1*4947cdc7SCole Faust// Always use this implementation, even for Posix-compliant platforms
2*4947cdc7SCole Faust// (upstream code uses the implementation in int_posix64.go, but we
3*4947cdc7SCole Faust// do not want to depend on golang.olg/x.sys/unix package).
4*4947cdc7SCole Faustpackage starlark
5*4947cdc7SCole Faust
6*4947cdc7SCole Faust// generic Int implementation as a union
7*4947cdc7SCole Faust
8*4947cdc7SCole Faustimport "math/big"
9*4947cdc7SCole Faust
10*4947cdc7SCole Fausttype intImpl struct {
11*4947cdc7SCole Faust	// We use only the signed 32-bit range of small to ensure
12*4947cdc7SCole Faust	// that small+small and small*small do not overflow.
13*4947cdc7SCole Faust	small_ int64    // minint32 <= small <= maxint32
14*4947cdc7SCole Faust	big_   *big.Int // big != nil <=> value is not representable as int32
15*4947cdc7SCole Faust}
16*4947cdc7SCole Faust
17*4947cdc7SCole Faust// --- low-level accessors ---
18*4947cdc7SCole Faust
19*4947cdc7SCole Faust// get returns the small and big components of the Int.
20*4947cdc7SCole Faust// small is defined only if big is nil.
21*4947cdc7SCole Faust// small is sign-extended to 64 bits for ease of subsequent arithmetic.
22*4947cdc7SCole Faustfunc (i Int) get() (small int64, big *big.Int) {
23*4947cdc7SCole Faust	return i.impl.small_, i.impl.big_
24*4947cdc7SCole Faust}
25*4947cdc7SCole Faust
26*4947cdc7SCole Faust// Precondition: math.MinInt32 <= x && x <= math.MaxInt32
27*4947cdc7SCole Faustfunc makeSmallInt(x int64) Int {
28*4947cdc7SCole Faust	return Int{intImpl{small_: x}}
29*4947cdc7SCole Faust}
30*4947cdc7SCole Faust
31*4947cdc7SCole Faust// Precondition: x cannot be represented as int32.
32*4947cdc7SCole Faustfunc makeBigInt(x *big.Int) Int {
33*4947cdc7SCole Faust	return Int{intImpl{big_: x}}
34*4947cdc7SCole Faust}
35