IceShard 1
A personal game engine project, with development focused on 2D/2.5D games.
Loading...
Searching...
No Matches
heap_string.hxx
Go to the documentation of this file.
1
3
4#pragma once
5#include <ice/string.hxx>
9
10namespace ice
11{
12
13 template<typename CharT = char> requires ice::concepts::SupportedCharType<CharT>
15 {
16 using CharType = CharT;
19 using ReverseIterator = std::reverse_iterator<CharType*>;
20 using ConstIterator = CharType const*;
21 using ConstReverseIterator = std::reverse_iterator<CharType const*>;
24
29
30 inline explicit HeapString(ice::Allocator& allocator) noexcept;
31 inline HeapString(ice::Allocator& allocator, ice::BasicString<CharType> string) noexcept;
32 inline ~HeapString() noexcept;
33
34 inline HeapString(HeapString&& other) noexcept;
35 inline HeapString(HeapString const& other) noexcept;
36
37 inline auto operator=(HeapString&& other) noexcept -> HeapString&;
38 inline auto operator=(HeapString const& other) noexcept -> HeapString&;
39 inline auto operator=(ice::BasicString<CharType> str) noexcept -> HeapString&;
40
41 inline operator ice::BasicString<CharType>() const noexcept;
42
43 template<typename Self>
44 inline auto data(this Self& self) noexcept -> ValueType* { return self._data; }
45
46 inline auto size() const noexcept -> SizeType { return SizeType{ _size, sizeof(CharType) }; }
47 inline void resize(ice::ncount new_size) noexcept;
48
49 inline auto capacity() const noexcept -> SizeType { return SizeType{ _capacity, sizeof(CharType) }; }
50 inline void set_capacity(ice::ncount new_capacity) noexcept;
51
52 inline auto data_view() const noexcept -> ice::Data;
53 inline auto extract_memory() noexcept -> ice::Memory;
54 };
55
56 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
57 inline HeapString<CharT>::HeapString(ice::Allocator& allocator) noexcept
58 : _allocator{ &allocator }
59 , _capacity{ 0 }
60 , _size{ 0 }
61 , _data{ nullptr }
62 {
63 }
64
65 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
67 : _allocator{ &allocator }
68 , _capacity{ 0 }
69 , _size{ 0 }
70 , _data{ nullptr }
71 {
72 *this = value;
73 }
74
75 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
77 : _allocator{ other._allocator }
78 , _size{ ice::exchange(other._size, 0) }
79 , _capacity{ ice::exchange(other._capacity, 0) }
80 , _data{ ice::exchange(other._data, nullptr) }
81 {
82 }
83
84 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
86 : _allocator{ other._allocator }
87 , _capacity{ 0 }
88 , _size{ 0 }
89 , _data{ nullptr }
90 {
91 if (other._size > 0)
92 {
93 set_capacity(other.size() + 1);
94
95 // TODO: We need actually very, VERY good tests for string manipulations...
97 this->end(),
98 other.cbegin(),
99 other.size().bytes()
100 );
101
102 _size = other._size;
103 _data[_size] = CharType{ 0 };
104 }
105 }
106
107 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
109 {
110 _allocator->deallocate(this->memory_view());
111 }
112
113 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
115 {
116 if (this != ice::addressof(other))
117 {
118 set_capacity(0);
119
120 _allocator = other._allocator;
121 _size = ice::exchange(other._size, 0);
122 _capacity = ice::exchange(other._capacity, 0);
123 _data = ice::exchange(other._data, nullptr);
124 }
125 return *this;
126 }
127
128 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
129 inline auto HeapString<CharT>::operator=(HeapString<CharT> const& other) noexcept -> HeapString<CharT>&
130 {
131 if (this != ice::addressof(other))
132 {
133 this->clear();
134 this->reserve(other.capacity());
135
136 if (other._size > 0)
137 {
139 this->memory_view(),
140 other.data_view()
141 );
142 }
143
144 _size = other._size;
145 _data[_size] = CharType{ };
146 }
147 return *this;
148 }
149
150 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
151 inline auto HeapString<CharT>::operator=(ice::BasicString<CharT> str) noexcept -> HeapString<CharT>&
152 {
153 auto const* const other_str_begin = str.begin();
154 bool const part_of_this = other_str_begin >= this->begin()
155 && other_str_begin < this->end();
156 ICE_ASSERT_CORE(part_of_this == false);
157
158 if (!part_of_this)
159 {
160 set_capacity(str.size() + 1);
162 this->memory_view(),
163 str.data_view()
164 );
165
166 _size = str.size().u32();
167 _data[_size] = ValueType{ 0 };
168 }
169 return *this;
170 }
171
172 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
173 inline HeapString<CharT>::operator ice::BasicString<typename HeapString<CharT>::CharType>() const noexcept
174 {
175 return ice::BasicString<CharT>{ _data, _size };
176 }
177
178 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
179 inline void HeapString<CharT>::resize(ice::ncount new_size) noexcept
180 {
181 if (new_size > 0 && new_size >= capacity())
182 {
183 set_capacity(new_size + 1);
184 }
185
186 _size = new_size.u32();
187 if (_data != nullptr)
188 {
189 _data[_size] = CharType{ 0 };
190 }
191 }
192
193 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
194 inline void HeapString<CharT>::set_capacity(ice::ncount new_capacity) noexcept
195 {
196 ice::u32 const new_capacity_u32 = new_capacity.u32();
197 if (new_capacity_u32 == _capacity)
198 {
199 return;
200 }
201
202 ValueType* new_data = nullptr;
203 if (new_capacity_u32 > 0)
204 {
205 ice::AllocResult new_buffer = _allocator->allocate(ice::meminfo_of<ValueType> * new_capacity);
206
207 if (_size > 0)
208 {
209 ice::memcpy(new_buffer, this->data_view());
210 }
211
212 new_data = reinterpret_cast<ValueType*>(new_buffer.memory);
213 }
214
215 _allocator->deallocate(this->memory_view());
216 _capacity = new_capacity_u32;
217 _data = new_data;
218
219 if (new_capacity_u32 <= _size)
220 {
221 _size = ice::min(new_capacity_u32, new_capacity_u32 - 1);
222 }
223
224 if (_data != nullptr)
225 {
226 _data[_size] = 0;
227 }
228 }
229
230 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
231 inline auto HeapString<CharT>::data_view() const noexcept -> ice::Data
232 {
233 return Data{
234 .location = _data,
235 .size = size().bytes(),
236 .alignment = ice::align_of<CharType>
237 };
238 }
239
240 template<typename CharT> requires ice::concepts::SupportedCharType<CharT>
242 {
243 _size = 0; // clear the size too
244 return {
245 ice::exchange(_data, nullptr),
246 ice::exchange(_capacity, 0),
248 };
249 }
250
251 constexpr auto hash(ice::HeapString<> const& value) noexcept -> ice::u64
252 {
253 return ice::hash(ice::String{ value });
254 }
255
256} // namespace ice
257
258template<typename CharType>
259struct fmt::formatter<ice::HeapString<CharType>> : public fmt::formatter<ice::BasicString<CharType>>
260{
261 template<typename FormatContext>
262 constexpr auto format(ice::HeapString<CharType> const& value, FormatContext& ctx) const noexcept
263 {
264 return fmt::formatter<ice::BasicString<CharType>>::format({ value._data, value._size }, ctx);
265 }
266};
#define ICE_ASSERT_CORE(expression)
Definition assert_core.hxx:43
Definition string_concepts.hxx:12
Definition container_concepts.hxx:12
constexpr auto min(arr_t< Size, T > left, arr_t< Size, U > right) noexcept -> arr_t< Size, T >
Definition array_operations.hxx:60
SPDX-License-Identifier: MIT.
Definition array.hxx:12
ice::BasicString< char > String
Definition string.hxx:82
std::uint64_t u64
Definition types.hxx:27
constexpr ice::ualign align_of
Definition mem_info.hxx:15
std::uint32_t u32
Definition types.hxx:26
constexpr ice::meminfo meminfo_of
Definition mem_info.hxx:18
ice::AllocatorBase< ice::build::is_debug||ice::build::is_develop > Allocator
Definition mem_types.hxx:25
constexpr auto hash(ice::HeapString<> const &value) noexcept -> ice::u64
Definition heap_string.hxx:251
auto memcpy(void *dest, void const *source, ice::usize size) noexcept -> void *
constexpr auto format(ice::HeapString< CharType > const &value, FormatContext &ctx) const noexcept
Definition heap_string.hxx:262
Definition mem.hxx:44
void * memory
Definition mem.hxx:45
Definition string.hxx:15
Definition mem_data.hxx:17
Definition heap_string.hxx:15
auto size() const noexcept -> SizeType
Definition heap_string.hxx:46
auto data(this Self &self) noexcept -> ValueType *
Definition heap_string.hxx:44
void set_capacity(ice::ncount new_capacity) noexcept
Definition heap_string.hxx:194
ValueType * _data
Definition heap_string.hxx:28
auto extract_memory() noexcept -> ice::Memory
Definition heap_string.hxx:241
auto capacity() const noexcept -> SizeType
Definition heap_string.hxx:49
ice::ncount SizeType
Definition heap_string.hxx:22
auto operator=(HeapString &&other) noexcept -> HeapString &
CharType ValueType
Definition heap_string.hxx:17
~HeapString() noexcept
Definition heap_string.hxx:108
auto data_view() const noexcept -> ice::Data
Definition heap_string.hxx:231
void resize(ice::ncount new_size) noexcept
Definition heap_string.hxx:179
ice::u32 _size
Definition heap_string.hxx:27
ice::u32 _capacity
Definition heap_string.hxx:26
CharType * Iterator
Definition heap_string.hxx:18
std::reverse_iterator< CharType const * > ConstReverseIterator
Definition heap_string.hxx:21
CharType const * ConstIterator
Definition heap_string.hxx:20
ice::BasicString< CharType > StringType
Definition heap_string.hxx:23
CharT CharType
Definition heap_string.hxx:16
ice::Allocator * _allocator
Definition heap_string.hxx:25
HeapString(ice::Allocator &allocator) noexcept
Definition heap_string.hxx:57
std::reverse_iterator< CharType * > ReverseIterator
Definition heap_string.hxx:19
Definition mem_memory.hxx:13
Definition ncount.hxx:14
constexpr auto memory_view(this Self &self) noexcept -> ice::Memory
Definition editable_operations.hxx:168
void clear(this Self &self) noexcept
Definition editable_operations.hxx:16
constexpr auto begin(this Self &self) noexcept -> typename Self::Iterator
Definition editable_operations.hxx:132
constexpr auto end(this Self &self) noexcept -> typename Self::Iterator
Definition editable_operations.hxx:138
Definition resizable_operations.hxx:13
void reserve(this Self &self, ice::ncount min_capacity) noexcept
Definition resizable_operations.hxx:23