// automatically generated by the FlatBuffers compiler, do not modify
import flatbuffers

namespace optional_scalars

enum OptionalByte:
    OptionalByte_None = 0
    OptionalByte_One = 1
    OptionalByte_Two = 2

class ScalarStuff

class ScalarStuff : flatbuffers_handle
    def just_i8() -> int:
        return buf_.flatbuffers_field_int8(pos_, 4, 0)
    def maybe_i8() -> int, bool:
        return buf_.flatbuffers_field_int8(pos_, 6, 0), buf_.flatbuffers_field_present(pos_, 6)
    def default_i8() -> int:
        return buf_.flatbuffers_field_int8(pos_, 8, 42)
    def just_u8() -> int:
        return buf_.flatbuffers_field_uint8(pos_, 10, 0)
    def maybe_u8() -> int, bool:
        return buf_.flatbuffers_field_uint8(pos_, 12, 0), buf_.flatbuffers_field_present(pos_, 12)
    def default_u8() -> int:
        return buf_.flatbuffers_field_uint8(pos_, 14, 42)
    def just_i16() -> int:
        return buf_.flatbuffers_field_int16(pos_, 16, 0)
    def maybe_i16() -> int, bool:
        return buf_.flatbuffers_field_int16(pos_, 18, 0), buf_.flatbuffers_field_present(pos_, 18)
    def default_i16() -> int:
        return buf_.flatbuffers_field_int16(pos_, 20, 42)
    def just_u16() -> int:
        return buf_.flatbuffers_field_uint16(pos_, 22, 0)
    def maybe_u16() -> int, bool:
        return buf_.flatbuffers_field_uint16(pos_, 24, 0), buf_.flatbuffers_field_present(pos_, 24)
    def default_u16() -> int:
        return buf_.flatbuffers_field_uint16(pos_, 26, 42)
    def just_i32() -> int:
        return buf_.flatbuffers_field_int32(pos_, 28, 0)
    def maybe_i32() -> int, bool:
        return buf_.flatbuffers_field_int32(pos_, 30, 0), buf_.flatbuffers_field_present(pos_, 30)
    def default_i32() -> int:
        return buf_.flatbuffers_field_int32(pos_, 32, 42)
    def just_u32() -> int:
        return buf_.flatbuffers_field_uint32(pos_, 34, 0)
    def maybe_u32() -> int, bool:
        return buf_.flatbuffers_field_uint32(pos_, 36, 0), buf_.flatbuffers_field_present(pos_, 36)
    def default_u32() -> int:
        return buf_.flatbuffers_field_uint32(pos_, 38, 42)
    def just_i64() -> int:
        return buf_.flatbuffers_field_int64(pos_, 40, 0)
    def maybe_i64() -> int, bool:
        return buf_.flatbuffers_field_int64(pos_, 42, 0), buf_.flatbuffers_field_present(pos_, 42)
    def default_i64() -> int:
        return buf_.flatbuffers_field_int64(pos_, 44, 42)
    def just_u64() -> int:
        return buf_.flatbuffers_field_uint64(pos_, 46, 0)
    def maybe_u64() -> int, bool:
        return buf_.flatbuffers_field_uint64(pos_, 48, 0), buf_.flatbuffers_field_present(pos_, 48)
    def default_u64() -> int:
        return buf_.flatbuffers_field_uint64(pos_, 50, 42)
    def just_f32() -> float:
        return buf_.flatbuffers_field_float32(pos_, 52, 0.0)
    def maybe_f32() -> float, bool:
        return buf_.flatbuffers_field_float32(pos_, 54, 0), buf_.flatbuffers_field_present(pos_, 54)
    def default_f32() -> float:
        return buf_.flatbuffers_field_float32(pos_, 56, 42.0)
    def just_f64() -> float:
        return buf_.flatbuffers_field_float64(pos_, 58, 0.0)
    def maybe_f64() -> float, bool:
        return buf_.flatbuffers_field_float64(pos_, 60, 0), buf_.flatbuffers_field_present(pos_, 60)
    def default_f64() -> float:
        return buf_.flatbuffers_field_float64(pos_, 62, 42.0)
    def just_bool() -> bool:
        return bool(buf_.flatbuffers_field_int8(pos_, 64, 0))
    def maybe_bool() -> bool, bool:
        return bool(buf_.flatbuffers_field_int8(pos_, 66, 0)), buf_.flatbuffers_field_present(pos_, 66)
    def default_bool() -> bool:
        return bool(buf_.flatbuffers_field_int8(pos_, 68, 1))
    def just_enum() -> OptionalByte:
        return OptionalByte(buf_.flatbuffers_field_int8(pos_, 70, 0))
    def maybe_enum() -> OptionalByte, bool:
        return OptionalByte(buf_.flatbuffers_field_int8(pos_, 72, 0)), buf_.flatbuffers_field_present(pos_, 72)
    def default_enum() -> OptionalByte:
        return OptionalByte(buf_.flatbuffers_field_int8(pos_, 74, 1))

