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

#ifndef FLATBUFFERS_GENERATED_TIMEDKEYPOINT_DV_H_
#define FLATBUFFERS_GENERATED_TIMEDKEYPOINT_DV_H_

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

#include "geometry_types_base.hpp"

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

namespace dv {

struct TimedKeyPointFlatbuffer;
struct TimedKeyPoint;

struct TimedKeyPointPacketFlatbuffer;
struct TimedKeyPointPacket;

bool operator==(const TimedKeyPoint &lhs, const TimedKeyPoint &rhs);
bool operator==(const TimedKeyPointPacket &lhs, const TimedKeyPointPacket &rhs);

inline const flatbuffers::TypeTable *TimedKeyPointTypeTable();

inline const flatbuffers::TypeTable *TimedKeyPointPacketTypeTable();

struct TimedKeyPoint : public flatbuffers::NativeTable {
	typedef TimedKeyPointFlatbuffer TableType;

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

	Point2f pt;
	float size;
	float angle;
	float response;
	int32_t octave;
	int32_t class_id;
	int64_t timestamp;

	TimedKeyPoint() : size(0.0f), angle(0.0f), response(0.0f), octave(0), class_id(0), timestamp(0) {
	}

	// Generated Constructor
	TimedKeyPoint(const Point2f &_pt, float _size, float _angle, float _response, int32_t _octave, int32_t _class_id,
		int64_t _timestamp) :
		pt{_pt},
		size{_size},
		angle{_angle},
		response{_response},
		octave{_octave},
		class_id{_class_id},
		timestamp{_timestamp} {
	}
};

inline bool operator==(const TimedKeyPoint &lhs, const TimedKeyPoint &rhs) {
	return (lhs.pt == rhs.pt) && (lhs.size == rhs.size) && (lhs.angle == rhs.angle) && (lhs.response == rhs.response)
		&& (lhs.octave == rhs.octave) && (lhs.class_id == rhs.class_id) && (lhs.timestamp == rhs.timestamp);
}

struct TimedKeyPointFlatbuffer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
	typedef TimedKeyPoint NativeTableType;

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

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

	enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
		VT_PT        = 4,
		VT_SIZE      = 6,
		VT_ANGLE     = 8,
		VT_RESPONSE  = 10,
		VT_OCTAVE    = 12,
		VT_CLASS_ID  = 14,
		VT_TIMESTAMP = 16
	};

	/// coordinates of the keypoints.
	const Point2f *pt() const {
		return GetStruct<const Point2f *>(VT_PT);
	}

	/// diameter of the meaningful keypoint neighborhood.
	float size() const {
		return GetField<float>(VT_SIZE, 0.0f);
	}

	/// computed orientation of the keypoint (-1 if not applicable);
	/// it's in [0,360) degrees and measured relative to
	/// image coordinate system, ie in clockwise.
	float angle() const {
		return GetField<float>(VT_ANGLE, 0.0f);
	}

	/// the response by which the most strong keypoints have been selected. Can be used for the further sorting or
	/// subsampling.
	float response() const {
		return GetField<float>(VT_RESPONSE, 0.0f);
	}

	/// octave (pyramid layer) from which the keypoint has been extracted.
	int32_t octave() const {
		return GetField<int32_t>(VT_OCTAVE, 0);
	}

	/// object class (if the keypoints need to be clustered by an object they belong to).
	int32_t class_id() const {
		return GetField<int32_t>(VT_CLASS_ID, 0);
	}

	/// Timestamp (µs).
	int64_t timestamp() const {
		return GetField<int64_t>(VT_TIMESTAMP, 0);
	}

	bool Verify(flatbuffers::Verifier &verifier) const {
		return VerifyTableStart(verifier) && VerifyField<Point2f>(verifier, VT_PT)
			&& VerifyField<float>(verifier, VT_SIZE) && VerifyField<float>(verifier, VT_ANGLE)
			&& VerifyField<float>(verifier, VT_RESPONSE) && VerifyField<int32_t>(verifier, VT_OCTAVE)
			&& VerifyField<int32_t>(verifier, VT_CLASS_ID) && VerifyField<int64_t>(verifier, VT_TIMESTAMP)
			&& verifier.EndTable();
	}

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

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

	void add_pt(const Point2f *pt) {
		fbb_.AddStruct(TimedKeyPointFlatbuffer::VT_PT, pt);
	}

	void add_size(float size) {
		fbb_.AddElement<float>(TimedKeyPointFlatbuffer::VT_SIZE, size, 0.0f);
	}

	void add_angle(float angle) {
		fbb_.AddElement<float>(TimedKeyPointFlatbuffer::VT_ANGLE, angle, 0.0f);
	}

	void add_response(float response) {
		fbb_.AddElement<float>(TimedKeyPointFlatbuffer::VT_RESPONSE, response, 0.0f);
	}

	void add_octave(int32_t octave) {
		fbb_.AddElement<int32_t>(TimedKeyPointFlatbuffer::VT_OCTAVE, octave, 0);
	}

	void add_class_id(int32_t class_id) {
		fbb_.AddElement<int32_t>(TimedKeyPointFlatbuffer::VT_CLASS_ID, class_id, 0);
	}

	void add_timestamp(int64_t timestamp) {
		fbb_.AddElement<int64_t>(TimedKeyPointFlatbuffer::VT_TIMESTAMP, timestamp, 0);
	}

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

	TimedKeyPointBuilder &operator=(const TimedKeyPointBuilder &);

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

