mana: improve offset_ptr_t and related code
This commit is contained in:
parent
ddb67325c4
commit
e33bbcb4f7
2 changed files with 59 additions and 34 deletions
|
@ -15,18 +15,31 @@ typedef enum
|
|||
mana_uint8,
|
||||
mana_sint8,
|
||||
mana_uint16,
|
||||
mana_sint16,
|
||||
mana_uint32,
|
||||
mana_sint32,
|
||||
mana_uint64,
|
||||
mana_sint64,
|
||||
mana_float,
|
||||
mana_double,
|
||||
} mana_data_type_t;
|
||||
|
||||
// Offset based pointer. Allows to memcpy() structures with these pointers
|
||||
// inside as long as the range covered by the pointers is also copied.
|
||||
//
|
||||
// Raw pointer value is '&ptr + offset'. nullptr is defined as offset=1.
|
||||
// => Cannot point to the first byte of the struct itself but that's fine.
|
||||
// Do not create temporaries of these. The offset will then be relative to the
|
||||
// temporary on the stack! Do not copy these unless you copy the full memory
|
||||
// range so that the offset_ptr_t in the new location stays valid.
|
||||
typedef struct
|
||||
{
|
||||
mana_data_type_t data_type;
|
||||
ptrdiff_t offset;
|
||||
} mana_offset_ptr_t;
|
||||
|
||||
// Typed offset pointer based array. Stores the array size in bytes instead of
|
||||
// elements to allow storing any type using mana_custom.
|
||||
typedef struct
|
||||
{
|
||||
mana_offset_ptr_t ptr;
|
||||
|
|
|
@ -16,8 +16,11 @@
|
|||
namespace mesytec::mnode::mana
|
||||
{
|
||||
|
||||
inline bool is_null(const mana_offset_ptr_t &ptr) { return ptr.offset == 1; }
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline void set(mana_offset_ptr_t &ptr, void *p)
|
||||
{
|
||||
assert(p != reinterpret_cast<u8 *>(&ptr) + 1);
|
||||
|
@ -33,31 +36,6 @@ inline void set(mana_offset_ptr_t &ptr, void *p)
|
|||
ptr.offset = 1;
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
inline bool is_null(const mana_offset_ptr_t &ptr) { return ptr.offset == 1; }
|
||||
|
||||
inline void *get(mana_offset_ptr_t &ptr)
|
||||
{
|
||||
return is_null(ptr) ? nullptr : reinterpret_cast<u8 *>(&ptr) + ptr.offset;
|
||||
}
|
||||
|
||||
template <typename T> T *get(mana_offset_ptr_t &ptr); // to catch unsupported types
|
||||
|
||||
template <typename T> T *get_(mana_offset_ptr_t &ptr, mana_data_type_t expected)
|
||||
{
|
||||
if (ptr.data_type != expected)
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<T *>(get(ptr));
|
||||
}
|
||||
|
||||
template <> u32 *get(mana_offset_ptr_t &ptr) { return get_<u32>(ptr, mana_uint32); }
|
||||
template <> u64 *get(mana_offset_ptr_t &ptr) { return get_<u64>(ptr, mana_uint64); }
|
||||
template <> s8 *get(mana_offset_ptr_t &ptr) { return get_<s8>(ptr, mana_sint8); }
|
||||
template <> char *get(mana_offset_ptr_t &ptr) { return get_<char>(ptr, mana_sint8); }
|
||||
template <> float *get(mana_offset_ptr_t &ptr) { return get_<float>(ptr, mana_float); }
|
||||
template <> double *get(mana_offset_ptr_t &ptr) { return get_<double>(ptr, mana_double); }
|
||||
|
||||
inline void set(mana_offset_ptr_t &ptr, mana_data_type_t data_type, void *p)
|
||||
{
|
||||
|
@ -65,13 +43,47 @@ inline void set(mana_offset_ptr_t &ptr, mana_data_type_t data_type, void *p)
|
|||
detail::set(ptr, p);
|
||||
}
|
||||
|
||||
inline void set(mana_offset_ptr_t &ptr, std::nullptr_t) { set(ptr, mana_uint32, nullptr); }
|
||||
inline void set(mana_offset_ptr_t &ptr, u32 *p) { set(ptr, mana_uint32, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, u64 *p) { set(ptr, mana_uint64, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, s8 *p) { set(ptr, mana_sint8, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, char *p) { set(ptr, mana_sint8, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, float *p) { set(ptr, mana_float, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, double *p) { set(ptr, mana_double, p); }
|
||||
inline void *get(mana_offset_ptr_t &ptr)
|
||||
{
|
||||
return is_null(ptr) ? nullptr : reinterpret_cast<u8 *>(&ptr) + ptr.offset;
|
||||
}
|
||||
|
||||
template <typename T> T *get(mana_offset_ptr_t &ptr, mana_data_type_t expected)
|
||||
{
|
||||
if (ptr.data_type != expected)
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<T *>(get(ptr));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T> T *get(mana_offset_ptr_t &ptr); // to catch unsupported types
|
||||
|
||||
template <> u32 *get(mana_offset_ptr_t &ptr) { return detail::get<u32>(ptr, mana_uint32); }
|
||||
template <> u64 *get(mana_offset_ptr_t &ptr) { return detail::get<u64>(ptr, mana_uint64); }
|
||||
template <> s8 *get(mana_offset_ptr_t &ptr) { return detail::get<s8>(ptr, mana_sint8); }
|
||||
template <> char *get(mana_offset_ptr_t &ptr) { return detail::get<char>(ptr, mana_sint8); }
|
||||
template <> float *get(mana_offset_ptr_t &ptr) { return detail::get<float>(ptr, mana_float); }
|
||||
template <> double *get(mana_offset_ptr_t &ptr) { return detail::get<double>(ptr, mana_double); }
|
||||
|
||||
// To make 'set(ptr, nullptr)' work.
|
||||
inline void set(mana_offset_ptr_t &ptr, std::nullptr_t)
|
||||
{
|
||||
detail::set(ptr, ptr.data_type, nullptr);
|
||||
}
|
||||
|
||||
inline void set(mana_offset_ptr_t &ptr, u8 *p) { detail::set(ptr, mana_uint8, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, s8 *p) { detail::set(ptr, mana_sint8, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, char *p) { detail::set(ptr, mana_sint8, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, u16 *p) { detail::set(ptr, mana_uint16, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, s16 *p) { detail::set(ptr, mana_sint16, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, u32 *p) { detail::set(ptr, mana_uint32, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, s32 *p) { detail::set(ptr, mana_sint32, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, u64 *p) { detail::set(ptr, mana_uint64, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, s64 *p) { detail::set(ptr, mana_sint64, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, float *p) { detail::set(ptr, mana_float, p); }
|
||||
inline void set(mana_offset_ptr_t &ptr, double *p) { detail::set(ptr, mana_double, p); }
|
||||
|
||||
template <typename T>
|
||||
T *push_offset_array(mana::Arena &arena, mana_offset_array_t &dest, size_t size)
|
||||
|
@ -86,7 +98,7 @@ template <typename T>
|
|||
T *push_typed_offset_array(mana::Arena &arena, mana_offset_array_t &dest, size_t size)
|
||||
{
|
||||
T *ptr = arena.push_t<T>(size);
|
||||
mana::set(dest.ptr, ptr);
|
||||
set(dest.ptr, ptr);
|
||||
dest.size_bytes = size * sizeof(T);
|
||||
return ptr;
|
||||
}
|
||||
|
@ -98,7 +110,7 @@ template <typename T> size_t element_count(mana_offset_array_t &array)
|
|||
|
||||
template <typename T> mvlc::util::span<T> get_span(mana_offset_array_t &array)
|
||||
{
|
||||
auto ptr = reinterpret_cast<T *>(get(array.ptr));
|
||||
auto ptr = get<T>(array.ptr);
|
||||
auto size = element_count<T>(array);
|
||||
return {ptr, size};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue