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

#ifndef FLATBUFFERS_GENERATED_EVENT_DV_H_
#define FLATBUFFERS_GENERATED_EVENT_DV_H_

#pragma GCC system_header
#pragma clang system_header

#include "../external/flatbuffers/flatbuffers.h"

#include <fmt/chrono.h>
#include <fmt/format.h>
#include <fmt/ostream.h>
#include <fmt/ranges.h>

namespace dv {

struct Event;

struct EventPacketFlatbuffer;
struct EventPacket;

bool operator==(const Event &lhs, const Event &rhs);
bool operator==(const EventPacket &lhs, const EventPacket &rhs);

inline const flatbuffers::TypeTable *EventTypeTable();

inline const flatbuffers::TypeTable *EventPacketTypeTable();

FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Event FLATBUFFERS_FINAL_CLASS {
	typedef Event NativeTableType;
	typedef Event TableType;

private:
	int64_t timestamp_;
	int16_t x_;
	int16_t y_;
	uint8_t polarity_;
	int8_t padding0__;
	int16_t padding1__;

public:
	static FLATBUFFERS_CONSTEXPR const char *GetFullyQualifiedName() {
		return "dv.Event";
	}
	Event() {
		memset(static_cast<void *>(this), 0, sizeof(Event));
	}
	Event(int64_t _timestamp, int16_t _x, int16_t _y, bool _polarity) :
		timestamp_(flatbuffers::EndianScalar(_timestamp)),
		x_(flatbuffers::EndianScalar(_x)),
		y_(flatbuffers::EndianScalar(_y)),
		polarity_(flatbuffers::EndianScalar(static_cast<uint8_t>(_polarity))),
		padding0__(0),
		padding1__(0) {
		(void) padding0__;
		(void) padding1__;
	}
	/// Timestamp (µs).
	int64_t timestamp() const {
		return flatbuffers::EndianScalar(timestamp_);
	}
	int16_t x() const {
		return flatbuffers::EndianScalar(x_);
	}
	int16_t y() const {
		return flatbuffers::EndianScalar(y_);
	}
	bool polarity() const {
		return flatbuffers::EndianScalar(polarity_) != 0;
	}

	friend std::ostream &operator<<(std::ostream &os, const Event &event) {
		os << fmt::format("({}, {}, {}, {})", event.timestamp(), event.x(), event.y(), event.polarity());
		return os;
	}
};

FLATBUFFERS_STRUCT_END(Event, 16);

inline bool operator==(const Event &lhs, const Event &rhs) {
	return (lhs.timestamp() == rhs.timestamp()) && (lhs.x() == rhs.x()) && (lhs.y() == rhs.y())
		&& (lhs.polarity() == rhs.polarity());
}

struct EventPacket : public flatbuffers::NativeTable {
	typedef EventPacketFlatbuffer TableType;

	static FLATBUFFERS_CONSTEXPR const char *GetFullyQualifiedName() {
		return "dv.EventPacket";
	}

	std::vector<Event> elements;

	EventPacket() {
	}

	// Generated Constructor
	EventPacket(const std::vector<Event> &_elements) : elements{_elements} {
	}

	friend std::ostream &operator<<(std::ostream &os, const EventPacket &packet) {
		if (packet.elements.empty()) {
			os << "EventPacket containing 0 events";
			return os;
		}

		const int64_t lowestTime  = packet.elements.front().timestamp();
		const int64_t highestTime = packet.elements.back().timestamp();

		os << fmt::format("EventPacket containing {} events within {}μs duration; time range within [{}; {}]",
			packet.elements.size(), highestTime - lowestTime, lowestTime, highestTime);
		return os;
	}
};

inline bool operator==(const EventPacket &lhs, const EventPacket &rhs) {
	return (lhs.elements == rhs.elements);
}

struct EventPacketFlatbuffer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
	typedef EventPacket NativeTableType;
	static FLATBUFFERS_CONSTEXPR const char *identifier = "EVTS";

	static const flatbuffers::TypeTable *MiniReflectTypeTable() {
		return EventPacketTypeTable();
	}

	static FLATBUFFERS_CONSTEXPR const char *GetFullyQualifiedName() {
		return "dv.EventPacket";
	}

	enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
		VT_ELEMENTS = 4
	};

	const flatbuffers::Vector<const Event *> *elements() const {
		return GetPointer<const flatbuffers::Vector<const Event *> *>(VT_ELEMENTS);
	}

	bool Verify(flatbuffers::Verifier &verifier) const {
		return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_ELEMENTS) && verifier.VerifyVector(elements())
			&& verifier.EndTable();
	}

	EventPacket *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
	void UnPackTo(EventPacket *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
	static void UnPackToFrom(
		EventPacket *_o, const EventPacketFlatbuffer *_fb, const flatbuffers::resolver_function_t *_resolver = nullptr);
	static flatbuffers::Offset<EventPacketFlatbuffer> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EventPacket *_o,
		const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};

struct EventPacketBuilder {
	flatbuffers::FlatBufferBuilder &fbb_;
	flatbuffers::uoffset_t start_;

	void add_elements(flatbuffers::Offset<flatbuffers::Vector<const Event *>> elements) {
		fbb_.AddOffset(EventPacketFlatbuffer::VT_ELEMENTS, elements);
	}

	explicit EventPacketBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) {
		start_ = fbb_.StartTable();
	}

	EventPacketBuilder &operator=(const EventPacketBuilder &);

	flatbuffers::Offset<EventPacketFlatbuffer> Finish() {
		const auto end = fbb_.EndTable(start_);
		auto o         = flatbuffers::Offset<EventPacketFlatbuffer>(end);
		return o;
	}
};

