1// Copyright 2020 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package netip
6
7import (
8	"testing"
9)
10
11func TestUint128AddSub(t *testing.T) {
12	const add1 = 1
13	const sub1 = -1
14	tests := []struct {
15		in   uint128
16		op   int // +1 or -1 to add vs subtract
17		want uint128
18	}{
19		{uint128{0, 0}, add1, uint128{0, 1}},
20		{uint128{0, 1}, add1, uint128{0, 2}},
21		{uint128{1, 0}, add1, uint128{1, 1}},
22		{uint128{0, ^uint64(0)}, add1, uint128{1, 0}},
23		{uint128{^uint64(0), ^uint64(0)}, add1, uint128{0, 0}},
24
25		{uint128{0, 0}, sub1, uint128{^uint64(0), ^uint64(0)}},
26		{uint128{0, 1}, sub1, uint128{0, 0}},
27		{uint128{0, 2}, sub1, uint128{0, 1}},
28		{uint128{1, 0}, sub1, uint128{0, ^uint64(0)}},
29		{uint128{1, 1}, sub1, uint128{1, 0}},
30	}
31	for _, tt := range tests {
32		var got uint128
33		switch tt.op {
34		case add1:
35			got = tt.in.addOne()
36		case sub1:
37			got = tt.in.subOne()
38		default:
39			panic("bogus op")
40		}
41		if got != tt.want {
42			t.Errorf("%v add %d = %v; want %v", tt.in, tt.op, got, tt.want)
43		}
44	}
45}
46
47func TestBitsSetFrom(t *testing.T) {
48	tests := []struct {
49		bit  uint8
50		want uint128
51	}{
52		{0, uint128{^uint64(0), ^uint64(0)}},
53		{1, uint128{^uint64(0) >> 1, ^uint64(0)}},
54		{63, uint128{1, ^uint64(0)}},
55		{64, uint128{0, ^uint64(0)}},
56		{65, uint128{0, ^uint64(0) >> 1}},
57		{127, uint128{0, 1}},
58		{128, uint128{0, 0}},
59	}
60	for _, tt := range tests {
61		var zero uint128
62		got := zero.bitsSetFrom(tt.bit)
63		if got != tt.want {
64			t.Errorf("0.bitsSetFrom(%d) = %064b want %064b", tt.bit, got, tt.want)
65		}
66	}
67}
68
69func TestBitsClearedFrom(t *testing.T) {
70	tests := []struct {
71		bit  uint8
72		want uint128
73	}{
74		{0, uint128{0, 0}},
75		{1, uint128{1 << 63, 0}},
76		{63, uint128{^uint64(0) &^ 1, 0}},
77		{64, uint128{^uint64(0), 0}},
78		{65, uint128{^uint64(0), 1 << 63}},
79		{127, uint128{^uint64(0), ^uint64(0) &^ 1}},
80		{128, uint128{^uint64(0), ^uint64(0)}},
81	}
82	for _, tt := range tests {
83		ones := uint128{^uint64(0), ^uint64(0)}
84		got := ones.bitsClearedFrom(tt.bit)
85		if got != tt.want {
86			t.Errorf("ones.bitsClearedFrom(%d) = %064b want %064b", tt.bit, got, tt.want)
87		}
88	}
89}
90