Program Listing for File values.hpp
↰ Return to documentation for file (/tmp/ws/src/data_tamer/data_tamer_cpp/include/data_tamer/values.hpp
)
#pragma once
#include <functional>
#include <cstring>
#include <typeindex>
#include "data_tamer/custom_types.hpp"
#include "data_tamer/contrib/SerializeMe.hpp"
namespace DataTamer
{
class ValuePtr
{
public:
ValuePtr() = default;
template <typename T>
ValuePtr(const T* pointer, CustomSerializer::Ptr type_info = {});
template <template <class, class> class Container, class T, class... TArgs>
ValuePtr(const Container<T, TArgs...>* vect);
template <template <class, class> class Container, class T, class... TArgs>
ValuePtr(const Container<T, TArgs...>* vect, CustomSerializer::Ptr type_info);
template <typename T, size_t N>
ValuePtr(const std::array<T, N>* vect);
template <typename T, size_t N>
ValuePtr(const std::array<T, N>* vect, CustomSerializer::Ptr type_info);
ValuePtr(ValuePtr const& other) = delete;
ValuePtr& operator=(ValuePtr const& other) = delete;
ValuePtr(ValuePtr&& other) = default;
ValuePtr& operator=(ValuePtr&& other) = default;
[[nodiscard]] bool operator==(const ValuePtr& other) const;
[[nodiscard]] bool operator!=(const ValuePtr& other) const { return !(*this == other); }
void serialize(SerializeMe::SpanBytes& dest) const;
[[nodiscard]] size_t getSerializedSize() const;
[[nodiscard]] BasicType type() const { return type_; }
[[nodiscard]] bool isVector() const { return is_vector_; }
[[nodiscard]] uint16_t vectorSize() const { return array_size_; }
private:
const void* v_ptr_ = nullptr;
BasicType type_ = BasicType::OTHER;
std::type_index type_index_ = typeid(void);
std::uint8_t memory_size_ = 0;
std::function<void(SerializeMe::SpanBytes&)> serialize_impl_;
std::function<size_t()> get_size_impl_;
bool is_vector_ = false;
uint16_t array_size_ = 0;
};
//------------------------------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
template <typename T>
inline ValuePtr::ValuePtr(const T* pointer, CustomSerializer::Ptr type_info) :
v_ptr_(pointer)
, type_(GetBasicType<T>())
, type_index_(typeid(T))
, memory_size_(sizeof(T))
, is_vector_(false)
{
if (type_info)
{
serialize_impl_ = [type_info, pointer](SerializeMe::SpanBytes& buffer) -> void {
type_info->serialize(pointer, buffer);
};
get_size_impl_ = [type_info, pointer]() -> size_t {
return type_info->serializedSize(pointer);
};
}
}
template <template <class, class> class Container, class T, class... TArgs>
inline ValuePtr::ValuePtr(const Container<T, TArgs...>* vect) :
v_ptr_(vect)
, type_(GetBasicType<T>())
, type_index_(typeid(Container<T, TArgs...>))
, memory_size_(sizeof(T))
, is_vector_(true)
{
serialize_impl_ = [vect](SerializeMe::SpanBytes& buffer) -> void {
SerializeMe::SerializeIntoBuffer(buffer, *vect);
};
get_size_impl_ = [vect]() -> size_t { return SerializeMe::BufferSize(*vect); };
}
template <template <class, class> class Container, class T, class... TArgs>
inline ValuePtr::ValuePtr(const Container<T, TArgs...>* vect,
CustomSerializer::Ptr type_info) :
v_ptr_(vect)
, type_(GetBasicType<T>())
, type_index_(typeid(Container<T, TArgs...>))
, memory_size_(sizeof(T))
, is_vector_(true)
{
serialize_impl_ = [type_info, vect](SerializeMe::SpanBytes& buffer) -> void {
SerializeMe::SerializeIntoBuffer(buffer, uint32_t(vect->size()));
for (const auto& value : (*vect))
{
type_info->serialize(&value, buffer);
}
};
get_size_impl_ = [type_info, vect]() -> size_t {
if (vect->empty())
{
return sizeof(uint32_t);
}
if (type_info->isFixedSize())
{
return sizeof(uint32_t) + vect->size() * type_info->serializedSize(&vect->front());
}
size_t tot_size = sizeof(uint32_t);
for (const auto& value : (*vect))
{
tot_size += type_info->serializedSize(&value);
}
return tot_size;
};
}
template <typename T, size_t N>
inline ValuePtr::ValuePtr(const std::array<T, N>* array) :
v_ptr_(array)
, type_(GetBasicType<T>())
, type_index_(typeid(std::array<T, N>))
, is_vector_(true)
, array_size_(N)
{
serialize_impl_ = [array](SerializeMe::SpanBytes& buffer) -> void {
SerializeMe::SerializeIntoBuffer(buffer, *array);
};
get_size_impl_ = [array]() { return SerializeMe::BufferSize(*array); };
}
template <typename T, size_t N>
inline ValuePtr::ValuePtr(const std::array<T, N>* array,
CustomSerializer::Ptr type_info) :
v_ptr_(array)
, type_(GetBasicType<T>())
, type_index_(typeid(std::array<T, N>))
, is_vector_(true)
, array_size_(N)
{
serialize_impl_ = [type_info, array](SerializeMe::SpanBytes& buffer) -> void {
for (const auto& value : (*array))
{
type_info->serialize(&value, buffer);
}
};
get_size_impl_ = [type_info, array]() {
size_t tot_size = 0;
if (type_info->isFixedSize())
{
return N * type_info->serializedSize(&array->front());
}
for (const auto& value : (*array))
{
tot_size += type_info->serializedSize(&value);
}
return tot_size;
};
}
inline bool ValuePtr::operator==(const ValuePtr& other) const
{
return type_ == other.type_ &&
type_index_ == other.type_index_ &&
is_vector_ == other.is_vector_ &&
array_size_ == other.array_size_;
}
inline void ValuePtr::serialize(SerializeMe::SpanBytes& dest) const
{
if (serialize_impl_)
{
serialize_impl_(dest);
return;
}
std::memcpy(dest.data(), v_ptr_, memory_size_);
dest.trimFront(memory_size_);
}
inline size_t ValuePtr::getSerializedSize() const
{
return (get_size_impl_) ? get_size_impl_() : memory_size_;
}
} // namespace DataTamer