inline flatbuffers::Offset<EventPacketFlatbuffer> CreateEventPacket(
	flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::Offset<flatbuffers::Vector<const Event *>> elements = 0) {
	EventPacketBuilder builder_(_fbb);
	builder_.add_elements(elements);
	return builder_.Finish();
}

inline flatbuffers::Offset<EventPacketFlatbuffer> CreateEventPacketDirect(
	flatbuffers::FlatBufferBuilder &_fbb, const std::vector<Event> *elements = nullptr) {
	auto elements__ = elements ? _fbb.CreateVectorOfStructs<Event>(*elements) : 0;
	return dv::CreateEventPacket(_fbb, elements__);
}

flatbuffers::Offset<EventPacketFlatbuffer> CreateEventPacket(flatbuffers::FlatBufferBuilder &_fbb,
	const EventPacket *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

inline EventPacket *EventPacketFlatbuffer::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
	auto _o = new EventPacket();
	UnPackTo(_o, _resolver);
	return _o;
}

inline void EventPacketFlatbuffer::UnPackTo(EventPacket *_o, const flatbuffers::resolver_function_t *_resolver) const {
	(void) _o;
	(void) _resolver;
	UnPackToFrom(_o, this, _resolver);
}

inline void EventPacketFlatbuffer::UnPackToFrom(
	EventPacket *_o, const EventPacketFlatbuffer *_fb, const flatbuffers::resolver_function_t *_resolver) {
	(void) _o;
	(void) _fb;
	(void) _resolver;
	{
		auto _e = _fb->elements();
		if (_e) {
			_o->elements.resize(_e->size());
			for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) {
				_o->elements[_i] = *_e->Get(_i);
			}
		}
	};
}

inline flatbuffers::Offset<EventPacketFlatbuffer> EventPacketFlatbuffer::Pack(
	flatbuffers::FlatBufferBuilder &_fbb, const EventPacket *_o, const flatbuffers::rehasher_function_t *_rehasher) {
	return CreateEventPacket(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<EventPacketFlatbuffer> CreateEventPacket(
	flatbuffers::FlatBufferBuilder &_fbb, const EventPacket *_o, const flatbuffers::rehasher_function_t *_rehasher) {
	(void) _rehasher;
	(void) _o;

	struct _VectorArgs {
		flatbuffers::FlatBufferBuilder *__fbb;
		const EventPacket *__o;
		const flatbuffers::rehasher_function_t *__rehasher;
	} _va = {&_fbb, _o, _rehasher};

	(void) _va;
	auto _elements = _o->elements.size() ? _fbb.CreateVectorOfStructs(_o->elements.data(), _o->elements.size()) : 0;
	return dv::CreateEventPacket(_fbb, _elements);
}

inline const flatbuffers::TypeTable *EventTypeTable() {
	static const flatbuffers::TypeCode type_codes[] = {
		{flatbuffers::ET_LONG,  0, -1},
        {flatbuffers::ET_SHORT, 0, -1},
        {flatbuffers::ET_SHORT, 0, -1},
		{flatbuffers::ET_BOOL,  0, -1}
    };
	static const int64_t values[]          = {0, 8, 10, 12, 16};
	static const char *const names[]       = {"timestamp", "x", "y", "polarity"};
	static const flatbuffers::TypeTable tt = {flatbuffers::ST_STRUCT, 4, type_codes, nullptr, values, names};
	return &tt;
}

inline const flatbuffers::TypeTable *EventPacketTypeTable() {
	static const flatbuffers::TypeCode type_codes[] = {
		{flatbuffers::ET_SEQUENCE, 1, 0}
    };
	static const flatbuffers::TypeFunction type_refs[] = {EventTypeTable};
	static const char *const names[]                   = {"elements"};
	static const flatbuffers::TypeTable tt = {flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names};
	return &tt;
}

inline const dv::EventPacketFlatbuffer *GetEventPacket(const void *buf) {
	return flatbuffers::GetRoot<dv::EventPacketFlatbuffer>(buf);
}

inline const dv::EventPacketFlatbuffer *GetSizePrefixedEventPacket(const void *buf) {
	return flatbuffers::GetSizePrefixedRoot<dv::EventPacketFlatbuffer>(buf);
}

inline const char *EventPacketIdentifier() {
	return "EVTS";
}

inline bool EventPacketBufferHasIdentifier(const void *buf) {
	return flatbuffers::BufferHasIdentifier(buf, EventPacketIdentifier());
}

inline bool VerifyEventPacketBuffer(flatbuffers::Verifier &verifier) {
	return verifier.VerifyBuffer<dv::EventPacketFlatbuffer>(EventPacketIdentifier());
}

inline bool VerifySizePrefixedEventPacketBuffer(flatbuffers::Verifier &verifier) {
	return verifier.VerifySizePrefixedBuffer<dv::EventPacketFlatbuffer>(EventPacketIdentifier());
}

inline void FinishEventPacketBuffer(
	flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<dv::EventPacketFlatbuffer> root) {
	fbb.Finish(root, EventPacketIdentifier());
}

inline void FinishSizePrefixedEventPacketBuffer(
	flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<dv::EventPacketFlatbuffer> root) {
	fbb.FinishSizePrefixed(root, EventPacketIdentifier());
}

inline std::unique_ptr<EventPacket> UnPackEventPacket(
	const void *buf, const flatbuffers::resolver_function_t *res = nullptr) {
	return std::unique_ptr<EventPacket>(GetEventPacket(buf)->UnPack(res));
}

} // namespace dv

// fmt compatibility for ostream class printing.
template<>
struct fmt::formatter<dv::Event> : fmt::ostream_formatter {};

template<>
struct fmt::formatter<dv::EventPacket> : fmt::ostream_formatter {};

#endif // FLATBUFFERS_GENERATED_EVENT_DV_H_
