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

/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */

import * as flatbuffers from 'flatbuffers';



export class C implements flatbuffers.IUnpackableObject<CT> {
  bb: flatbuffers.ByteBuffer|null = null;
  bb_pos = 0;
  __init(i:number, bb:flatbuffers.ByteBuffer):C {
  this.bb_pos = i;
  this.bb = bb;
  return this;
}

static getRootAsC(bb:flatbuffers.ByteBuffer, obj?:C):C {
  return (obj || new C()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}

static getSizePrefixedRootAsC(bb:flatbuffers.ByteBuffer, obj?:C):C {
  bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
  return (obj || new C()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
}

c():boolean {
  const offset = this.bb!.__offset(this.bb_pos, 4);
  return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
}

mutate_c(value:boolean):boolean {
  const offset = this.bb!.__offset(this.bb_pos, 4);

  if (offset === 0) {
    return false;
  }

  this.bb!.writeInt8(this.bb_pos + offset, +value);
  return true;
}

static getFullyQualifiedName():string {
  return 'UnionUnderlyingType.C';
}

static startC(builder:flatbuffers.Builder) {
  builder.startObject(1);
}

static addC(builder:flatbuffers.Builder, c:boolean) {
  builder.addFieldInt8(0, +c, +false);
}

static endC(builder:flatbuffers.Builder):flatbuffers.Offset {
  const offset = builder.endObject();
  return offset;
}

static createC(builder:flatbuffers.Builder, c:boolean):flatbuffers.Offset {
  C.startC(builder);
  C.addC(builder, c);
  return C.endC(builder);
}

unpack(): CT {
  return new CT(
    this.c()
  );
}


unpackTo(_o: CT): void {
  _o.c = this.c();
}
}

export class CT implements flatbuffers.IGeneratedObject {
constructor(
  public c: boolean = false
){}


pack(builder:flatbuffers.Builder): flatbuffers.Offset {
  return C.createC(builder,
    this.c
  );
}
}
