IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
mem_data.hxx
Go to the documentation of this file.
1
3
4#pragma once
5#include <ice/mem_info.hxx>
7
8namespace ice
9{
10
11 template<typename T>
12 concept HasDataRepresentation = requires(T t) {
13 { t.operator ice::Data() } -> std::convertible_to<ice::Data>;
14 };
15
16 struct Data
17 {
18 void const* location;
21 };
22
23 template<typename Type>
24 inline auto data_view(Type const& var) noexcept
25 {
26 if constexpr (HasDataRepresentation<Type>)
27 {
28 return (ice::Data) var;
29 }
30 else
31 {
32 return Data{
33 .location = std::addressof(var),
34 .size = ice::size_of<Type>,
35 .alignment = ice::align_of<Type>
36 };
37 }
38 }
39
40 template<typename Type, ice::usize::base_type Size>
41 constexpr auto data_view(Type const(&var)[Size]) noexcept
42 {
43 return Data{
44 .location = std::addressof(var),
45 .size = ice::size_of<Type> *Size,
46 .alignment = ice::align_of<Type>
47 };
48 }
49
50 inline auto ptr_add(ice::Data mem, ice::usize offset) noexcept -> ice::Data
51 {
52 ICE_ASSERT_CORE(mem.size >= offset);
53 return Data{
54 .location = ice::ptr_add(mem.location, offset),
55 .size = {mem.size.value - offset.value},
56 .alignment = mem.alignment
57 };
58 }
59
60 namespace data
61 {
62
63 constexpr auto with_highest_alignment(ice::Data data) noexcept -> ice::Data
64 {
65 ice::u32 align_value = static_cast<std::underlying_type_t<ice::ualign>>(data.alignment);
66
67 // We check all bits on the next alignment. Ex.: (8 << 1) - 1 = 15 [0x00ff]
68 while ((std::bit_cast<ice::uptr>(data.location) & ((align_value << 1) - 1)) == 0)
69 {
70 // Increase alignment
71 align_value <<= 1;
72
73 // If alignment reaches 128 we stop here.
74 if (align_value == static_cast<std::underlying_type_t<ice::ualign>>(ice::ualign::b_256))
75 {
76 break;
77 }
78 }
79
80 data.alignment = static_cast<ice::ualign>(align_value);
81 return data;
82 }
83
84 template<typename T>
85 requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
86 inline auto read_raw(ice::Data source, T& out_value) noexcept -> ice::Data
87 {
89 out_value = *reinterpret_cast<T const*>(source.location);
91 source.size = ice::usize{ source.size.value - ice::size_of<T>.value };
93 return source;
94 }
95
96 template<typename T, ice::u64 Size>
97 requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
98 inline auto read_raw_array(ice::Data source, T(&out_array)[Size]) noexcept -> ice::Data
99 {
101 ice::memcpy(out_array, source.location, sizeof(T) * Size);
102 source.location = ice::ptr_add(source.location, ice::size_of<T> * Size);
103 source.size = ice::usize{ source.size.value - ice::size_of<T>.value * Size };
105 return source;
106 }
107
108 template<typename T>
109 requires (std::is_trivially_copyable_v<T>)
110 inline auto read_raw(ice::Data source, T*& out_value_ptr) noexcept -> ice::Data
111 {
113 out_value_ptr = reinterpret_cast<T const*>(source.location);
114 source.location = out_value_ptr + 1;
115 source.size = ice::usize{ source.size.value - ice::size_of<T>.value };
117 return source;
118 }
119
120 template<typename T, typename OffsetType = ice::usize::base_type>
121 requires (std::is_trivially_copyable_v<T> && !std::is_pointer_v<T>)
122 inline auto read_offset(ice::Data source, T& out_value) noexcept -> ice::Data
123 {
125 OffsetType offset;
126 read_raw(source, offset);
127 source.location = ice::ptr_add(source.location, { offset });
128 source.size = ice::usize{ source.size.value - offset };
129 source = with_highest_alignment(source);
130
132 out_value = *reinterpret_cast<T const*>(source.location);
133 source.location = &out_value + 1;
134 source.size = ice::usize{ source.size.value - ice::size_of<T>.value };
136 return source;
137 }
138
139 template<typename T, typename OffsetType = ice::usize::base_type>
140 requires (std::is_trivially_copyable_v<T>)
141 inline auto read_offset(ice::Data source, T*& out_value_ptr) noexcept -> ice::Data
142 {
144 OffsetType offset;
145 read_raw(source, offset);
146 source.location = ice::ptr_add(source.location, { offset });
147 source.size = ice::usize{ source.size.value - offset };
148 source = with_highest_alignment(source);
149
151 out_value_ptr = reinterpret_cast<T const*>(source.location);
152 source.location = out_value_ptr + 1;
153 source.size = ice::usize{ source.size.value - ice::size_of<T>.value };
155 return source;
156 }
157
158 } // namespace data
159
160} // namespace ice
#define ICE_ASSERT_CORE(expression)
Definition assert_core.hxx:43
Definition mem_data.hxx:12
Definition span.hxx:129
auto read_raw(ice::Data source, T &out_value) noexcept -> ice::Data
Definition mem_data.hxx:86
constexpr auto with_highest_alignment(ice::Data data) noexcept -> ice::Data
Definition mem_data.hxx:63
auto read_raw_array(ice::Data source, T(&out_array)[Size]) noexcept -> ice::Data
Definition mem_data.hxx:98
auto read_offset(ice::Data source, T &out_value) noexcept -> ice::Data
Definition mem_data.hxx:122
SPDX-License-Identifier: MIT.
Definition array.hxx:12
constexpr ice::usize size_of
Definition mem_info.hxx:12
auto data_view(ice::Array< Type, Logic > const &arr) noexcept -> ice::Data=delete
constexpr ice::ualign align_of
Definition mem_info.hxx:15
auto ptr_add(void *pointer, ice::usize offset) noexcept -> void *
Definition mem_arithmetic.hxx:34
std::uint32_t u32
Definition types.hxx:26
ualign
Definition mem_size_types.hxx:39
@ b_256
Definition mem_size_types.hxx:50
auto memcpy(void *dest, void const *source, ice::usize size) noexcept -> void *
Definition mem_data.hxx:17
ice::ualign alignment
Definition mem_data.hxx:20
void const * location
Definition mem_data.hxx:18
ice::usize size
Definition mem_data.hxx:19
Represents a unsigned size value on the given platform.
Definition mem_size_types.hxx:26
base_type value
Definition mem_size_types.hxx:35