package flatbuffers

// Builder is a state machine for creating FlatBuffer objects.
// Use a Builder to construct object(s) starting from leaf nodes.
//
// A Builder constructs byte buffers in a last-first manner for simplicity and
// performance.
type Builder struct {
	// `Bytes` gives raw access to the buffer. Most users will want to use
	// FinishedBytes() instead.
	Bytes []byte

	minalign  int
	vtable    []UOffsetT
	objectEnd UOffsetT
	vtables   []UOffsetT
	head      UOffsetT
	nested    bool
	finished  bool
}

// NewBuilder initializes a Builder of size `initial_size`.
// The internal buffer is grown as needed.
func NewBuilder(initialSize int) *Builder {
	if initialSize <= 0 {
		initialSize = 0
	}

	b := &Builder{}
	b.Bytes = make([]byte, initialSize)
	b.head = UOffsetT(initialSize)
	b.minalign = 1
	b.vtables = make([]UOffsetT, 0, 16) // sensible default capacity

	return b
}

// Reset truncates the underlying Builder buffer, facilitating alloc-free
// reuse of a Builder. It also resets bookkeeping data.
func (b *Builder) Reset() {
	if b.Bytes != nil {
		b.Bytes = b.Bytes[:cap(b.Bytes)]
	}

	if b.vtables != nil {
		b.vtables = b.vtables[:0]
	}

	if b.vtable != nil {
		b.vtable = b.vtable[:0]
	}

	b.head = UOffsetT(len(b.Bytes))
	b.minalign = 1
	b.nested = false
	b.finished = false
}

// FinishedBytes returns a pointer to the written data in the byte buffer.
// Panics if the builder is not in a finished state (which is caused by calling
// `Finish()`).
func (b *Builder) FinishedBytes() []byte {
	b.assertFinished()
	return b.Bytes[b.Head():]
}

// StartObject initializes bookkeeping for writing a new object.
func (b *Builder) StartObject(numfields int) {
	b.assertNotNested()
	b.nested = true

	// use 32-bit offsets so that arithmetic doesn't overflow.
	if cap(b.vtable) < numfields || b.vtable == nil {
		b.vtable = make([]UOffsetT, numfields)
	} else {
		b.vtable = b.vtable[:numfields]
		for i := 0; i < len(b.vtable); i++ {
			b.vtable[i] = 0
		}
	}

	b.objectEnd = b.Offset()
	b.minalign = 1
}

// WriteVtable serializes the vtable for the current object, if applicable.
//
// Before writing out the vtable, this checks pre-existing vtables for equality
// to this one. If an equal vtable is found, point the object to the existing
// vtable and return.
//
// Because vtable values are sensitive to alignment of object data, not all
// logically-equal vtables will be deduplicated.
//
// A vtable has the following format:
//   <VOffsetT: size of the vtable in bytes, including this value>
//   <VOffsetT: size of the object in bytes, including the vtable offset>
//   <VOffsetT: offset for a field> * N, where N is the number of fields in
//	        the schema for this type. Includes deprecated fields.
// Thus, a vtable is made of 2 + N elements, each SizeVOffsetT bytes wide.
//
// An object has the following format:
//   <SOffsetT: offset to this object's vtable (may be negative)>
//   <byte: data>+
func (b *Builder) WriteVtable() (n UOffsetT) {
	// Prepend a zero scalar to the object. Later in this function we'll
	// write an offset here that points to the object's vtable:
	b.PrependSOffsetT(0)

	objectOffset := b.Offset()
	existingVtable := UOffsetT(0)

	// Search backwards through existing vtables, because similar vtables
	// are likely to have been recently appended. See
	// BenchmarkVtableDeduplication for a case in which this heuristic
	// saves about 30% of the time used in writing objects with duplicate
	// tables.
	for i := len(b.vtables) - 1; i >= 0; i-- {
		// Find the other vtable, which is associated with `i`:
		vt2Offset := b.vtables[i]
		vt2Start := len(b.Bytes) - int(vt2Offset)
		vt2Len := GetVOffsetT(b.Bytes[vt2Start:])

		metadata := VtableMetadataFields * SizeVOffsetT
		vt2End := vt2Start + int(vt2Len)
		vt2 := b.Bytes[vt2Start+metadata : vt2End]

		// Compare the other vtable to the one under consideration.
		// If they are equal, store the offset and break:
		if vtableEqual(b.vtable, objectOffset, vt2) {
			existingVtable = vt2Offset
			break
		}
	}

	if existingVtable == 0 {
		// Did not find a vtable, so write this one to the buffer.

		// Write out the current vtable in reverse , because
		// serialization occurs in last-first order:
		for i := len(b.vtable) - 1; i >= 0; i-- {
			var off UOffsetT
			if b.vtable[i] != 0 {
				// Forward reference to field;
				// use 32bit number to assert no overflow:
				off = objectOffset - b.vtable[i]
			}

			b.PrependVOffsetT(VOffsetT(off))
		}

		// The two metadata fields are written last.

		// First, store the object bytesize:
		objectSize := objectOffset - b.objectEnd
		b.PrependVOffsetT(VOffsetT(objectSize))

		// Second, store the vtable bytesize:
		vBytes := (len(b.vtable) + VtableMetadataFields) * SizeVOffsetT
		b.PrependVOffsetT(VOffsetT(vBytes))

		// Next, write the offset to the new vtable in the
		// already-allocated SOffsetT at the beginning of this object:
		objectStart := SOffsetT(len(b.Bytes)) - SOffsetT(objectOffset)
		WriteSOffsetT(b.Bytes[objectStart:],
			SOffsetT(b.Offset())-SOffsetT(objectOffset))

		// Finally, store this vtable in memory for future
		// deduplication:
		b.vtables = append(b.vtables, b.Offset())
	} else {
		// Found a duplicate vtable.

		objectStart := SOffsetT(len(b.Bytes)) - SOffsetT(objectOffset)
		b.head = UOffsetT(objectStart)

		// Write the offset to the found vtable in the
		// already-allocated SOffsetT at the beginning of this object:
		WriteSOffsetT(b.Bytes[b.head:],
			SOffsetT(existingVtable)-SOffsetT(objectOffset))
	}

	b.vtable = b.vtable[:0]
	return objectOffset
}

