//------------------------------------------------------------------------------ // Automatically generated by the Fast Binary Encoding compiler, do not modify! // https://github.com/chronoxor/FastBinaryEncoding // Source: FBE // FBE version: 1.14.1.0 //------------------------------------------------------------------------------ #pragma once #if defined(__clang__) #pragma clang system_header #elif defined(__GNUC__) #pragma GCC system_header #elif defined(_MSC_VER) #pragma system_header #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) #include #include #undef HOST_NOT_FOUND #elif defined(_WIN32) || defined(_WIN64) #undef DELETE #undef ERROR #undef HOST_NOT_FOUND #undef Yield #undef min #undef max #undef uuid_t #endif namespace FBE { //! Bytes buffer type /*! Represents bytes buffer which is a lightweight wrapper around std::vector with similar interface. */ class buffer_t { public: typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; typedef std::vector::reverse_iterator reverse_iterator; typedef std::vector::const_reverse_iterator const_reverse_iterator; buffer_t() = default; buffer_t(size_t capacity) { reserve(capacity); } buffer_t(const std::string& str) { assign(str); } buffer_t(size_t size, uint8_t value) { assign(size, value); } buffer_t(const uint8_t* data, size_t size) { assign(data, size); } buffer_t(const std::vector& other) : _data(other) {} buffer_t(std::vector&& other) : _data(std::move(other)) {} buffer_t(const buffer_t& other) = default; buffer_t(buffer_t&& other) = default; ~buffer_t() = default; buffer_t& operator=(const std::string& str) { assign(str); return *this; } buffer_t& operator=(const std::vector& other) { _data = other; return *this; } buffer_t& operator=(std::vector&& other) { _data = std::move(other); return *this; } buffer_t& operator=(const buffer_t& other) = default; buffer_t& operator=(buffer_t&& other) = default; uint8_t& operator[](size_t index) { return _data[index]; } const uint8_t& operator[](size_t index) const { return _data[index]; } bool empty() const { return _data.empty(); } size_t capacity() const { return _data.capacity(); } size_t size() const { return _data.size(); } size_t max_size() const { return _data.max_size(); } std::vector& buffer() noexcept { return _data; } const std::vector& buffer() const noexcept { return _data; } uint8_t* data() noexcept { return _data.data(); } const uint8_t* data() const noexcept { return _data.data(); } uint8_t& at(size_t index) { return _data.at(index); } const uint8_t& at(size_t index) const { return _data.at(index); } uint8_t& front() { return _data.front(); } const uint8_t& front() const { return _data.front(); } uint8_t& back() { return _data.back(); } const uint8_t& back() const { return _data.back(); } void reserve(size_t capacity) { _data.reserve(capacity); } void resize(size_t size, uint8_t value = 0) { _data.resize(size, value); } void shrink_to_fit() { _data.shrink_to_fit(); } void assign(const std::string& str) { assign((const uint8_t*)str.c_str(), str.size()); } void assign(const std::vector& vec) { assign(vec.begin(), vec.end()); } void assign(size_t size, uint8_t value) { _data.assign(size, value); } void assign(const uint8_t* data, size_t size) { _data.assign(data, data + size); } template void assign(InputIterator first, InputIterator last) { _data.assign(first, last); } iterator insert(const_iterator position, uint8_t value) { return _data.insert(position, value); } iterator insert(const_iterator position, const std::string& str) { return insert(position, (const uint8_t*)str.c_str(), str.size()); } iterator insert(const_iterator position, const std::vector& vec) { return insert(position, vec.begin(), vec.end()); } iterator insert(const_iterator position, size_t size, uint8_t value) { return _data.insert(position, size, value); } iterator insert(const_iterator position, const uint8_t* data, size_t size) { return _data.insert(position, data, data + size); } template iterator insert(const_iterator position, InputIterator first, InputIterator last) { return _data.insert(position, first, last); } iterator erase(const_iterator position) { return _data.erase(position); } iterator erase(const_iterator first, const_iterator last) { return _data.erase(first, last); } void clear() noexcept { _data.clear(); } void push_back(uint8_t value) { _data.push_back(value); } void pop_back() { _data.pop_back(); } template iterator emplace(const_iterator position, Args&&... args) { return _data.emplace(position, args...); } template void emplace_back(Args&&... args) { _data.emplace_back(args...); } iterator begin() noexcept { return _data.begin(); } const_iterator begin() const noexcept { return _data.begin(); } const_iterator cbegin() const noexcept { return _data.cbegin(); } reverse_iterator rbegin() noexcept { return _data.rbegin(); } const_reverse_iterator rbegin() const noexcept { return _data.rbegin(); } const_reverse_iterator crbegin() const noexcept { return _data.crbegin(); } iterator end() noexcept { return _data.end(); } const_iterator end() const noexcept { return _data.end(); } const_iterator cend() const noexcept { return _data.cend(); } reverse_iterator rend() noexcept { return _data.rend(); } const_reverse_iterator rend() const noexcept { return _data.rend(); } const_reverse_iterator crend() const noexcept { return _data.crend(); } //! Get the string equivalent from the bytes buffer std::string string() const { return std::string(_data.begin(), _data.end()); } //! Encode the Base64 string from the bytes buffer std::string base64encode() const; //! Decode the bytes buffer from the Base64 string static buffer_t base64decode(const std::string& str); //! Swap two instances void swap(buffer_t& value) noexcept { using std::swap; swap(_data, value._data); } friend void swap(buffer_t& value1, buffer_t& value2) noexcept { value1.swap(value2); } private: std::vector _data; }; //! Decimal type /*! Represents decimal type using double and provides basic arithmetic operations. */ class decimal_t { public: decimal_t() noexcept { _value = 0.0; } decimal_t(int8_t value) noexcept { _value = (double)value; } decimal_t(uint8_t value) noexcept { _value = (double)value; } decimal_t(int16_t value) noexcept { _value = (double)value; } decimal_t(uint16_t value) noexcept { _value = (double)value; } decimal_t(int32_t value) noexcept { _value = (double)value; } decimal_t(uint32_t value) noexcept { _value = (double)value; } decimal_t(int64_t value) noexcept { _value = (double)value; } decimal_t(uint64_t value) noexcept { _value = (double)value; } decimal_t(float value) noexcept { _value = (double)value; } decimal_t(double value) noexcept { _value = value; } template explicit decimal_t(const T& value) noexcept { _value = (double)value; } decimal_t(const decimal_t& value) noexcept = default; decimal_t(decimal_t&& value) noexcept = default; ~decimal_t() noexcept = default; template decimal_t& operator=(const T& value) noexcept { _value = (double)value; return *this; } decimal_t& operator=(const decimal_t& value) noexcept = default; decimal_t& operator=(decimal_t&& value) noexcept = default; // Arithmetic operators decimal_t operator+() const noexcept { return decimal_t(_value); } decimal_t operator-() const noexcept { return decimal_t(-_value); } decimal_t& operator++() noexcept { return *this += 1; } decimal_t operator++(int) noexcept { decimal_t temp(*this); ++*this; return temp; } decimal_t& operator--() noexcept { return *this -= 1; } decimal_t operator--(int) noexcept { decimal_t temp(*this); --*this; return temp; } decimal_t& operator+=(const decimal_t& value) noexcept { return *this = *this + value; } decimal_t& operator-=(const decimal_t& value) noexcept { return *this = *this - value; } decimal_t& operator*=(const decimal_t& value) noexcept { return *this = *this * value; } decimal_t& operator/=(const decimal_t& value) { return *this = *this / value; } template decimal_t& operator+=(const T& value) noexcept { return *this = *this + decimal_t(value); } template decimal_t& operator-=(const T& value) noexcept { return *this = *this - decimal_t(value); } template decimal_t& operator*=(const T& value) noexcept { return *this = *this * decimal_t(value); } template decimal_t& operator/=(const T& value) { return *this = *this / decimal_t(value); } template friend T& operator+=(T& value1, const decimal_t& value2) noexcept { return value1 = (T)(decimal_t(value1) + value2); } template friend T& operator-=(T& value1, const decimal_t& value2) noexcept { return value1 = (T)(decimal_t(value1) - value2); } template friend T& operator*=(T& value1, const decimal_t& value2) noexcept { return value1 = (T)(decimal_t(value1) * value2); } template friend T& operator/=(T& value1, const decimal_t& value2) { return value1 = (T)(decimal_t(value1) / value2); } template friend decimal_t operator+(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) + value2; } template friend decimal_t operator+(const decimal_t& value1, const T& value2) noexcept { return value1 + decimal_t(value2); } friend decimal_t operator+(const decimal_t& value1, const decimal_t& value2) noexcept { return decimal_t(value1._value + value2._value); } template friend decimal_t operator-(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) - value2; } template friend decimal_t operator-(const decimal_t& value1, const T& value2) noexcept { return value1 - decimal_t(value2); } friend decimal_t operator-(const decimal_t& value1, const decimal_t& value2) noexcept { return decimal_t(value1._value - value2._value); } template friend decimal_t operator*(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) * value2; } template friend decimal_t operator*(const decimal_t& value1, const T& value2) noexcept { return value1 * decimal_t(value2); } friend decimal_t operator*(const decimal_t& value1, const decimal_t& value2) noexcept { return decimal_t(value1._value * value2._value); } template friend decimal_t operator/(const T& value1, const decimal_t& value2) { return decimal_t(value1) / value2; } template friend decimal_t operator/(const decimal_t& value1, const T& value2) { return value1 / decimal_t(value2); } friend decimal_t operator/(const decimal_t& value1, const decimal_t& value2) { return decimal_t(value1._value / value2._value); } // Comparison operators template friend bool operator==(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) == value2; } template friend bool operator==(const decimal_t& value1, const T& value2) noexcept { return value1 == decimal_t(value2); } friend bool operator==(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value == value2._value; } template friend bool operator!=(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) != value2; } template friend bool operator!=(const decimal_t& value1, const T& value2) noexcept { return value1 != decimal_t(value2); } friend bool operator!=(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value != value2._value; } template friend bool operator<(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) < value2; } template friend bool operator<(const decimal_t& value1, const T& value2) noexcept { return value1 < decimal_t(value2); } friend bool operator<(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value < value2._value; } template friend bool operator>(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) > value2; } template friend bool operator>(const decimal_t& value1, const T& value2) noexcept { return value1 > decimal_t(value2); } friend bool operator>(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value > value2._value; } template friend bool operator<=(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) <= value2; } template friend bool operator<=(const decimal_t& value1, const T& value2) noexcept { return value1 <= decimal_t(value2); } friend bool operator<=(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value <= value2._value; } template friend bool operator>=(const T& value1, const decimal_t& value2) noexcept { return decimal_t(value1) >= value2; } template friend bool operator>=(const decimal_t& value1, const T& value2) noexcept { return value1 >= decimal_t(value2); } friend bool operator>=(const decimal_t& value1, const decimal_t& value2) noexcept { return value1._value >= value2._value; } // Type cast operator bool() const noexcept { return (_value != 0.0); } operator uint8_t() const noexcept { return (uint8_t)_value; } operator uint16_t() const noexcept { return (uint16_t)_value; } operator uint32_t() const noexcept { return (uint32_t)_value; } operator uint64_t() const noexcept { return (uint64_t)_value; } operator float() const noexcept { return (float)_value; } operator double() const noexcept { return (double)_value; } //! Get string from the current decimal value std::string string() const { return std::to_string(_value); } //! Input instance from the given input stream friend std::istream& operator>>(std::istream& is, decimal_t& value) { is >> value._value; return is; } //! Output instance into the given output stream friend std::ostream& operator<<(std::ostream& os, const decimal_t& value) { os << value.string(); return os; } #if defined(LOGGING_PROTOCOL) //! Store logging format friend CppLogging::Record& operator<<(CppLogging::Record& record, const decimal_t& value) { return record.StoreCustom(value._value); } #endif //! Swap two instances void swap(decimal_t& value) noexcept { using std::swap; swap(_value, value._value); } friend void swap(decimal_t& value1, decimal_t& value2) noexcept { value1.swap(value2); } private: double _value; }; } // namespace FBE #if defined(FMT_VERSION) && (FMT_VERSION >= 90000) template <> struct fmt::formatter : formatter { template auto format(const FBE::decimal_t& value, FormatContext& ctx) const { return formatter::format((double)value, ctx); } }; #endif template <> struct std::hash { typedef FBE::decimal_t argument_type; typedef size_t result_type; result_type operator() (const argument_type& value) const { result_type result = 17; result = result * 31 + std::hash()((double)value); return result; } }; namespace FBE { // Register a new enum-based flags macro #define FBE_ENUM_FLAGS(type)\ inline FBE::Flags operator|(type f1, type f2) noexcept { return FBE::Flags(f1) | FBE::Flags(f2); }\ inline FBE::Flags operator&(type f1, type f2) noexcept { return FBE::Flags(f1) & FBE::Flags(f2); }\ inline FBE::Flags operator^(type f1, type f2) noexcept { return FBE::Flags(f1) ^ FBE::Flags(f2); } // Enum-based flags template class Flags { // Enum underlying type typedef typename std::make_unsigned::type>::type type; public: Flags() noexcept : _value(0) {} explicit Flags(type value) noexcept : _value(value) {} explicit Flags(TEnum value) noexcept : _value((type)value) {} Flags(const Flags&) noexcept = default; Flags(Flags&&) noexcept = default; ~Flags() noexcept = default; Flags& operator=(type value) noexcept { _value = value; return *this; } Flags& operator=(TEnum value) noexcept { _value = (type)value; return *this; } Flags& operator=(const Flags&) noexcept = default; Flags& operator=(Flags&&) noexcept = default; // Is any flag set? explicit operator bool() const noexcept { return isset(); } // Is no flag set? bool operator!() const noexcept { return !isset(); } // Reverse all flags Flags operator~() const noexcept { return Flags(~_value); } // Flags logical assign operators Flags& operator&=(const Flags& flags) noexcept { _value &= flags._value; return *this; } Flags& operator|=(const Flags& flags) noexcept { _value |= flags._value; return *this; } Flags& operator^=(const Flags& flags) noexcept { _value ^= flags._value; return *this; } // Flags logical friend operators friend Flags operator&(const Flags& flags1, const Flags& flags2) noexcept { return Flags(flags1._value & flags2._value); } friend Flags operator|(const Flags& flags1, const Flags& flags2) noexcept { return Flags(flags1._value | flags2._value); } friend Flags operator^(const Flags& flags1, const Flags& flags2) noexcept { return Flags(flags1._value ^ flags2._value); } // Flags comparison friend bool operator==(const Flags& flags1, const Flags& flags2) noexcept { return flags1._value == flags2._value; } friend bool operator!=(const Flags& flags1, const Flags& flags2) noexcept { return flags1._value != flags2._value; } // Convert to the enum value operator TEnum() const noexcept { return (TEnum)_value; } //! Is any flag set? bool isset() const noexcept { return (_value != 0); } //! Is the given flag set? bool isset(type value) const noexcept { return (_value & value) != 0; } //! Is the given flag set? bool isset(TEnum value) const noexcept { return (_value & (type)value) != 0; } // Get the enum value TEnum value() const noexcept { return (TEnum)_value; } // Get the underlying enum value type underlying() const noexcept { return _value; } // Get the bitset value std::bitset bitset() const noexcept { return {_value}; } // Swap two instances void swap(Flags& flags) noexcept { using std::swap; swap(_value, flags._value); } template friend void swap(Flags& flags1, Flags& flags2) noexcept; private: type _value; }; template inline void swap(Flags& flags1, Flags& flags2) noexcept { flags1.swap(flags2); } // Get Epoch timestamp inline uint64_t epoch() { return 0ull; } // Get UTC timestamp uint64_t utc(); //! Universally unique identifier (UUID) /*! A universally unique identifier (UUID) is an identifier standard used in software construction. This implementation generates the following UUID types: - Nil UUID0 (all bits set to zero) - Sequential UUID1 (time based version) - Random UUID4 (randomly or pseudo-randomly generated version) A UUID is simply a 128-bit value: "123e4567-e89b-12d3-a456-426655440000" https://en.wikipedia.org/wiki/Universally_unique_identifier https://www.ietf.org/rfc/rfc4122.txt */ class uuid_t { public: //! Default constructor uuid_t() : _data() { _data.fill(0); } //! Initialize UUID with a given string /*! \param uuid - UUID string */ explicit uuid_t(const std::string& uuid); //! Initialize UUID with a given 16 bytes data buffer /*! \param data - UUID 16 bytes data buffer */ explicit uuid_t(const std::array& data) : _data(data) {} uuid_t(const uuid_t&) = default; uuid_t(uuid_t&&) noexcept = default; ~uuid_t() = default; uuid_t& operator=(const std::string& uuid) { _data = uuid_t(uuid).data(); return *this; } uuid_t& operator=(const std::array& data) { _data = data; return *this; } uuid_t& operator=(const uuid_t&) = default; uuid_t& operator=(uuid_t&&) noexcept = default; // UUID comparison friend bool operator==(const uuid_t& uuid1, const uuid_t& uuid2) { return uuid1._data == uuid2._data; } friend bool operator!=(const uuid_t& uuid1, const uuid_t& uuid2) { return uuid1._data != uuid2._data; } friend bool operator<(const uuid_t& uuid1, const uuid_t& uuid2) { return uuid1._data < uuid2._data; } friend bool operator>(const uuid_t& uuid1, const uuid_t& uuid2) { return uuid1._data > uuid2._data; } friend bool operator<=(const uuid_t& uuid1, const uuid_t& uuid2) { return uuid1._data <= uuid2._data; } friend bool operator>=(const uuid_t& uuid1, const uuid_t& uuid2) { return uuid1._data >= uuid2._data; } //! Check if the UUID is nil UUID0 (all bits set to zero) explicit operator bool() const noexcept { return *this != nil(); } //! Get the UUID data buffer std::array& data() noexcept { return _data; } //! Get the UUID data buffer const std::array& data() const noexcept { return _data; } //! Get string from the current UUID in format "00000000-0000-0000-0000-000000000000" std::string string() const; //! Generate nil UUID0 (all bits set to zero) static uuid_t nil() { return uuid_t(); } //! Generate sequential UUID1 (time based version) static uuid_t sequential(); //! Generate random UUID4 (randomly or pseudo-randomly generated version) static uuid_t random(); //! Output instance into the given output stream friend std::ostream& operator<<(std::ostream& os, const uuid_t& uuid) { os << uuid.string(); return os; } #if defined(LOGGING_PROTOCOL) //! Store logging format friend CppLogging::Record& operator<<(CppLogging::Record& record, const uuid_t& uuid); #endif //! Swap two instances void swap(uuid_t& uuid) noexcept { using std::swap; swap(_data, uuid._data); } friend void swap(uuid_t& uuid1, uuid_t& uuid2) noexcept { uuid1.swap(uuid2); } private: std::array _data; }; } // namespace FBE #if defined(FMT_VERSION) && (FMT_VERSION >= 90000) template <> struct fmt::formatter : formatter { template auto format(const FBE::uuid_t& value, FormatContext& ctx) const { return formatter::format(value.string(), ctx); } }; #endif template <> struct std::hash { typedef FBE::uuid_t argument_type; typedef size_t result_type; result_type operator() (const argument_type& value) const { result_type result = 17; std::hash hasher; for (size_t i = 0; i < value.data().size(); ++i) result = result * 31 + hasher(value.data()[i]); return result; } }; namespace FBE { // Fast Binary Encoding buffer based on the dynamic byte buffer class FBEBuffer { public: FBEBuffer() : _data(nullptr), _capacity(0), _size(0), _offset(0) {} // Initialize the read buffer with the given byte buffer and offset explicit FBEBuffer(const void* data, size_t size, size_t offset = 0) { attach(data, size, offset); } // Initialize the read buffer with the given byte vector and offset explicit FBEBuffer(const std::vector& buffer, size_t offset = 0) { attach(buffer, offset); } // Initialize the read buffer with another buffer and offset explicit FBEBuffer(const FBEBuffer& buffer, size_t offset = 0) { attach(buffer.data(), buffer.size(), offset); } // Initialize the write buffer with the given capacity explicit FBEBuffer(size_t capacity) : FBEBuffer() { reserve(capacity); } FBEBuffer(const FBEBuffer&) = delete; FBEBuffer(FBEBuffer&&) noexcept = delete; ~FBEBuffer() { if (_capacity > 0) std::free(_data); } FBEBuffer& operator=(const FBEBuffer&) = delete; FBEBuffer& operator=(FBEBuffer&&) noexcept = delete; bool empty() const noexcept { return (_data == nullptr) || (_size == 0); } const uint8_t* data() const noexcept { return _data; } uint8_t* data() noexcept { return _data; } size_t capacity() const noexcept { return _capacity; } size_t size() const noexcept { return _size; } size_t offset() const noexcept { return _offset; } // Attach the given buffer with a given offset to the current read buffer void attach(const void* data, size_t size, size_t offset = 0); // Attach the given byte vector with a given offset to the current read buffer void attach(const std::vector& buffer, size_t offset = 0); // Clone the given buffer with a given offset to the current buffer void clone(const void* data, size_t size, size_t offset = 0); // Clone the given vector with a given offset to the current buffer void clone(const std::vector& buffer, size_t offset = 0); // Allocate memory in the current write buffer and return offset to the allocated memory block size_t allocate(size_t size); // Remove some memory of the given size from the current write buffer void remove(size_t offset, size_t size); // Reserve memory of the given capacity in the current write buffer void reserve(size_t capacity); // Resize the current write buffer void resize(size_t size); // Reset the current write buffer and its offset void reset(); // Shift the current write buffer offset void shift(size_t offset) { _offset += offset; } // Unshift the current write buffer offset void unshift(size_t offset) { _offset -= offset; } private: uint8_t* _data; size_t _capacity; size_t _size; size_t _offset; }; // Fast Binary Encoding base model class Model { public: Model() : Model(nullptr) {} Model(const std::shared_ptr& buffer) { _buffer = buffer ? buffer : std::make_shared(); } Model(const Model&) = default; Model(Model&&) noexcept = default; ~Model() = default; Model& operator=(const Model&) = default; Model& operator=(Model&&) noexcept = default; // Get the model buffer FBEBuffer& buffer() noexcept { return *_buffer; } const FBEBuffer& buffer() const noexcept { return *_buffer; } // Attach the model buffer void attach(const void* data, size_t size, size_t offset = 0) { _buffer->attach(data, size, offset); } void attach(const std::vector& buffer, size_t offset = 0) { _buffer->attach(buffer, offset); } void attach(const FBEBuffer& buffer, size_t offset = 0) { _buffer->attach(buffer.data(), buffer.size(), offset); } // Model buffer operations size_t allocate(size_t size) { return _buffer->allocate(size); } void remove(size_t offset, size_t size) { _buffer->remove(offset, size); } void reserve(size_t capacity) { _buffer->reserve(capacity); } void resize(size_t size) { _buffer->resize(size); } void reset() { _buffer->reset(); } void shift(size_t offset) { _buffer->shift(offset); } void unshift(size_t offset) { _buffer->unshift(offset); } private: std::shared_ptr _buffer; }; } // namespace FBE