// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime

import (
	
)

// listHead points to the head of an intrusive doubly-linked list.
//
// Prior to use, you must call init to store the offset of listNode fields.
//
// Every object in the list should be the same type.
type listHead struct {
	obj unsafe.Pointer

	initialized bool
	nodeOffset  uintptr
}

// init initializes the list head. off is the offset (via unsafe.Offsetof) of
// the listNode field in the objects in the list.
func ( *listHead) ( uintptr) {
	.initialized = true
	.nodeOffset = 
}

// listNode is the linked list node for objects in a listHead list.
//
// listNode must be stored as a field in objects placed in the linked list. The
// offset of the field is registered via listHead.init.
//
// For example:
//
//	type foo struct {
//		val int
//
//		node listNode
//	}
//
// var fooHead listHead
// fooHead.init(unsafe.Offsetof(foo{}.node))
type listNode struct {
	prev unsafe.Pointer
	next unsafe.Pointer
}

func ( *listHead) ( unsafe.Pointer) *listNode {
	if !.initialized {
		throw("runtime: uninitialized listHead")
	}

	if  == nil {
		return nil
	}
	return (*listNode)(unsafe.Add(, .nodeOffset))
}

// Returns true if the list is empty.
func ( *listHead) () bool {
	return .obj == nil
}

// Returns the head of the list without removing it.
func ( *listHead) () unsafe.Pointer {
	return .obj
}

// Push p onto the front of the list.
func ( *listHead) ( unsafe.Pointer) {
	// p becomes the head of the list.

	// ... so p's next is the current head.
	 := .getNode()
	.next = .obj

	// ... and the current head's prev is p.
	if .obj != nil {
		 := .getNode(.obj)
		.prev = 
	}

	.obj = 
}

// Pop removes the head of the list.
func ( *listHead) () unsafe.Pointer {
	if .obj == nil {
		return nil
	}

	// Return the head of the list.
	 := .obj

	// ... so the new head is p's next.
	 := .getNode()
	.obj = .next
	// p is no longer on the list. Clear next to remove unused references.
	// N.B. as the head, prev must already be nil.
	.next = nil

	// ... and the new head no longer has a prev.
	if .obj != nil {
		 := .getNode(.obj)
		.prev = nil
	}

	return 
}

// Remove p from the middle of the list.
func ( *listHead) ( unsafe.Pointer) {
	if .obj ==  {
		// Use pop to ensure head is updated when removing the head.
		.pop()
		return
	}

	 := .getNode()
	 := .getNode(.prev)
	 := .getNode(.next)

	// Link prev to next.
	if  != nil {
		.next = .next
	}
	// Link next to prev.
	if  != nil {
		.prev = .prev
	}

	.prev = nil
	.next = nil
}