// EndObject writes data necessary to finish object construction.
func (b *Builder) EndObject() UOffsetT {
	b.assertNested()
	n := b.WriteVtable()
	b.nested = false
	return n
}

// Doubles the size of the byteslice, and copies the old data towards the
// end of the new byteslice (since we build the buffer backwards).
func (b *Builder) growByteBuffer() {
	if (int64(len(b.Bytes)) & int64(0xC0000000)) != 0 {
		panic("cannot grow buffer beyond 2 gigabytes")
	}
	newLen := len(b.Bytes) * 2
	if newLen == 0 {
		newLen = 1
	}

	if cap(b.Bytes) >= newLen {
		b.Bytes = b.Bytes[:newLen]
	} else {
		extension := make([]byte, newLen-len(b.Bytes))
		b.Bytes = append(b.Bytes, extension...)
	}

	middle := newLen / 2
	copy(b.Bytes[middle:], b.Bytes[:middle])
}

// Head gives the start of useful data in the underlying byte buffer.
// Note: unlike other functions, this value is interpreted as from the left.
func (b *Builder) Head() UOffsetT {
	return b.head
}

// Offset relative to the end of the buffer.
func (b *Builder) Offset() UOffsetT {
	return UOffsetT(len(b.Bytes)) - b.head
}

// Pad places zeros at the current offset.
func (b *Builder) Pad(n int) {
	for i := 0; i < n; i++ {
		b.PlaceByte(0)
	}
}

// Prep prepares to write an element of `size` after `additional_bytes`
// have been written, e.g. if you write a string, you need to align such
// the int length field is aligned to SizeInt32, and the string data follows it
// directly.
// If all you need to do is align, `additionalBytes` will be 0.
func (b *Builder) Prep(size, additionalBytes int) {
	// Track the biggest thing we've ever aligned to.
	if size > b.minalign {
		b.minalign = size
	}
	// Find the amount of alignment needed such that `size` is properly
	// aligned after `additionalBytes`:
	alignSize := (^(len(b.Bytes) - int(b.Head()) + additionalBytes)) + 1
	alignSize &= (size - 1)

	// Reallocate the buffer if needed:
	for int(b.head) <= alignSize+size+additionalBytes {
		oldBufSize := len(b.Bytes)
		b.growByteBuffer()
		b.head += UOffsetT(len(b.Bytes) - oldBufSize)
	}
	b.Pad(alignSize)
}

// PrependSOffsetT prepends an SOffsetT, relative to where it will be written.
func (b *Builder) PrependSOffsetT(off SOffsetT) {
	b.Prep(SizeSOffsetT, 0) // Ensure alignment is already done.
	if !(UOffsetT(off) <= b.Offset()) {
		panic("unreachable: off <= b.Offset()")
	}
	off2 := SOffsetT(b.Offset()) - off + SOffsetT(SizeSOffsetT)
	b.PlaceSOffsetT(off2)
}