def GetRootAsScalarStuff(buf:string): return ScalarStuff { buf, buf.flatbuffers_indirect(0) }

struct ScalarStuffBuilder:
    b_:flatbuffers_builder
    def start():
        b_.StartObject(36)
        return this
    def add_just_i8(just_i8:int):
        b_.PrependInt8Slot(0, just_i8, 0)
        return this
    def add_maybe_i8(maybe_i8:int):
        b_.PrependInt8Slot(1, maybe_i8)
        return this
    def add_default_i8(default_i8:int):
        b_.PrependInt8Slot(2, default_i8, 42)
        return this
    def add_just_u8(just_u8:int):
        b_.PrependUint8Slot(3, just_u8, 0)
        return this
    def add_maybe_u8(maybe_u8:int):
        b_.PrependUint8Slot(4, maybe_u8)
        return this
    def add_default_u8(default_u8:int):
        b_.PrependUint8Slot(5, default_u8, 42)
        return this
    def add_just_i16(just_i16:int):
        b_.PrependInt16Slot(6, just_i16, 0)
        return this
    def add_maybe_i16(maybe_i16:int):
        b_.PrependInt16Slot(7, maybe_i16)
        return this
    def add_default_i16(default_i16:int):
        b_.PrependInt16Slot(8, default_i16, 42)
        return this
    def add_just_u16(just_u16:int):
        b_.PrependUint16Slot(9, just_u16, 0)
        return this
    def add_maybe_u16(maybe_u16:int):
        b_.PrependUint16Slot(10, maybe_u16)
        return this
    def add_default_u16(default_u16:int):
        b_.PrependUint16Slot(11, default_u16, 42)
        return this
    def add_just_i32(just_i32:int):
        b_.PrependInt32Slot(12, just_i32, 0)
        return this
    def add_maybe_i32(maybe_i32:int):
        b_.PrependInt32Slot(13, maybe_i32)
        return this
    def add_default_i32(default_i32:int):
        b_.PrependInt32Slot(14, default_i32, 42)
        return this
    def add_just_u32(just_u32:int):
        b_.PrependUint32Slot(15, just_u32, 0)
        return this
    def add_maybe_u32(maybe_u32:int):
        b_.PrependUint32Slot(16, maybe_u32)
        return this
    def add_default_u32(default_u32:int):
        b_.PrependUint32Slot(17, default_u32, 42)
        return this
    def add_just_i64(just_i64:int):
        b_.PrependInt64Slot(18, just_i64, 0)
        return this
    def add_maybe_i64(maybe_i64:int):
        b_.PrependInt64Slot(19, maybe_i64)
        return this
    def add_default_i64(default_i64:int):
        b_.PrependInt64Slot(20, default_i64, 42)
        return this
    def add_just_u64(just_u64:int):
        b_.PrependUint64Slot(21, just_u64, 0)
        return this
    def add_maybe_u64(maybe_u64:int):
        b_.PrependUint64Slot(22, maybe_u64)
        return this
    def add_default_u64(default_u64:int):
        b_.PrependUint64Slot(23, default_u64, 42)
        return this
    def add_just_f32(just_f32:float):
        b_.PrependFloat32Slot(24, just_f32, 0.0)
        return this
    def add_maybe_f32(maybe_f32:float):
        b_.PrependFloat32Slot(25, maybe_f32)
        return this
    def add_default_f32(default_f32:float):
        b_.PrependFloat32Slot(26, default_f32, 42.0)
        return this
    def add_just_f64(just_f64:float):
        b_.PrependFloat64Slot(27, just_f64, 0.0)
        return this
    def add_maybe_f64(maybe_f64:float):
        b_.PrependFloat64Slot(28, maybe_f64)
        return this
    def add_default_f64(default_f64:float):
        b_.PrependFloat64Slot(29, default_f64, 42.0)
        return this
    def add_just_bool(just_bool:bool):
        b_.PrependBoolSlot(30, just_bool, 0)
        return this
    def add_maybe_bool(maybe_bool:bool):
        b_.PrependBoolSlot(31, maybe_bool)
        return this
    def add_default_bool(default_bool:bool):
        b_.PrependBoolSlot(32, default_bool, 1)
        return this
    def add_just_enum(just_enum:OptionalByte):
        b_.PrependInt8Slot(33, just_enum, 0)
        return this
    def add_maybe_enum(maybe_enum:OptionalByte):
        b_.PrependInt8Slot(34, maybe_enum)
        return this
    def add_default_enum(default_enum:OptionalByte):
        b_.PrependInt8Slot(35, default_enum, 1)
        return this
    def end():
        return b_.EndObject()

