// 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 flatbuffers.field_int8(buf_, pos_, 4, 0)
    def maybe_i8() -> int, bool:
        return flatbuffers.field_int8(buf_, pos_, 6, 0), flatbuffers.field_present(buf_, pos_, 6)
    def default_i8() -> int:
        return flatbuffers.field_int8(buf_, pos_, 8, 42)
    def just_u8() -> int:
        return flatbuffers.field_uint8(buf_, pos_, 10, 0)
    def maybe_u8() -> int, bool:
        return flatbuffers.field_uint8(buf_, pos_, 12, 0), flatbuffers.field_present(buf_, pos_, 12)
    def default_u8() -> int:
        return flatbuffers.field_uint8(buf_, pos_, 14, 42)
    def just_i16() -> int:
        return flatbuffers.field_int16(buf_, pos_, 16, 0)
    def maybe_i16() -> int, bool:
        return flatbuffers.field_int16(buf_, pos_, 18, 0), flatbuffers.field_present(buf_, pos_, 18)
    def default_i16() -> int:
        return flatbuffers.field_int16(buf_, pos_, 20, 42)
    def just_u16() -> int:
        return flatbuffers.field_uint16(buf_, pos_, 22, 0)
    def maybe_u16() -> int, bool:
        return flatbuffers.field_uint16(buf_, pos_, 24, 0), flatbuffers.field_present(buf_, pos_, 24)
    def default_u16() -> int:
        return flatbuffers.field_uint16(buf_, pos_, 26, 42)
    def just_i32() -> int:
        return flatbuffers.field_int32(buf_, pos_, 28, 0)
    def maybe_i32() -> int, bool:
        return flatbuffers.field_int32(buf_, pos_, 30, 0), flatbuffers.field_present(buf_, pos_, 30)
    def default_i32() -> int:
        return flatbuffers.field_int32(buf_, pos_, 32, 42)
    def just_u32() -> int:
        return flatbuffers.field_uint32(buf_, pos_, 34, 0)
    def maybe_u32() -> int, bool:
        return flatbuffers.field_uint32(buf_, pos_, 36, 0), flatbuffers.field_present(buf_, pos_, 36)
    def default_u32() -> int:
        return flatbuffers.field_uint32(buf_, pos_, 38, 42)
    def just_i64() -> int:
        return flatbuffers.field_int64(buf_, pos_, 40, 0)
    def maybe_i64() -> int, bool:
        return flatbuffers.field_int64(buf_, pos_, 42, 0), flatbuffers.field_present(buf_, pos_, 42)
    def default_i64() -> int:
        return flatbuffers.field_int64(buf_, pos_, 44, 42)
    def just_u64() -> int:
        return flatbuffers.field_uint64(buf_, pos_, 46, 0)
    def maybe_u64() -> int, bool:
        return flatbuffers.field_uint64(buf_, pos_, 48, 0), flatbuffers.field_present(buf_, pos_, 48)
    def default_u64() -> int:
        return flatbuffers.field_uint64(buf_, pos_, 50, 42)
    def just_f32() -> float:
        return flatbuffers.field_float32(buf_, pos_, 52, 0.0)
    def maybe_f32() -> float, bool:
        return flatbuffers.field_float32(buf_, pos_, 54, 0.0), flatbuffers.field_present(buf_, pos_, 54)
    def default_f32() -> float:
        return flatbuffers.field_float32(buf_, pos_, 56, 42.0)
    def just_f64() -> float:
        return flatbuffers.field_float64(buf_, pos_, 58, 0.0)
    def maybe_f64() -> float, bool:
        return flatbuffers.field_float64(buf_, pos_, 60, 0.0), flatbuffers.field_present(buf_, pos_, 60)
    def default_f64() -> float:
        return flatbuffers.field_float64(buf_, pos_, 62, 42.0)
    def just_bool() -> bool:
        return bool(flatbuffers.field_int8(buf_, pos_, 64, 0))
    def maybe_bool() -> bool, bool:
        return bool(flatbuffers.field_int8(buf_, pos_, 66, 0)), flatbuffers.field_present(buf_, pos_, 66)
    def default_bool() -> bool:
        return bool(flatbuffers.field_int8(buf_, pos_, 68, 1))
    def just_enum() -> OptionalByte:
        return OptionalByte(flatbuffers.field_int8(buf_, pos_, 70, 0))
    def maybe_enum() -> OptionalByte, bool:
        return OptionalByte(flatbuffers.field_int8(buf_, pos_, 72, 0)), flatbuffers.field_present(buf_, pos_, 72)
    def default_enum() -> OptionalByte:
        return OptionalByte(flatbuffers.field_int8(buf_, pos_, 74, 1))

def GetRootAsScalarStuff(buf:string): return ScalarStuff { buf, flatbuffers.indirect(buf, 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()