// PrependUOffsetT prepends an UOffsetT, relative to where it will be written.
func (b *Builder) PrependUOffsetT(off UOffsetT) {
	b.Prep(SizeUOffsetT, 0) // Ensure alignment is already done.
	if !(off <= b.Offset()) {
		panic("unreachable: off <= b.Offset()")
	}
	off2 := b.Offset() - off + UOffsetT(SizeUOffsetT)
	b.PlaceUOffsetT(off2)
}

// StartVector initializes bookkeeping for writing a new vector.
//
// A vector has the following format:
//   <UOffsetT: number of elements in this vector>
//   <T: data>+, where T is the type of elements of this vector.
func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT {
	b.assertNotNested()
	b.nested = true
	b.Prep(SizeUint32, elemSize*numElems)
	b.Prep(alignment, elemSize*numElems) // Just in case alignment > int.
	return b.Offset()
}

// EndVector writes data necessary to finish vector construction.
func (b *Builder) EndVector(vectorNumElems int) UOffsetT {
	b.assertNested()

	// we already made space for this, so write without PrependUint32
	b.PlaceUOffsetT(UOffsetT(vectorNumElems))

	b.nested = false
	return b.Offset()
}

// CreateString writes a null-terminated string as a vector.
func (b *Builder) CreateString(s string) UOffsetT {
	b.assertNotNested()
	b.nested = true

	b.Prep(int(SizeUOffsetT), (len(s)+1)*SizeByte)
	b.PlaceByte(0)

	l := UOffsetT(len(s))

	b.head -= l
	copy(b.Bytes[b.head:b.head+l], s)

	return b.EndVector(len(s))
}

// CreateByteString writes a byte slice as a string (null-terminated).
func (b *Builder) CreateByteString(s []byte) UOffsetT {
	b.assertNotNested()
	b.nested = true

	b.Prep(int(SizeUOffsetT), (len(s)+1)*SizeByte)
	b.PlaceByte(0)

	l := UOffsetT(len(s))

	b.head -= l
	copy(b.Bytes[b.head:b.head+l], s)

	return b.EndVector(len(s))
}

// CreateByteVector writes a ubyte vector
func (b *Builder) CreateByteVector(v []byte) UOffsetT {
	b.assertNotNested()
	b.nested = true

	b.Prep(int(SizeUOffsetT), len(v)*SizeByte)

	l := UOffsetT(len(v))

	b.head -= l
	copy(b.Bytes[b.head:b.head+l], v)

	return b.EndVector(len(v))
}

func (b *Builder) assertNested() {
	// If you get this assert, you're in an object while trying to write
	// data that belongs outside of an object.
	// To fix this, write non-inline data (like vectors) before creating
	// objects.
	if !b.nested {
		panic("Incorrect creation order: must be inside object.")
	}
}

func (b *Builder) assertNotNested() {
	// If you hit this, you're trying to construct a Table/Vector/String
	// during the construction of its parent table (between the MyTableBuilder
	// and builder.Finish()).
	// Move the creation of these sub-objects to above the MyTableBuilder to
	// not get this assert.
	// Ignoring this assert may appear to work in simple cases, but the reason
	// it is here is that storing objects in-line may cause vtable offsets
	// to not fit anymore. It also leads to vtable duplication.
	if b.nested {
		panic("Incorrect creation order: object must not be nested.")
	}
}

func (b *Builder) assertFinished() {
	// If you get this assert, you're attempting to get access a buffer
	// which hasn't been finished yet. Be sure to call builder.Finish()
	// with your root table.
	// If you really need to access an unfinished buffer, use the Bytes
	// buffer directly.
	if !b.finished {
		panic("Incorrect use of FinishedBytes(): must call 'Finish' first.")
	}
}

// PrependBoolSlot prepends a bool onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependBoolSlot(o int, x, d bool) {
	val := byte(0)
	if x {
		val = 1
	}
	def := byte(0)
	if d {
		def = 1
	}
	b.PrependByteSlot(o, val, def)
}

// PrependByteSlot prepends a byte onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependByteSlot(o int, x, d byte) {
	if x != d {
		b.PrependByte(x)
		b.Slot(o)
	}
}

// PrependUint8Slot prepends a uint8 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependUint8Slot(o int, x, d uint8) {
	if x != d {
		b.PrependUint8(x)
		b.Slot(o)
	}
}

// PrependUint16Slot prepends a uint16 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependUint16Slot(o int, x, d uint16) {
	if x != d {
		b.PrependUint16(x)
		b.Slot(o)
	}
}

// PrependUint32Slot prepends a uint32 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependUint32Slot(o int, x, d uint32) {
	if x != d {
		b.PrependUint32(x)
		b.Slot(o)
	}
}