inline flatbuffers::Offset<TimedKeyPointFlatbuffer> CreateTimedKeyPoint(flatbuffers::FlatBufferBuilder &_fbb,
	const Point2f *pt = 0, float size = 0.0f, float angle = 0.0f, float response = 0.0f, int32_t octave = 0,
	int32_t class_id = 0, int64_t timestamp = 0) {
	TimedKeyPointBuilder builder_(_fbb);
	builder_.add_timestamp(timestamp);
	builder_.add_class_id(class_id);
	builder_.add_octave(octave);
	builder_.add_response(response);
	builder_.add_angle(angle);
	builder_.add_size(size);
	builder_.add_pt(pt);
	return builder_.Finish();
}

flatbuffers::Offset<TimedKeyPointFlatbuffer> CreateTimedKeyPoint(flatbuffers::FlatBufferBuilder &_fbb,
	const TimedKeyPoint *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

struct TimedKeyPointPacket : public flatbuffers::NativeTable {
	typedef TimedKeyPointPacketFlatbuffer TableType;

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

	std::vector<TimedKeyPoint> elements;

	TimedKeyPointPacket() {
	}

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

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

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

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

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

struct TimedKeyPointPacketFlatbuffer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
	typedef TimedKeyPointPacket NativeTableType;
	static FLATBUFFERS_CONSTEXPR const char *identifier = "TKPS";

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

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

	enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
		VT_ELEMENTS = 4
	};

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

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

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

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

	void add_elements(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TimedKeyPointFlatbuffer>>> elements) {
		fbb_.AddOffset(TimedKeyPointPacketFlatbuffer::VT_ELEMENTS, elements);
	}

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

	TimedKeyPointPacketBuilder &operator=(const TimedKeyPointPacketBuilder &);

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

inline flatbuffers::Offset<TimedKeyPointPacketFlatbuffer> CreateTimedKeyPointPacket(
	flatbuffers::FlatBufferBuilder &_fbb,
	flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TimedKeyPointFlatbuffer>>> elements = 0) {
	TimedKeyPointPacketBuilder builder_(_fbb);
	builder_.add_elements(elements);
	return builder_.Finish();
}

inline flatbuffers::Offset<TimedKeyPointPacketFlatbuffer> CreateTimedKeyPointPacketDirect(
	flatbuffers::FlatBufferBuilder &_fbb,
	const std::vector<flatbuffers::Offset<TimedKeyPointFlatbuffer>> *elements = nullptr) {
	auto elements__ = elements ? _fbb.CreateVector<flatbuffers::Offset<TimedKeyPointFlatbuffer>>(*elements) : 0;
	return dv::CreateTimedKeyPointPacket(_fbb, elements__);
}

flatbuffers::Offset<TimedKeyPointPacketFlatbuffer> CreateTimedKeyPointPacket(flatbuffers::FlatBufferBuilder &_fbb,
	const TimedKeyPointPacket *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);

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

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

inline void TimedKeyPointFlatbuffer::UnPackToFrom(
	TimedKeyPoint *_o, const TimedKeyPointFlatbuffer *_fb, const flatbuffers::resolver_function_t *_resolver) {
	(void) _o;
	(void) _fb;
	(void) _resolver;
	{
		auto _e = _fb->pt();
		if (_e)
			_o->pt = *_e;
	};
	{
		auto _e  = _fb->size();
		_o->size = _e;
	};
	{
		auto _e   = _fb->angle();
		_o->angle = _e;
	};
	{
		auto _e      = _fb->response();
		_o->response = _e;
	};
	{
		auto _e    = _fb->octave();
		_o->octave = _e;
	};
	{
		auto _e      = _fb->class_id();
		_o->class_id = _e;
	};
	{
		auto _e       = _fb->timestamp();
		_o->timestamp = _e;
	};
}

inline flatbuffers::Offset<TimedKeyPointFlatbuffer> TimedKeyPointFlatbuffer::Pack(
	flatbuffers::FlatBufferBuilder &_fbb, const TimedKeyPoint *_o, const flatbuffers::rehasher_function_t *_rehasher) {
	return CreateTimedKeyPoint(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<TimedKeyPointFlatbuffer> CreateTimedKeyPoint(
	flatbuffers::FlatBufferBuilder &_fbb, const TimedKeyPoint *_o, const flatbuffers::rehasher_function_t *_rehasher) {
	(void) _rehasher;
	(void) _o;

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

	(void) _va;
	auto _pt        = &_o->pt;
	auto _size      = _o->size;
	auto _angle     = _o->angle;
	auto _response  = _o->response;
	auto _octave    = _o->octave;
	auto _class_id  = _o->class_id;
	auto _timestamp = _o->timestamp;
	return dv::CreateTimedKeyPoint(_fbb, _pt, _size, _angle, _response, _octave, _class_id, _timestamp);
}

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

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

inline void TimedKeyPointPacketFlatbuffer::UnPackToFrom(TimedKeyPointPacket *_o,
	const TimedKeyPointPacketFlatbuffer *_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++) {
				_e->Get(_i)->UnPackTo(&_o->elements[_i], _resolver);
			}
		}
	};
}

