101#include <string_view>
102#include <unordered_map>
129 enum Type : uint8_t {
150 uint8_t type{kUnknownType};
161 using KeyMap = std::unordered_map<std::string, uint16_t>;
166 using KeyList = std::vector<Key>;
197 explicit Vector3f(
float _x,
float _y,
float _z)
noexcept;
206 friend std::ostream& operator<<(std::ostream& ostream,
const Vector3f& v3f)
noexcept;
238 explicit Vector3d(
double _x,
double _y,
double _z)
noexcept;
247 friend std::ostream& operator<<(std::ostream& ostream,
const Vector3d& v3d)
noexcept;
307 bool operator<<(const Bytes& bytes) noexcept;
319 bool operator>>(Bytes& bytes) const noexcept;
327 [[nodiscard]] static
bool check_valid(const Bytes& bytes) noexcept;
335 [[nodiscard]]
bool is_valid() const noexcept;
347 bool shallow_copy(const
PointCloud& target) noexcept;
359 bool deep_copy(const
PointCloud& target) noexcept;
380 [[nodiscard]]
size_t get_serialized_size() const noexcept;
393 [[nodiscard]] KeyMap get_key_map(KeyList* key_list =
nullptr) const noexcept;
400 [[nodiscard]]
size_t size() const noexcept;
411 [[nodiscard]]
size_t pack_size() const noexcept;
422 [[nodiscard]]
bool is_owner() const noexcept;
432 [[nodiscard]] uint64_t get_protocol_size_num() const noexcept;
442 [[nodiscard]] uint64_t get_protocol_type_num() const noexcept;
452 [[nodiscard]]
std::
string get_protocol_size_str() const noexcept;
462 [[nodiscard]]
std::
string get_protocol_name_str() const noexcept;
472 [[nodiscard]]
std::
string get_protocol_type_str() const noexcept;
483 [[nodiscard]] const uint8_t* get_internal_data() const noexcept;
494 [[nodiscard]]
size_t get_reserved_size() const noexcept;
509 bool get_value_v3f(
float& x,
float& y,
float& z,
size_t loop_index) const noexcept;
518 bool get_value_v3f(
Vector3f& v3f,
size_t loop_index) const noexcept;
526 [[nodiscard]]
Vector3f get_value_v3f(
size_t loop_index) const noexcept;
537 bool get_value_v3d(
double& x,
double& y,
double& z,
size_t loop_index) const noexcept;
546 bool get_value_v3d(
Vector3d& v3d,
size_t loop_index) const noexcept;
554 [[nodiscard]]
Vector3d get_value_v3d(
size_t loop_index) const noexcept;
569 template <typename T>
570 bool get_value(T& t,
size_t loop_index, uint16_t offset) const noexcept;
580 template <typename T>
581 [[nodiscard]] T get_value(
size_t loop_index, uint16_t offset) const noexcept;
598 template <typename T>
599 bool get_value(T& t,
size_t loop_index, KeyMap& key_map,
std::string_view key) const noexcept;
610 template <typename T>
611 [[nodiscard]] T get_value(
size_t loop_index, KeyMap& key_map,
std::string_view key) const noexcept;
626 [[nodiscard]]
double get_value_for_double_float(
size_t loop_index, uint16_t offset, uint8_t type) const noexcept;
637 [[nodiscard]]
double get_value_for_double_float(
size_t loop_index, KeyMap& key_map,
std::string_view key,
638 uint8_t type) const noexcept;
651 [[nodiscard]]
std::
string get_value_for_print(
size_t loop_index, uint16_t offset, uint8_t type) const noexcept;
662 [[nodiscard]]
std::
string get_value_for_print(
size_t loop_index, KeyMap& key_map,
std::string_view key,
663 uint8_t type) const noexcept;
679 bool create(
size_t size, uint64_t size_num, uint64_t type_num,
std::string_view key_str) noexcept;
693 template <typename... T>
694 bool create(
size_t _size, const
std::vector<
std::
string>& keys = {})
noexcept;
709 template <
typename... T>
710 bool create_v3f(
size_t _size,
const std::vector<std::string>& keys = {})
noexcept;
725 template <
typename... T>
726 bool create_v3d(
size_t _size,
const std::vector<std::string>& keys = {})
noexcept;
741 bool fill_packed_data(
const uint8_t* src_data,
size_t _size)
noexcept;
755 template <
typename... T>
756 bool push_value(T... args)
noexcept;
768 template <
typename... T>
769 bool push_value_v3f(
float x,
float y,
float z, T... args)
noexcept;
779 template <
typename... T>
780 bool push_value_v3f(Vector3f v3f, T... args)
noexcept;
792 template <
typename... T>
793 bool push_value_v3d(
double x,
double y,
double z, T... args)
noexcept;
803 template <
typename... T>
804 bool push_value_v3d(Vector3d v3d, T... args)
noexcept;
817 bool resize(
size_t size)
noexcept;
832 template <
typename... T>
833 bool set_value(
size_t loop_index, T... args)
noexcept;
844 template <
typename... T>
845 bool set_value_v3f(
size_t loop_index,
float x,
float y,
float z, T... args)
noexcept;
856 template <
typename... T>
857 bool set_value_v3f(
size_t loop_index, Vector3f v3f, T... args)
noexcept;
868 template <
typename... T>
869 bool set_value_v3d(
size_t loop_index,
double x,
double y,
double z, T... args)
noexcept;
880 template <
typename... T>
881 bool set_value_v3d(
size_t loop_index, Vector3d v3d, T... args)
noexcept;
897 void clear(
bool force =
false) noexcept;
901 static constexpr
bool kZerocopyTypes{
true};
905 uint64_t size_num{0};
907 uint64_t type_num{0};
909 Protocol() noexcept = default;
911 template <typename... T>
912 static uint64_t get_size_num() noexcept;
914 template <typename... T>
915 static uint64_t get_type_num() noexcept;
917 template <typename T>
918 static constexpr uint8_t get_type() noexcept;
920 constexpr uint64_t get_pack_size() const noexcept;
922 static
bool check_valid(uint64_t _size_num, std::string_view _names) noexcept;
924 static std::
string get_names(const std::vector<std::
string>& keys) noexcept;
926 KeyList get_key_list() const noexcept;
928 std::
string get_size_for_print() const noexcept;
930 std::
string get_type_for_print() const noexcept;
934 uint8_t* data_{
nullptr};
937 uint32_t reserved_buf_{0};
938 uint16_t pack_size_{0};
939 bool is_owner_{
false};
942 static constexpr uint32_t kMagicNumberBegin{0x98B7F16A};
943 static constexpr uint32_t kMagicNumberEnd{0x98B7F16F};
951inline bool PointCloud::get_value(T& t,
size_t loop_index, uint16_t offset)
const noexcept {
952 static_assert(std::is_fundamental_v<T>,
"T must be fundamental.");
954 size_t p = (loop_index * pack_size_) + offset;
956 if VUNLIKELY (p +
sizeof(T) > size_ * pack_size_) {
957 std::memset(&t, 0,
sizeof(T));
961 std::memcpy(&t, data_ + p,
sizeof(T));
967inline T PointCloud::get_value(
size_t loop_index, uint16_t offset)
const noexcept {
968 static_assert(std::is_fundamental_v<T>,
"T must be fundamental.");
972 get_value(t, loop_index, offset);
978inline bool PointCloud::get_value(T& t,
size_t loop_index, KeyMap& key_map, std::string_view key)
const noexcept {
979 static_assert(std::is_fundamental_v<T>,
"T must be fundamental.");
981 auto iter = key_map.find(key.data());
984 std::memset(&t, 0,
sizeof(T));
988 return get_value<T>(t, loop_index, iter->second);
992inline T PointCloud::get_value(
size_t loop_index, KeyMap& key_map, std::string_view key)
const noexcept {
993 static_assert(std::is_fundamental_v<T>,
"T must be fundamental.");
997 get_value(t, loop_index, key_map, key);
1002template <
typename... T>
1003inline bool PointCloud::create(
size_t size,
const std::vector<std::string>& keys)
noexcept {
1004 static_assert((std::is_fundamental_v<T> && ...),
"All types must be fundamental.");
1006 static_assert(
sizeof...(T) >= 3 &&
sizeof...(T) <= 16,
"The number of keys ranges is [3 ~ 16].");
1008 if VUNLIKELY (
sizeof...(T) != keys.size()) {
1012 uint64_t size_num = Protocol::get_size_num<T...>();
1018 std::string key_str = Protocol::get_names(keys);
1024 uint64_t type_num = Protocol::get_type_num<T...>();
1030 if (is_owner_ && data_ && capacity_ != 0) {
1034 protocol_.size_num = size_num;
1035 std::memset(protocol_.names, 0,
sizeof(protocol_.names));
1036 std::memcpy(protocol_.names, key_str.c_str(), key_str.size());
1037 protocol_.type_num = type_num;
1040 pack_size_ = protocol_.get_pack_size();
1041 capacity_ = size * pack_size_;
1053template <
typename... T>
1054inline bool PointCloud::create_v3f(
size_t _size,
const std::vector<std::string>& keys)
noexcept {
1055 std::vector<std::string> target_keys{
"x",
"y",
"z"};
1057 target_keys.insert(target_keys.end(), keys.begin(), keys.end());
1059 return create<float, float, float, T...>(_size, target_keys);
1062template <
typename... T>
1063inline bool PointCloud::create_v3d(
size_t _size,
const std::vector<std::string>& keys)
noexcept {
1064 std::vector<std::string> target_keys{
"x",
"y",
"z"};
1066 target_keys.insert(target_keys.end(), keys.begin(), keys.end());
1068 return create<double, double, double, T...>(_size, target_keys);
1071inline bool PointCloud::fill_packed_data(
const uint8_t* src_data,
size_t _size)
noexcept {
1072 bool is_fill_success =
false;
1074 if VUNLIKELY (_size == 0 || !src_data) {
1075 is_fill_success =
false;
1076 }
else if VUNLIKELY (!is_owner_ || !data_ || pack_size_ == 0 || capacity_ == 0) {
1077 is_fill_success =
false;
1078 }
else if VUNLIKELY (_size * pack_size_ > capacity_) {
1079 is_fill_success =
false;
1081 std::memcpy(data_, src_data, _size * pack_size_);
1083 index_ = _size * pack_size_;
1084 is_fill_success =
true;
1087 return is_fill_success;
1090template <
typename... T>
1091inline bool PointCloud::push_value(T... args)
noexcept {
1092 static_assert((std::is_fundamental_v<T> && ...),
"All types must be fundamental.");
1094 static_assert(
sizeof...(T) >= 3 &&
sizeof...(T) <= 16,
"The number of keys ranges is [3 ~ 16].");
1096 if VUNLIKELY (!is_owner_ || !data_ || pack_size_ == 0 || capacity_ == 0) {
1100 if VUNLIKELY (size_ * pack_size_ >= capacity_) {
1104 constexpr size_t kTargetPackSize = (
sizeof(T) + ...);
1106 if VUNLIKELY (kTargetPackSize != pack_size_) {
1110 auto* target_ptr = data_ + index_;
1114 std::memcpy(target_ptr, &args,
sizeof(args));
1115 target_ptr +=
sizeof(args);
1119 index_ += pack_size_;
1125template <
typename... T>
1126inline bool PointCloud::push_value_v3f(
float x,
float y,
float z, T... args)
noexcept {
1127 return push_value(x, y, z, args...);
1130template <
typename... T>
1131inline bool PointCloud::push_value_v3f(Vector3f v3f, T... args)
noexcept {
1132 return push_value(v3f.x, v3f.y, v3f.z, args...);
1135template <
typename... T>
1136inline bool PointCloud::push_value_v3d(
double x,
double y,
double z, T... args)
noexcept {
1137 return push_value(x, y, z, args...);
1140template <
typename... T>
1141inline bool PointCloud::push_value_v3d(Vector3d v3d, T... args)
noexcept {
1142 return push_value(v3d.x, v3d.y, v3d.z, args...);
1145inline bool PointCloud::resize(
size_t size)
noexcept {
1146 if VUNLIKELY (!is_owner_ || !data_ || pack_size_ == 0 || capacity_ == 0) {
1150 if VUNLIKELY (size * pack_size_ > capacity_) {
1155 index_ = size_ * pack_size_;
1160template <
typename... T>
1161bool PointCloud::set_value(
size_t loop_index, T... args)
noexcept {
1162 static_assert((std::is_fundamental_v<T> && ...),
"All types must be fundamental.");
1164 static_assert(
sizeof...(T) >= 3 &&
sizeof...(T) <= 16,
"The number of keys ranges is [3 ~ 16].");
1166 if VUNLIKELY (!is_owner_ || !data_ || pack_size_ == 0 || capacity_ == 0) {
1170 if VUNLIKELY (loop_index >= size_ || size_ * pack_size_ > capacity_) {
1174 if VUNLIKELY (index_ != size_ * pack_size_) {
1175 std::cerr <<
"[PointCloud::set_value] Invalid buffer state: "
1176 <<
"The current buffer size does not match the capacity. "
1177 <<
"Please call resize(size) before using set_value()." << std::endl;
1181 constexpr size_t kTargetPackSize = (
sizeof(T) + ...);
1183 if VUNLIKELY (kTargetPackSize != pack_size_) {
1187 auto* target_ptr = data_ + (loop_index * pack_size_);
1191 std::memcpy(target_ptr, &args,
sizeof(args));
1192 target_ptr +=
sizeof(args);
1199template <
typename... T>
1200inline bool PointCloud::set_value_v3f(
size_t loop_index,
float x,
float y,
float z, T... args)
noexcept {
1201 return set_value(loop_index, x, y, z, args...);
1204template <
typename... T>
1205inline bool PointCloud::set_value_v3f(
size_t loop_index, Vector3f v3f, T... args)
noexcept {
1206 return set_value(loop_index, v3f.x, v3f.y, v3f.z, args...);
1209template <
typename... T>
1210inline bool PointCloud::set_value_v3d(
size_t loop_index,
double x,
double y,
double z, T... args)
noexcept {
1211 return set_value(loop_index, x, y, z, args...);
1214template <
typename... T>
1215inline bool PointCloud::set_value_v3d(
size_t loop_index, Vector3d v3d, T... args)
noexcept {
1216 return set_value(loop_index, v3d.x, v3d.y, v3d.z, args...);
1219template <
typename... T>
1220inline uint64_t PointCloud::Protocol::get_size_num() noexcept {
1221 uint64_t target_num = 0;
1223 uint64_t key_shift =
sizeof...(T) * 4;
1228 target_num |= (
static_cast<uint64_t
>(
sizeof(type)) & 0xF) << key_shift;
1235template <
typename... T>
1236inline uint64_t PointCloud::Protocol::get_type_num() noexcept {
1237 uint64_t target_num = 0;
1239 uint64_t key_shift =
sizeof...(T) * 4;
1244 target_num |= (
static_cast<uint64_t
>(get_type<decltype(type)>()) & 0xF) << key_shift;
1251template <
typename T>
1252inline constexpr uint8_t PointCloud::Protocol::get_type() noexcept {
1253 if constexpr (std::is_same_v<T, bool>) {
1255 }
else if constexpr (std::is_same_v<T, int8_t>) {
1257 }
else if constexpr (std::is_same_v<T, uint8_t>) {
1259 }
else if constexpr (std::is_same_v<T, int16_t>) {
1261 }
else if constexpr (std::is_same_v<T, uint16_t>) {
1263 }
else if constexpr (std::is_same_v<T, int32_t>) {
1265 }
else if constexpr (std::is_same_v<T, uint32_t>) {
1267 }
else if constexpr (std::is_same_v<T, int64_t>) {
1269 }
else if constexpr (std::is_same_v<T, uint64_t>) {
1271 }
else if constexpr (std::is_same_v<T, float>) {
1273 }
else if constexpr (std::is_same_v<T, double>) {
1280inline constexpr uint64_t PointCloud::Protocol::get_pack_size() const noexcept {
1283 auto target_num = size_num;
1285 while (target_num > 0) {
1286 sum += target_num & 0xF;
Versatile byte buffer with small-buffer optimisation, ownership semantics and compression.
static uint8_t * bytes_malloc(size_t size) noexcept
Allocates a raw byte buffer from the memory pool (or heap if pool is unavailable).
static void bytes_free(uint8_t *ptr, size_t size) noexcept
Frees a buffer previously allocated by bytes_malloc().
#define VUNLIKELY(...)
Shorthand alias for VLINK_UNLIKELY. Hints that the expression is unlikely true.
定义 macros.h:302
#define VLINK_EXPORT_AND_ALIGNED(align_num)
Marks a class or variable as both exported and aligned to the given byte boundary.
定义 macros.h:103
#define VLIKELY(...)
Shorthand alias for VLINK_LIKELY. Hints that the expression is likely true.
定义 macros.h:297
@ kUnknownType
Unsupported type – is_supported() returns false.
定义 serializer.h:124
Schema-aware zero-copy 3-D point cloud with typed per-point fields.