// PrependUint64Slot prepends a uint64 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependUint64Slot(o int, x, d uint64) {
	if x != d {
		b.PrependUint64(x)
		b.Slot(o)
	}
}

// PrependInt8Slot prepends a int8 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependInt8Slot(o int, x, d int8) {
	if x != d {
		b.PrependInt8(x)
		b.Slot(o)
	}
}

// PrependInt16Slot prepends a int16 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependInt16Slot(o int, x, d int16) {
	if x != d {
		b.PrependInt16(x)
		b.Slot(o)
	}
}

// PrependInt32Slot prepends a int32 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependInt32Slot(o int, x, d int32) {
	if x != d {
		b.PrependInt32(x)
		b.Slot(o)
	}
}

// PrependInt64Slot prepends a int64 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependInt64Slot(o int, x, d int64) {
	if x != d {
		b.PrependInt64(x)
		b.Slot(o)
	}
}

// PrependFloat32Slot prepends a float32 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependFloat32Slot(o int, x, d float32) {
	if x != d {
		b.PrependFloat32(x)
		b.Slot(o)
	}
}

// PrependFloat64Slot prepends a float64 onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependFloat64Slot(o int, x, d float64) {
	if x != d {
		b.PrependFloat64(x)
		b.Slot(o)
	}
}

// PrependUOffsetTSlot prepends an UOffsetT onto the object at vtable slot `o`.
// If value `x` equals default `d`, then the slot will be set to zero and no
// other data will be written.
func (b *Builder) PrependUOffsetTSlot(o int, x, d UOffsetT) {
	if x != d {
		b.PrependUOffsetT(x)
		b.Slot(o)
	}
}

// PrependStructSlot prepends a struct onto the object at vtable slot `o`.
// Structs are stored inline, so nothing additional is being added.
// In generated code, `d` is always 0.
func (b *Builder) PrependStructSlot(voffset int, x, d UOffsetT) {
	if x != d {
		b.assertNested()
		if x != b.Offset() {
			panic("inline data write outside of object")
		}
		b.Slot(voffset)
	}
}

// Slot sets the vtable key `voffset` to the current location in the buffer.
func (b *Builder) Slot(slotnum int) {
	b.vtable[slotnum] = UOffsetT(b.Offset())
}

// Finish finalizes a buffer, pointing to the given `rootTable`.
func (b *Builder) Finish(rootTable UOffsetT) {
	b.assertNotNested()
	b.Prep(b.minalign, SizeUOffsetT)
	b.PrependUOffsetT(rootTable)
	b.finished = true
}

// vtableEqual compares an unwritten vtable to a written vtable.
func vtableEqual(a []UOffsetT, objectStart UOffsetT, b []byte) bool {
	if len(a)*SizeVOffsetT != len(b) {
		return false
	}

	for i := 0; i < len(a); i++ {
		x := GetVOffsetT(b[i*SizeVOffsetT : (i+1)*SizeVOffsetT])

		// Skip vtable entries that indicate a default value.
		if x == 0 && a[i] == 0 {
			continue
		}

		y := SOffsetT(objectStart) - SOffsetT(a[i])
		if SOffsetT(x) != y {
			return false
		}
	}
	return true
}

// PrependBool prepends a bool to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependBool(x bool) {
	b.Prep(SizeBool, 0)
	b.PlaceBool(x)
}

// PrependUint8 prepends a uint8 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependUint8(x uint8) {
	b.Prep(SizeUint8, 0)
	b.PlaceUint8(x)
}

// PrependUint16 prepends a uint16 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependUint16(x uint16) {
	b.Prep(SizeUint16, 0)
	b.PlaceUint16(x)
}

// PrependUint32 prepends a uint32 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependUint32(x uint32) {
	b.Prep(SizeUint32, 0)
	b.PlaceUint32(x)
}

// PrependUint64 prepends a uint64 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependUint64(x uint64) {
	b.Prep(SizeUint64, 0)
	b.PlaceUint64(x)
}

// PrependInt8 prepends a int8 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependInt8(x int8) {
	b.Prep(SizeInt8, 0)
	b.PlaceInt8(x)
}

// PrependInt16 prepends a int16 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependInt16(x int16) {
	b.Prep(SizeInt16, 0)
	b.PlaceInt16(x)
}

// PrependInt32 prepends a int32 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependInt32(x int32) {
	b.Prep(SizeInt32, 0)
	b.PlaceInt32(x)
}

// PrependInt64 prepends a int64 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependInt64(x int64) {
	b.Prep(SizeInt64, 0)
	b.PlaceInt64(x)
}