inline flatbuffers::Offset<TimedKeyPointPacketFlatbuffer> TimedKeyPointPacketFlatbuffer::Pack(
	flatbuffers::FlatBufferBuilder &_fbb, const TimedKeyPointPacket *_o,
	const flatbuffers::rehasher_function_t *_rehasher) {
	return CreateTimedKeyPointPacket(_fbb, _o, _rehasher);
}

inline flatbuffers::Offset<TimedKeyPointPacketFlatbuffer> CreateTimedKeyPointPacket(
	flatbuffers::FlatBufferBuilder &_fbb, const TimedKeyPointPacket *_o,
	const flatbuffers::rehasher_function_t *_rehasher) {
	(void) _rehasher;
	(void) _o;

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

	(void) _va;
	auto _elements = _o->elements.size()
					   ? _fbb.CreateVector<flatbuffers::Offset<TimedKeyPointFlatbuffer>>(
							 _o->elements.size(),
							 [](size_t i, _VectorArgs *__va) {
								 return CreateTimedKeyPoint(*__va->__fbb, &__va->__o->elements[i], __va->__rehasher);
							 },
							 &_va)
					   : 0;
	return dv::CreateTimedKeyPointPacket(_fbb, _elements);
}

inline const flatbuffers::TypeTable *TimedKeyPointTypeTable() {
	static const flatbuffers::TypeCode type_codes[] = {
		{flatbuffers::ET_SEQUENCE, 0, 0 },
        {flatbuffers::ET_FLOAT,    0, -1},
        {flatbuffers::ET_FLOAT,    0, -1},
		{flatbuffers::ET_FLOAT,    0, -1},
        {flatbuffers::ET_INT,      0, -1},
        {flatbuffers::ET_INT,      0, -1},
		{flatbuffers::ET_LONG,     0, -1}
    };
	static const flatbuffers::TypeFunction type_refs[] = {Point2fTypeTable};
	static const char *const names[]       = {"pt", "size", "angle", "response", "octave", "class_id", "timestamp"};
	static const flatbuffers::TypeTable tt = {flatbuffers::ST_TABLE, 7, type_codes, type_refs, nullptr, names};
	return &tt;
}

inline const flatbuffers::TypeTable *TimedKeyPointPacketTypeTable() {
	static const flatbuffers::TypeCode type_codes[] = {
		{flatbuffers::ET_SEQUENCE, 1, 0}
    };
	static const flatbuffers::TypeFunction type_refs[] = {TimedKeyPointTypeTable};
	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::TimedKeyPointPacketFlatbuffer *GetTimedKeyPointPacket(const void *buf) {
	return flatbuffers::GetRoot<dv::TimedKeyPointPacketFlatbuffer>(buf);
}

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

inline const char *TimedKeyPointPacketIdentifier() {
	return "TKPS";
}

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

inline bool VerifyTimedKeyPointPacketBuffer(flatbuffers::Verifier &verifier) {
	return verifier.VerifyBuffer<dv::TimedKeyPointPacketFlatbuffer>(TimedKeyPointPacketIdentifier());
}

inline bool VerifySizePrefixedTimedKeyPointPacketBuffer(flatbuffers::Verifier &verifier) {
	return verifier.VerifySizePrefixedBuffer<dv::TimedKeyPointPacketFlatbuffer>(TimedKeyPointPacketIdentifier());
}

inline void FinishTimedKeyPointPacketBuffer(
	flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<dv::TimedKeyPointPacketFlatbuffer> root) {
	fbb.Finish(root, TimedKeyPointPacketIdentifier());
}

inline void FinishSizePrefixedTimedKeyPointPacketBuffer(
	flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<dv::TimedKeyPointPacketFlatbuffer> root) {
	fbb.FinishSizePrefixed(root, TimedKeyPointPacketIdentifier());
}

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

} // namespace dv

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

#endif // FLATBUFFERS_GENERATED_TIMEDKEYPOINT_DV_H_
