## This file is generated by tempita. Do not modify this file directly or your changes will get overwritten.
## To edit this file edit the template in template/src

from io import BytesIO
from copy import deepcopy
import warnings

from . import __major__
from ._numeric cimport AbstractBaseNumericTag
from ._const cimport ID_BYTE, ID_SHORT, ID_INT, ID_LONG
from ._util cimport (
    write_byte,
    write_short,
    write_int,
    write_long,
    BufferContext,
    read_data,
    to_little_endian,
    read_byte,
)
if __major__ <= 2:
    from ._util import primitive_conversion
from ._dtype import EncoderType


cdef class AbstractBaseIntTag(AbstractBaseNumericTag):
    """Abstract Base Class for all int Tag classes"""

    @property
    def py_int(AbstractBaseNumericTag self) -> int:
        """
        A python int representation of the class.
        The returned data is immutable so changes will not mirror the instance.
        """
        raise NotImplementedError

    @property
    def py_data(self):
        """
        A python representation of the class. Note that the return type is undefined and may change in the future.
        You would be better off using the py_{type} or np_array properties if you require a fixed type.
        This is here for convenience to get a python representation under the same property name.
        """
        return self.py_int


cdef inline ByteTag read_byte_tag(BufferContext buffer, bint little_endian):
    cdef ByteTag tag = ByteTag.__new__(ByteTag)
    tag.value_ = read_byte(buffer)
    return tag


