github.com/mitranim/gg@v0.1.17/unsafe_test.go (about) 1 package gg_test 2 3 import ( 4 "math" 5 r "reflect" 6 "testing" 7 u "unsafe" 8 9 "github.com/mitranim/gg" 10 "github.com/mitranim/gg/gtest" 11 ) 12 13 func TestAnyNoEscUnsafe(t *testing.T) { 14 defer gtest.Catch(t) 15 16 testAnyNoEscUnsafe(any(nil)) 17 testAnyNoEscUnsafe(``) 18 testAnyNoEscUnsafe(`str`) 19 testAnyNoEscUnsafe(0) 20 testAnyNoEscUnsafe(10) 21 testAnyNoEscUnsafe(SomeModel{}) 22 testAnyNoEscUnsafe((func())(nil)) 23 } 24 25 /* 26 This doesn't verify that the value doesn't escape, because it's tricky to 27 implement for different types. Instead, various benchmarks serve as indirect 28 indicators. 29 */ 30 func testAnyNoEscUnsafe[A any](src A) { 31 tar := gg.AnyNoEscUnsafe(src) 32 gtest.Equal(r.TypeOf(tar), r.TypeOf(src)) 33 gtest.Equal(tar, any(src)) 34 } 35 36 func BenchmarkAnyNoEscUnsafe(b *testing.B) { 37 for ind := 0; ind < b.N; ind++ { 38 val := []int{ind} 39 gg.Nop1(esc(gg.AnyNoEscUnsafe(val))) 40 } 41 } 42 43 func BenchmarkSize(b *testing.B) { 44 defer gtest.Catch(b) 45 46 for ind := 0; ind < b.N; ind++ { 47 gg.Nop1(gg.Size[string]()) 48 } 49 } 50 51 func TestAsBytes(t *testing.T) { 52 defer gtest.Catch(t) 53 54 gtest.Zero(gg.AsBytes[struct{}](nil)) 55 gtest.Zero(gg.AsBytes[bool](nil)) 56 gtest.Zero(gg.AsBytes[uint64](nil)) 57 58 { 59 var src struct{} 60 tar := gg.AsBytes(&src) 61 62 gtest.Equal(tar, []byte{}) 63 gtest.Eq(u.Pointer(u.SliceData(tar)), u.Pointer(&src)) 64 gtest.Eq(u.Pointer(u.SliceData(tar)), u.Pointer(u.SliceData([]struct{}{})), `zerobase`) 65 gtest.Len(tar, 0) 66 gtest.Cap(tar, 0) 67 } 68 69 { 70 var src bool 71 gtest.False(src) 72 73 tar := gg.AsBytes(&src) 74 75 gtest.Equal(tar, []byte{0}) 76 gtest.Eq(u.Pointer(u.SliceData(tar)), u.Pointer(&src)) 77 gtest.Len(tar, 1) 78 gtest.Cap(tar, 1) 79 80 tar[0] = 1 81 gtest.True(src) 82 } 83 84 { 85 var src uint64 86 gtest.Eq(src, 0) 87 88 tar := gg.AsBytes(&src) 89 90 gtest.Equal(tar, make([]byte, 8)) 91 gtest.Eq(u.Pointer(u.SliceData(tar)), u.Pointer(&src)) 92 gtest.Len(tar, 8) 93 gtest.Cap(tar, 8) 94 95 for ind := range tar { 96 tar[ind] = 255 97 } 98 99 gtest.Eq(src, math.MaxUint64) 100 } 101 } 102 103 func TestCast(t *testing.T) { 104 defer gtest.Catch(t) 105 106 gtest.PanicStr(`size mismatch: uint8 (size 1) vs int64 (size 8)`, func() { 107 gg.Cast[int64](byte(0)) 108 }) 109 110 gtest.PanicStr(`size mismatch: int64 (size 8) vs uint8 (size 1)`, func() { 111 gg.Cast[byte](int64(0)) 112 }) 113 114 gtest.PanicStr(`size mismatch: string (size 16) vs []uint8 (size 24)`, func() { 115 gg.Cast[[]byte](string(``)) 116 }) 117 118 gtest.PanicStr(`size mismatch: []uint8 (size 24) vs string (size 16)`, func() { 119 gg.Cast[string]([]byte(nil)) 120 }) 121 122 gtest.Zero(gg.Cast[struct{}]([0]struct{}{})) 123 gtest.Eq(gg.Cast[int8](uint8(math.MaxUint8)), -1) 124 gtest.Eq(gg.Cast[uint8](int8(math.MaxInt8)), 127) 125 gtest.Eq(gg.Cast[uint8](int8(math.MinInt8)), 128) 126 127 { 128 type Src [16]byte 129 type Tar struct{ Src } 130 131 src := Src([]byte(`ef1e7d2249dc45fc`)) 132 gtest.Eq(string(src[:]), `ef1e7d2249dc45fc`) 133 134 tar := gg.Cast[Tar](src) 135 gtest.Eq(tar.Src, src) 136 gtest.Eq(gg.Cast[Src](tar), src) 137 } 138 } 139 140 func TestCastSlice(t *testing.T) { 141 defer gtest.Catch(t) 142 143 gtest.PanicStr(`size mismatch: uint8 (size 1) vs int64 (size 8)`, func() { 144 gg.CastSlice[int64, byte](nil) 145 }) 146 147 gtest.PanicStr(`size mismatch: int64 (size 8) vs uint8 (size 1)`, func() { 148 gg.CastSlice[byte, int64](nil) 149 }) 150 151 gtest.PanicStr(`size mismatch: string (size 16) vs []uint8 (size 24)`, func() { 152 gg.CastSlice[[]byte, string](nil) 153 }) 154 155 gtest.PanicStr(`size mismatch: []uint8 (size 24) vs string (size 16)`, func() { 156 gg.CastSlice[string, []byte](nil) 157 }) 158 159 gtest.Zero(gg.CastSlice[uint8, int8](nil)) 160 gtest.Zero(gg.CastSlice[int8, uint8](nil)) 161 162 { 163 src := []int8{-128, -127, -1, 0, 1, 127} 164 tar := gg.CastSlice[uint8](src) 165 166 gtest.Equal(tar, []uint8{128, 129, 255, 0, 1, 127}) 167 gtest.Eq(u.Pointer(u.SliceData(tar)), u.Pointer(u.SliceData(src))) 168 gtest.Len(tar, len(src)) 169 gtest.Cap(tar, cap(src)) 170 } 171 }