# automatically generated by the FlatBuffers compiler, do not modify

# namespace: tosa

import flatbuffers
from flatbuffers.compat import import_numpy
np = import_numpy()

class ClampAttribute(object):
    __slots__ = ['_tab']

    @classmethod
    def GetRootAs(cls, buf, offset=0):
        n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
        x = ClampAttribute()
        x.Init(buf, n + offset)
        return x

    @classmethod
    def GetRootAsClampAttribute(cls, buf, offset=0):
        """This method is deprecated. Please switch to GetRootAs."""
        return cls.GetRootAs(buf, offset)
    @classmethod
    def ClampAttributeBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
        return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x54\x4F\x53\x41", size_prefixed=size_prefixed)

    # ClampAttribute
    def Init(self, buf, pos):
        self._tab = flatbuffers.table.Table(buf, pos)

    # ClampAttribute
    def MinVal(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # ClampAttribute
    def MinValAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # ClampAttribute
    def MinValLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # ClampAttribute
    def MinValIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
        return o == 0

    # ClampAttribute
    def MaxVal(self, j):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            a = self._tab.Vector(o)
            return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
        return 0

    # ClampAttribute
    def MaxValAsNumpy(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
        return 0

    # ClampAttribute
    def MaxValLength(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        if o != 0:
            return self._tab.VectorLen(o)
        return 0

    # ClampAttribute
    def MaxValIsNone(self):
        o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
        return o == 0

def ClampAttributeStart(builder):
    builder.StartObject(2)

def Start(builder):
    ClampAttributeStart(builder)

def ClampAttributeAddMinVal(builder, minVal):
    builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(minVal), 0)

def AddMinVal(builder, minVal):
    ClampAttributeAddMinVal(builder, minVal)

def ClampAttributeStartMinValVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartMinValVector(builder, numElems: int) -> int:
    return ClampAttributeStartMinValVector(builder, numElems)

def ClampAttributeAddMaxVal(builder, maxVal):
    builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(maxVal), 0)

def AddMaxVal(builder, maxVal):
    ClampAttributeAddMaxVal(builder, maxVal)

def ClampAttributeStartMaxValVector(builder, numElems):
    return builder.StartVector(1, numElems, 1)

def StartMaxValVector(builder, numElems: int) -> int:
    return ClampAttributeStartMaxValVector(builder, numElems)

def ClampAttributeEnd(builder):
    return builder.EndObject()

def End(builder):
    return ClampAttributeEnd(builder)