// PrependFloat32 prepends a float32 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependFloat32(x float32) {
	b.Prep(SizeFloat32, 0)
	b.PlaceFloat32(x)
}

// PrependFloat64 prepends a float64 to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependFloat64(x float64) {
	b.Prep(SizeFloat64, 0)
	b.PlaceFloat64(x)
}

// PrependByte prepends a byte to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependByte(x byte) {
	b.Prep(SizeByte, 0)
	b.PlaceByte(x)
}

// PrependVOffsetT prepends a VOffsetT to the Builder buffer.
// Aligns and checks for space.
func (b *Builder) PrependVOffsetT(x VOffsetT) {
	b.Prep(SizeVOffsetT, 0)
	b.PlaceVOffsetT(x)
}

// PlaceBool prepends a bool to the Builder, without checking for space.
func (b *Builder) PlaceBool(x bool) {
	b.head -= UOffsetT(SizeBool)
	WriteBool(b.Bytes[b.head:], x)
}

// PlaceUint8 prepends a uint8 to the Builder, without checking for space.
func (b *Builder) PlaceUint8(x uint8) {
	b.head -= UOffsetT(SizeUint8)
	WriteUint8(b.Bytes[b.head:], x)
}

// PlaceUint16 prepends a uint16 to the Builder, without checking for space.
func (b *Builder) PlaceUint16(x uint16) {
	b.head -= UOffsetT(SizeUint16)
	WriteUint16(b.Bytes[b.head:], x)
}

// PlaceUint32 prepends a uint32 to the Builder, without checking for space.
func (b *Builder) PlaceUint32(x uint32) {
	b.head -= UOffsetT(SizeUint32)
	WriteUint32(b.Bytes[b.head:], x)
}

// PlaceUint64 prepends a uint64 to the Builder, without checking for space.
func (b *Builder) PlaceUint64(x uint64) {
	b.head -= UOffsetT(SizeUint64)
	WriteUint64(b.Bytes[b.head:], x)
}

// PlaceInt8 prepends a int8 to the Builder, without checking for space.
func (b *Builder) PlaceInt8(x int8) {
	b.head -= UOffsetT(SizeInt8)
	WriteInt8(b.Bytes[b.head:], x)
}

// PlaceInt16 prepends a int16 to the Builder, without checking for space.
func (b *Builder) PlaceInt16(x int16) {
	b.head -= UOffsetT(SizeInt16)
	WriteInt16(b.Bytes[b.head:], x)
}

// PlaceInt32 prepends a int32 to the Builder, without checking for space.
func (b *Builder) PlaceInt32(x int32) {
	b.head -= UOffsetT(SizeInt32)
	WriteInt32(b.Bytes[b.head:], x)
}

// PlaceInt64 prepends a int64 to the Builder, without checking for space.
func (b *Builder) PlaceInt64(x int64) {
	b.head -= UOffsetT(SizeInt64)
	WriteInt64(b.Bytes[b.head:], x)
}

// PlaceFloat32 prepends a float32 to the Builder, without checking for space.
func (b *Builder) PlaceFloat32(x float32) {
	b.head -= UOffsetT(SizeFloat32)
	WriteFloat32(b.Bytes[b.head:], x)
}

// PlaceFloat64 prepends a float64 to the Builder, without checking for space.
func (b *Builder) PlaceFloat64(x float64) {
	b.head -= UOffsetT(SizeFloat64)
	WriteFloat64(b.Bytes[b.head:], x)
}

// PlaceByte prepends a byte to the Builder, without checking for space.
func (b *Builder) PlaceByte(x byte) {
	b.head -= UOffsetT(SizeByte)
	WriteByte(b.Bytes[b.head:], x)
}

// PlaceVOffsetT prepends a VOffsetT to the Builder, without checking for space.
func (b *Builder) PlaceVOffsetT(x VOffsetT) {
	b.head -= UOffsetT(SizeVOffsetT)
	WriteVOffsetT(b.Bytes[b.head:], x)
}

// PlaceSOffsetT prepends a SOffsetT to the Builder, without checking for space.
func (b *Builder) PlaceSOffsetT(x SOffsetT) {
	b.head -= UOffsetT(SizeSOffsetT)
	WriteSOffsetT(b.Bytes[b.head:], x)
}

// PlaceUOffsetT prepends a UOffsetT to the Builder, without checking for space.
func (b *Builder) PlaceUOffsetT(x UOffsetT) {
	b.head -= UOffsetT(SizeUOffsetT)
	WriteUOffsetT(b.Bytes[b.head:], x)
}