cdef class ByteTag(AbstractBaseIntTag):
    """
    A 1 byte integer class.
    Can Store numbers between -(2^7) and (2^7 - 1)
    """
    tag_id = ID_BYTE

    def __init__(ByteTag self, value = 0):
        self.value_ = self._sanitise_value(int(value))

    def __str__(ByteTag self):
        return str(self.value_)

    def __eq__(ByteTag self, other):
        cdef ByteTag other_
        if isinstance(other, ByteTag):
            other_ = other
            return self.value_ == other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ == primitive_conversion(other)
        return NotImplemented

    def __reduce__(ByteTag self):
        return self.__class__, (self.value_,)

    def __deepcopy__(ByteTag self, memo=None):
        return self.__class__(deepcopy(self.value_, memo=memo))

    def __copy__(ByteTag self):
        return self.__class__(self.value_)

    def __hash__(ByteTag self):
        return hash((self.tag_id, self.value_))

    def __ge__(ByteTag self, other):
        cdef ByteTag other_
        if isinstance(other, ByteTag):
            other_ = other
            return self.value_ >= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a >= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ >= primitive_conversion(other)
        return NotImplemented

    def __gt__(ByteTag self, other):
        cdef ByteTag other_
        if isinstance(other, ByteTag):
            other_ = other
            return self.value_ > other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a > b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ > primitive_conversion(other)
        return NotImplemented

    def __le__(ByteTag self, other):
        cdef ByteTag other_
        if isinstance(other, ByteTag):
            other_ = other
            return self.value_ <= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a <= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ <= primitive_conversion(other)
        return NotImplemented

    def __lt__(ByteTag self, other):
        cdef ByteTag other_
        if isinstance(other, ByteTag):
            other_ = other
            return self.value_ < other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ < primitive_conversion(other)
        return NotImplemented

    def __repr__(ByteTag self):
        return f"{self.__class__.__name__}({self.value_})"

    def __int__(ByteTag self):
        return self.value_.__int__()

    def __float__(ByteTag self):
        return self.value_.__float__()

    def __bool__(ByteTag self):
        return self.value_.__bool__()

    @property
    def py_int(ByteTag self) -> int:
        """
        A python int representation of the class.
        The returned data is immutable so changes will not mirror the instance.
        """
        return self.value_

    if __major__ <= 2:
        def __add__(self, other):
            warnings.warn(f"__add__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) + primitive_conversion(other)

        def __sub__(self, other):
            warnings.warn(f"__sub__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) - primitive_conversion(other)

        def __mul__(self, other):
            warnings.warn(f"__mul__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) * primitive_conversion(other)

        def __truediv__(self, other):
            warnings.warn(f"__truediv__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) / primitive_conversion(other)

        def __floordiv__(self, other):
            warnings.warn(f"__floordiv__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) // primitive_conversion(other)

        def __mod__(self, other):
            warnings.warn(f"__mod__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) % primitive_conversion(other)

        def __divmod__(self, other):
            warnings.warn(f"__divmod__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(self), primitive_conversion(other))

        def __pow__(self, power, modulo):
            warnings.warn(f"__pow__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(self), power, modulo)

        def __lshift__(self, other):
            warnings.warn(f"__lshift__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) << primitive_conversion(other)

        def __rshift__(self, other):
            warnings.warn(f"__rshift__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) >> primitive_conversion(other)

        def __and__(self, other):
            warnings.warn(f"__and__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) & primitive_conversion(other)

        def __xor__(self, other):
            warnings.warn(f"__xor__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) ^ primitive_conversion(other)

        def __or__(self, other):
            warnings.warn(f"__or__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) | primitive_conversion(other)

        def __radd__(self, other):
            warnings.warn(f"__radd__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) + primitive_conversion(self)

        def __rsub__(self, other):
            warnings.warn(f"__rsub__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) - primitive_conversion(self)

        def __rmul__(self, other):
            warnings.warn(f"__rmul__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) * primitive_conversion(self)

        def __rtruediv__(self, other):
            warnings.warn(f"__rtruediv__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) / primitive_conversion(self)

        def __rfloordiv__(self, other):
            warnings.warn(f"__rfloordiv__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) // primitive_conversion(self)

        def __rmod__(self, other):
            warnings.warn(f"__rmod__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) % primitive_conversion(self)

        def __rdivmod__(self, other):
            warnings.warn(f"__rdivmod__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(other), primitive_conversion(self))

        def __rpow__(self, other, modulo):
            warnings.warn(f"__rpow__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(other), primitive_conversion(self), modulo)

        def __rlshift__(self, other):
            warnings.warn(f"__rlshift__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) << primitive_conversion(self)

        def __rrshift__(self, other):
            warnings.warn(f"__rrshift__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) >> primitive_conversion(self)

        def __rand__(self, other):
            warnings.warn(f"__rand__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) & primitive_conversion(self)

        def __rxor__(self, other):
            warnings.warn(f"__rxor__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) ^ primitive_conversion(self)

        def __ror__(self, other):
            warnings.warn(f"__ror__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) | primitive_conversion(self)

        def __neg__(self):
            warnings.warn(f"__neg__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return -self.value_

        def __pos__(self):
            warnings.warn(f"__pos__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return +self.value_

        def __abs__(self):
            warnings.warn(f"__abs__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return abs(self.value_)

        def __invert__(self):
            warnings.warn(f"__invert__ is depreciated on ByteTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return ~self.value_

    cdef signed char _sanitise_value(ByteTag self, value):
        return (value & 0x7F) - (value & 0x80)

    cdef str _to_snbt(ByteTag self):
        return f"{self.value_}b"

    cdef void write_payload(
        ByteTag self,
        object buffer: BytesIO,
        bint little_endian,
        string_encoder: EncoderType,
    ) except *:
        write_byte(self.value_, buffer)


cdef inline ShortTag read_short_tag(BufferContext buffer, bint little_endian):
    cdef ShortTag tag = ShortTag.__new__(ShortTag)
    cdef short *pointer = <short*> read_data(buffer, 2)
    tag.value_ = pointer[0]
    to_little_endian(&tag.value_, 2, little_endian)
    return tag


cdef class ShortTag(AbstractBaseIntTag):
    """
    A 2 byte integer class.
    Can Store numbers between -(2^15) and (2^15 - 1)
    """
    tag_id = ID_SHORT

    def __init__(ShortTag self, value = 0):
        self.value_ = self._sanitise_value(int(value))

    def __str__(ShortTag self):
        return str(self.value_)

    def __eq__(ShortTag self, other):
        cdef ShortTag other_
        if isinstance(other, ShortTag):
            other_ = other
            return self.value_ == other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ == primitive_conversion(other)
        return NotImplemented

    def __reduce__(ShortTag self):
        return self.__class__, (self.value_,)

    def __deepcopy__(ShortTag self, memo=None):
        return self.__class__(deepcopy(self.value_, memo=memo))

    def __copy__(ShortTag self):
        return self.__class__(self.value_)

    def __hash__(ShortTag self):
        return hash((self.tag_id, self.value_))

    def __ge__(ShortTag self, other):
        cdef ShortTag other_
        if isinstance(other, ShortTag):
            other_ = other
            return self.value_ >= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a >= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ >= primitive_conversion(other)
        return NotImplemented

    def __gt__(ShortTag self, other):
        cdef ShortTag other_
        if isinstance(other, ShortTag):
            other_ = other
            return self.value_ > other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a > b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ > primitive_conversion(other)
        return NotImplemented

    def __le__(ShortTag self, other):
        cdef ShortTag other_
        if isinstance(other, ShortTag):
            other_ = other
            return self.value_ <= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a <= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ <= primitive_conversion(other)
        return NotImplemented

    def __lt__(ShortTag self, other):
        cdef ShortTag other_
        if isinstance(other, ShortTag):
            other_ = other
            return self.value_ < other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ < primitive_conversion(other)
        return NotImplemented

    def __repr__(ShortTag self):
        return f"{self.__class__.__name__}({self.value_})"

    def __int__(ShortTag self):
        return self.value_.__int__()

    def __float__(ShortTag self):
        return self.value_.__float__()

    def __bool__(ShortTag self):
        return self.value_.__bool__()

    @property
    def py_int(ShortTag self) -> int:
        """
        A python int representation of the class.
        The returned data is immutable so changes will not mirror the instance.
        """
        return self.value_

    if __major__ <= 2:
        def __add__(self, other):
            warnings.warn(f"__add__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) + primitive_conversion(other)

        def __sub__(self, other):
            warnings.warn(f"__sub__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) - primitive_conversion(other)

        def __mul__(self, other):
            warnings.warn(f"__mul__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) * primitive_conversion(other)

        def __truediv__(self, other):
            warnings.warn(f"__truediv__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) / primitive_conversion(other)

        def __floordiv__(self, other):
            warnings.warn(f"__floordiv__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) // primitive_conversion(other)

        def __mod__(self, other):
            warnings.warn(f"__mod__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) % primitive_conversion(other)

        def __divmod__(self, other):
            warnings.warn(f"__divmod__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(self), primitive_conversion(other))

        def __pow__(self, power, modulo):
            warnings.warn(f"__pow__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(self), power, modulo)

        def __lshift__(self, other):
            warnings.warn(f"__lshift__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) << primitive_conversion(other)

        def __rshift__(self, other):
            warnings.warn(f"__rshift__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) >> primitive_conversion(other)

        def __and__(self, other):
            warnings.warn(f"__and__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) & primitive_conversion(other)

        def __xor__(self, other):
            warnings.warn(f"__xor__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) ^ primitive_conversion(other)

        def __or__(self, other):
            warnings.warn(f"__or__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) | primitive_conversion(other)

        def __radd__(self, other):
            warnings.warn(f"__radd__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) + primitive_conversion(self)

        def __rsub__(self, other):
            warnings.warn(f"__rsub__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) - primitive_conversion(self)

        def __rmul__(self, other):
            warnings.warn(f"__rmul__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) * primitive_conversion(self)

        def __rtruediv__(self, other):
            warnings.warn(f"__rtruediv__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) / primitive_conversion(self)

        def __rfloordiv__(self, other):
            warnings.warn(f"__rfloordiv__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) // primitive_conversion(self)

        def __rmod__(self, other):
            warnings.warn(f"__rmod__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) % primitive_conversion(self)

        def __rdivmod__(self, other):
            warnings.warn(f"__rdivmod__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(other), primitive_conversion(self))

        def __rpow__(self, other, modulo):
            warnings.warn(f"__rpow__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(other), primitive_conversion(self), modulo)

        def __rlshift__(self, other):
            warnings.warn(f"__rlshift__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) << primitive_conversion(self)

        def __rrshift__(self, other):
            warnings.warn(f"__rrshift__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) >> primitive_conversion(self)

        def __rand__(self, other):
            warnings.warn(f"__rand__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) & primitive_conversion(self)

        def __rxor__(self, other):
            warnings.warn(f"__rxor__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) ^ primitive_conversion(self)

        def __ror__(self, other):
            warnings.warn(f"__ror__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) | primitive_conversion(self)

        def __neg__(self):
            warnings.warn(f"__neg__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return -self.value_

        def __pos__(self):
            warnings.warn(f"__pos__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return +self.value_

        def __abs__(self):
            warnings.warn(f"__abs__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return abs(self.value_)

        def __invert__(self):
            warnings.warn(f"__invert__ is depreciated on ShortTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return ~self.value_

    cdef short _sanitise_value(ShortTag self, value):
        return (value & 0x7FFF) - (value & 0x8000)

    cdef str _to_snbt(ShortTag self):
        return f"{self.value_}s"

    cdef void write_payload(
        ShortTag self,
        object buffer: BytesIO,
        bint little_endian,
        string_encoder: EncoderType,
    ) except *:
        write_short(self.value_, buffer, little_endian)


cdef inline IntTag read_int_tag(BufferContext buffer, bint little_endian):
    cdef IntTag tag = IntTag.__new__(IntTag)
    cdef int*pointer = <int*> read_data(buffer, 4)
    tag.value_ = pointer[0]
    to_little_endian(&tag.value_, 4, little_endian)
    return tag


cdef class IntTag(AbstractBaseIntTag):
    """
    A 4 byte integer class.
    Can Store numbers between -(2^31) and (2^31 - 1)
    """
    tag_id = ID_INT

    def __init__(IntTag self, value = 0):
        self.value_ = self._sanitise_value(int(value))

    def __str__(IntTag self):
        return str(self.value_)

    def __eq__(IntTag self, other):
        cdef IntTag other_
        if isinstance(other, IntTag):
            other_ = other
            return self.value_ == other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ == primitive_conversion(other)
        return NotImplemented

    def __reduce__(IntTag self):
        return self.__class__, (self.value_,)

    def __deepcopy__(IntTag self, memo=None):
        return self.__class__(deepcopy(self.value_, memo=memo))

    def __copy__(IntTag self):
        return self.__class__(self.value_)

    def __hash__(IntTag self):
        return hash((self.tag_id, self.value_))

    def __ge__(IntTag self, other):
        cdef IntTag other_
        if isinstance(other, IntTag):
            other_ = other
            return self.value_ >= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a >= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ >= primitive_conversion(other)
        return NotImplemented

    def __gt__(IntTag self, other):
        cdef IntTag other_
        if isinstance(other, IntTag):
            other_ = other
            return self.value_ > other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a > b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ > primitive_conversion(other)
        return NotImplemented

    def __le__(IntTag self, other):
        cdef IntTag other_
        if isinstance(other, IntTag):
            other_ = other
            return self.value_ <= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a <= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ <= primitive_conversion(other)
        return NotImplemented

    def __lt__(IntTag self, other):
        cdef IntTag other_
        if isinstance(other, IntTag):
            other_ = other
            return self.value_ < other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ < primitive_conversion(other)
        return NotImplemented

    def __repr__(IntTag self):
        return f"{self.__class__.__name__}({self.value_})"

    def __int__(IntTag self):
        return self.value_.__int__()

    def __float__(IntTag self):
        return self.value_.__float__()

    def __bool__(IntTag self):
        return self.value_.__bool__()

    @property
    def py_int(IntTag self) -> int:
        """
        A python int representation of the class.
        The returned data is immutable so changes will not mirror the instance.
        """
        return self.value_

    if __major__ <= 2:
        def __add__(self, other):
            warnings.warn(f"__add__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) + primitive_conversion(other)

        def __sub__(self, other):
            warnings.warn(f"__sub__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) - primitive_conversion(other)

        def __mul__(self, other):
            warnings.warn(f"__mul__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) * primitive_conversion(other)

        def __truediv__(self, other):
            warnings.warn(f"__truediv__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) / primitive_conversion(other)

        def __floordiv__(self, other):
            warnings.warn(f"__floordiv__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) // primitive_conversion(other)

        def __mod__(self, other):
            warnings.warn(f"__mod__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) % primitive_conversion(other)

        def __divmod__(self, other):
            warnings.warn(f"__divmod__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(self), primitive_conversion(other))

        def __pow__(self, power, modulo):
            warnings.warn(f"__pow__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(self), power, modulo)

        def __lshift__(self, other):
            warnings.warn(f"__lshift__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) << primitive_conversion(other)

        def __rshift__(self, other):
            warnings.warn(f"__rshift__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) >> primitive_conversion(other)

        def __and__(self, other):
            warnings.warn(f"__and__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) & primitive_conversion(other)

        def __xor__(self, other):
            warnings.warn(f"__xor__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) ^ primitive_conversion(other)

        def __or__(self, other):
            warnings.warn(f"__or__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) | primitive_conversion(other)

        def __radd__(self, other):
            warnings.warn(f"__radd__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) + primitive_conversion(self)

        def __rsub__(self, other):
            warnings.warn(f"__rsub__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) - primitive_conversion(self)

        def __rmul__(self, other):
            warnings.warn(f"__rmul__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) * primitive_conversion(self)

        def __rtruediv__(self, other):
            warnings.warn(f"__rtruediv__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) / primitive_conversion(self)

        def __rfloordiv__(self, other):
            warnings.warn(f"__rfloordiv__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) // primitive_conversion(self)

        def __rmod__(self, other):
            warnings.warn(f"__rmod__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) % primitive_conversion(self)

        def __rdivmod__(self, other):
            warnings.warn(f"__rdivmod__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(other), primitive_conversion(self))

        def __rpow__(self, other, modulo):
            warnings.warn(f"__rpow__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(other), primitive_conversion(self), modulo)

        def __rlshift__(self, other):
            warnings.warn(f"__rlshift__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) << primitive_conversion(self)

        def __rrshift__(self, other):
            warnings.warn(f"__rrshift__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) >> primitive_conversion(self)

        def __rand__(self, other):
            warnings.warn(f"__rand__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) & primitive_conversion(self)

        def __rxor__(self, other):
            warnings.warn(f"__rxor__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) ^ primitive_conversion(self)

        def __ror__(self, other):
            warnings.warn(f"__ror__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) | primitive_conversion(self)

        def __neg__(self):
            warnings.warn(f"__neg__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return -self.value_

        def __pos__(self):
            warnings.warn(f"__pos__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return +self.value_

        def __abs__(self):
            warnings.warn(f"__abs__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return abs(self.value_)

        def __invert__(self):
            warnings.warn(f"__invert__ is depreciated on IntTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return ~self.value_

    cdef int _sanitise_value(IntTag self, value):
        return (value & 0x7FFF_FFFF) - (value & 0x8000_0000)

    cdef str _to_snbt(IntTag self):
        return f"{self.value_}"

    cdef void write_payload(
        IntTag self,
        object buffer: BytesIO,
        bint little_endian,
        string_encoder: EncoderType,
    ) except *:
        write_int(self.value_, buffer, little_endian)


cdef inline LongTag read_long_tag(BufferContext buffer, bint little_endian):
    cdef LongTag tag = LongTag.__new__(LongTag)
    cdef long long *pointer = <long long *> read_data(buffer, 8)
    tag.value_ = pointer[0]
    to_little_endian(&tag.value_, 8, little_endian)
    return tag


cdef class LongTag(AbstractBaseIntTag):
    """
    An 8 byte integer class.
    Can Store numbers between -(2^63) and (2^63 - 1)
    """
    tag_id = ID_LONG

    def __init__(LongTag self, value = 0):
        self.value_ = self._sanitise_value(int(value))

    def __str__(LongTag self):
        return str(self.value_)

    def __eq__(LongTag self, other):
        cdef LongTag other_
        if isinstance(other, LongTag):
            other_ = other
            return self.value_ == other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ == primitive_conversion(other)
        return NotImplemented

    def __reduce__(LongTag self):
        return self.__class__, (self.value_,)

    def __deepcopy__(LongTag self, memo=None):
        return self.__class__(deepcopy(self.value_, memo=memo))

    def __copy__(LongTag self):
        return self.__class__(self.value_)

    def __hash__(LongTag self):
        return hash((self.tag_id, self.value_))

    def __ge__(LongTag self, other):
        cdef LongTag other_
        if isinstance(other, LongTag):
            other_ = other
            return self.value_ >= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a >= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ >= primitive_conversion(other)
        return NotImplemented

    def __gt__(LongTag self, other):
        cdef LongTag other_
        if isinstance(other, LongTag):
            other_ = other
            return self.value_ > other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a > b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ > primitive_conversion(other)
        return NotImplemented

    def __le__(LongTag self, other):
        cdef LongTag other_
        if isinstance(other, LongTag):
            other_ = other
            return self.value_ <= other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a <= b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ <= primitive_conversion(other)
        return NotImplemented

    def __lt__(LongTag self, other):
        cdef LongTag other_
        if isinstance(other, LongTag):
            other_ = other
            return self.value_ < other_.value_
        elif __major__ <= 2:
            warnings.warn("NBT comparison operator (a == b) will only return True between classes of the same type.", FutureWarning)
            return self.value_ < primitive_conversion(other)
        return NotImplemented

    def __repr__(LongTag self):
        return f"{self.__class__.__name__}({self.value_})"

    def __int__(LongTag self):
        return self.value_.__int__()

    def __float__(LongTag self):
        return self.value_.__float__()

    def __bool__(LongTag self):
        return self.value_.__bool__()

    @property
    def py_int(LongTag self) -> int:
        """
        A python int representation of the class.
        The returned data is immutable so changes will not mirror the instance.
        """
        return self.value_

    if __major__ <= 2:
        def __add__(self, other):
            warnings.warn(f"__add__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) + primitive_conversion(other)

        def __sub__(self, other):
            warnings.warn(f"__sub__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) - primitive_conversion(other)

        def __mul__(self, other):
            warnings.warn(f"__mul__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) * primitive_conversion(other)

        def __truediv__(self, other):
            warnings.warn(f"__truediv__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) / primitive_conversion(other)

        def __floordiv__(self, other):
            warnings.warn(f"__floordiv__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) // primitive_conversion(other)

        def __mod__(self, other):
            warnings.warn(f"__mod__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) % primitive_conversion(other)

        def __divmod__(self, other):
            warnings.warn(f"__divmod__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(self), primitive_conversion(other))

        def __pow__(self, power, modulo):
            warnings.warn(f"__pow__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(self), power, modulo)

        def __lshift__(self, other):
            warnings.warn(f"__lshift__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) << primitive_conversion(other)

        def __rshift__(self, other):
            warnings.warn(f"__rshift__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) >> primitive_conversion(other)

        def __and__(self, other):
            warnings.warn(f"__and__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) & primitive_conversion(other)

        def __xor__(self, other):
            warnings.warn(f"__xor__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) ^ primitive_conversion(other)

        def __or__(self, other):
            warnings.warn(f"__or__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(self) | primitive_conversion(other)

        def __radd__(self, other):
            warnings.warn(f"__radd__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) + primitive_conversion(self)

        def __rsub__(self, other):
            warnings.warn(f"__rsub__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) - primitive_conversion(self)

        def __rmul__(self, other):
            warnings.warn(f"__rmul__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) * primitive_conversion(self)

        def __rtruediv__(self, other):
            warnings.warn(f"__rtruediv__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) / primitive_conversion(self)

        def __rfloordiv__(self, other):
            warnings.warn(f"__rfloordiv__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) // primitive_conversion(self)

        def __rmod__(self, other):
            warnings.warn(f"__rmod__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) % primitive_conversion(self)

        def __rdivmod__(self, other):
            warnings.warn(f"__rdivmod__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return divmod(primitive_conversion(other), primitive_conversion(self))

        def __rpow__(self, other, modulo):
            warnings.warn(f"__rpow__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return pow(primitive_conversion(other), primitive_conversion(self), modulo)

        def __rlshift__(self, other):
            warnings.warn(f"__rlshift__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) << primitive_conversion(self)

        def __rrshift__(self, other):
            warnings.warn(f"__rrshift__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) >> primitive_conversion(self)

        def __rand__(self, other):
            warnings.warn(f"__rand__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) & primitive_conversion(self)

        def __rxor__(self, other):
            warnings.warn(f"__rxor__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) ^ primitive_conversion(self)

        def __ror__(self, other):
            warnings.warn(f"__ror__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return primitive_conversion(other) | primitive_conversion(self)

        def __neg__(self):
            warnings.warn(f"__neg__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return -self.value_

        def __pos__(self):
            warnings.warn(f"__pos__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return +self.value_

        def __abs__(self):
            warnings.warn(f"__abs__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return abs(self.value_)

        def __invert__(self):
            warnings.warn(f"__invert__ is depreciated on LongTag and will be removed in the future. Please use .py_int to achieve the same behaviour.", DeprecationWarning)
            return ~self.value_

    cdef long long _sanitise_value(LongTag self, value):
        return (value & 0x7FFF_FFFF_FFFF_FFFF) - (value & 0x8000_0000_0000_0000)

    cdef str _to_snbt(LongTag self):
        return f"{self.value_}L"

    cdef void write_payload(
        LongTag self,
        object buffer: BytesIO,
        bint little_endian,
        string_encoder: EncoderType,
    ) except *:
        write_long(self.value_, buffer, little_endian)
