github.com/goplus/llgo@v0.8.3/internal/runtime/z_slice.go (about)

     1  /*
     2   * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package runtime
    18  
    19  import (
    20  	"unsafe"
    21  
    22  	"github.com/goplus/llgo/internal/runtime/c"
    23  )
    24  
    25  // -----------------------------------------------------------------------------
    26  
    27  // Slice is the runtime representation of a slice.
    28  type Slice struct {
    29  	data unsafe.Pointer
    30  	len  int
    31  	cap  int
    32  }
    33  
    34  // NilSlice returns a nil slice.
    35  func NilSlice() Slice {
    36  	return Slice{nil, 0, 0}
    37  }
    38  
    39  // NewSlice creates a new slice.
    40  func NewSlice(data unsafe.Pointer, len, cap int) Slice {
    41  	return Slice{data, len, cap}
    42  }
    43  
    44  func NewSlice3(base unsafe.Pointer, eltSize, cap, i, j, k int) (s Slice) {
    45  	if i < 0 || j < i || k < j || k > cap {
    46  		panic("slice index out of bounds")
    47  	}
    48  	s.len = j - i
    49  	s.cap = k - i
    50  	if k-i > 0 {
    51  		s.data = c.Advance(base, i*eltSize)
    52  	} else {
    53  		s.data = base
    54  	}
    55  	return
    56  }
    57  
    58  // SliceLen returns the length of a slice.
    59  func SliceLen(s Slice) int {
    60  	return s.len
    61  }
    62  
    63  // SliceCap returns the capacity of a slice.
    64  func SliceCap(s Slice) int {
    65  	return s.cap
    66  }
    67  
    68  // SliceData returns the data pointer of a slice.
    69  func SliceData(s Slice) unsafe.Pointer {
    70  	return s.data
    71  }
    72  
    73  // SliceAppend append elem data and returns a slice.
    74  func SliceAppend(src Slice, data unsafe.Pointer, num, etSize int) Slice {
    75  	if etSize == 0 {
    76  		return src
    77  	}
    78  	oldLen := src.len
    79  	newLen := src.len + num
    80  	if newLen > src.cap {
    81  		newCap := nextslicecap(newLen, src.cap)
    82  		p := AllocZ(uintptr(newCap * etSize))
    83  		if oldLen != 0 {
    84  			c.Memcpy(p, src.data, uintptr(oldLen*etSize))
    85  		}
    86  		src.data = p
    87  		src.cap = newCap
    88  	}
    89  	src.len = newLen
    90  	c.Memcpy(c.Advance(src.data, oldLen*etSize), data, uintptr(num*etSize))
    91  	return src
    92  }
    93  
    94  // -----------------------------------------------------------------------------