7 Set<T>::Set(Allocator* allocator) noexcept :
9 m_allocator(allocator),
17 Set<T>::~Set() noexcept
23 Set<T>::Set(
const Set<T>& rhs) noexcept :
25 m_allocator(rhs.m_allocator),
26 m_length(rhs.m_length),
27 m_capacity(rhs.m_length)
29 if (m_length == 0)
return;
30 m_data =
static_cast<Set::ptr_type
>(m_allocator->malloc(
sizeof(T) * m_capacity));
31 #if __cplusplus >= 201703L
32 if (std::is_trivially_copyable_v<T>)
34 std::memcpy(m_data, rhs.m_data,
sizeof(T) * m_length);
39 for (
size_t i = 0; i < m_length; ++i)
41 new (m_data + i) T(rhs.m_data[i]);
47 Set<T>& Set<T>::operator=(
const Set<T>& rhs) noexcept
49 if (
this == &rhs)
return *
this;
50 if (rhs.m_length == 0)
57 #if __cplusplus >= 201703L
58 if (std::is_trivially_copyable_v<T>)
60 std::memcpy(m_data, rhs.m_data,
sizeof(T) * m_length);
65 for (
size_t i = 0; i < m_length; ++i)
68 m_data[i] = rhs.m_data[i];
75 Set<T>::Set(Set<T>&& rhs) noexcept :
77 m_allocator(rhs.m_allocator),
78 m_length(rhs.m_length),
79 m_capacity(rhs.m_capacity)
87 Set<T>& Set<T>::operator=(Set<T>&& rhs) noexcept
91 m_allocator = rhs.m_allocator;
92 m_length = rhs.m_length;
93 m_capacity = rhs.m_capacity;
102 bool Set<T>::operator==(
const Set& rhs)
const noexcept
104 if (rhs.m_length != m_length)
return false;
105 for (
size_t i = 0; i < m_length; ++i)
107 if (m_data[i] != m_data[i])
return false;
113 void Set<T>::insert(
const T& element) noexcept
115 if (find(element) != end())
return;
116 if (m_capacity == m_length) grow();
117 new (m_data + m_length++) T(element);
130 return &m_data[m_length];
134 typename Set<T>::const_iterator Set<T>::cbegin() const noexcept
140 typename Set<T>::const_iterator Set<T>::cend() const noexcept
142 return &m_data[m_length];
146 typename Set<T>::reverse_iterator Set<T>::rbegin() noexcept
148 return reverse_iterator(&back());
152 typename Set<T>::reverse_iterator Set<T>::rend() noexcept
154 T* front_ptr = &front();
155 return reverse_iterator(--front_ptr);
159 typename Set<T>::const_reverse_iterator Set<T>::crbegin() const noexcept
161 return const_reverse_iterator(&back());
165 typename Set<T>::const_reverse_iterator Set<T>::crend() const noexcept
167 T* front_ptr =
const_cast<T*
>(&front());
168 return const_reverse_iterator(--front_ptr);
172 T& Set<T>::back() noexcept
174 return m_data[m_length - 1];
178 const T& Set<T>::back() const noexcept
180 return m_data[m_length - 1];
184 T& Set<T>::front() noexcept
190 const T& Set<T>::front() const noexcept
196 const T* Set<T>::data() const noexcept
202 void Set<T>::resize(
size_t new_length) noexcept
204 if (new_length == m_length)
return;
210 if (new_length > m_length)
213 for (
size_t i = m_length; i < new_length; ++i)
215 new (m_data + i) T();
217 m_length = new_length;
221 m_capacity = new_length;
222 ptr_type new_buffer =
static_cast<ptr_type
>(m_allocator->malloc(
sizeof(T) * new_length));
223 #if __cplusplus >= 201703L
224 if (std::is_trivially_copyable_v<T>)
226 std::memcpy(new_buffer, m_data,
sizeof(T) * new_length);
231 for (
size_t i = 0; i < m_length; ++i)
235 new (new_buffer + i) T(std::move(item));
239 m_allocator->free(m_data);
241 m_length = new_length;
246 void Set<T>::clear() noexcept
248 if (!std::is_trivially_destructible<T>::value)
250 for (
size_t i = 0; i < m_length; ++i)
258 m_allocator->free(m_data);
267 void Set<T>::reserve(
size_t new_capacity) noexcept
269 if (new_capacity <= m_capacity)
return;
270 m_capacity = new_capacity;
271 ptr_type new_buffer =
static_cast<ptr_type
>(m_allocator->malloc(
sizeof(T) * m_capacity));
272 #if __cplusplus >= 201703L
273 if (std::is_trivially_copyable_v<T>)
275 std::memcpy(new_buffer, m_data,
sizeof(T) * m_length);
280 for (
size_t i = 0; i < m_length; ++i)
283 new (new_buffer + i) T(std::move(item));
288 m_allocator->free(m_data);
293 size_t Set<T>::size() const noexcept
299 size_t Set<T>::length() const noexcept
305 size_t Set<T>::capacity() const noexcept
311 void Set<T>::grow() noexcept
313 m_capacity = m_capacity == 0 ? 1 : m_capacity << 1;
314 ptr_type new_buffer =
static_cast<ptr_type
>(m_allocator->malloc(
sizeof(T) * m_capacity));
315 #if __cplusplus >= 201703L
316 if (std::is_trivially_copyable_v<T>)
318 std::memcpy(new_buffer, m_data,
sizeof(T) * m_length);
323 for (
size_t i = 0; i < m_length; ++i)
326 new (new_buffer + i) T(std::move(item));
331 m_allocator->free(m_data);
337 void Set<T>::erase(
const T& element) noexcept
339 auto it = find(element);
340 if (it == end())
return;
341 size_t index(it - m_data);
342 if (index >= m_length)
return;
343 for (
size_t i = (index + 1); i < m_length; ++i)
344 m_data[i - 1] = std::move(m_data[i]);
346 m_data[m_length].~T();
352 void Set<T>::erase(iterator it) noexcept
354 size_t index(it - m_data);
355 if (index >= m_length)
return;
356 for (
size_t i = (index + 1); i < m_length; ++i)
357 m_data[i - 1] = std::move(m_data[i]);
359 m_data[m_length].~T();
363 void Set<T>::shrink_to_fit() noexcept
365 m_capacity = m_length;
366 ptr_type new_buffer =
static_cast<ptr_type
>(m_allocator->malloc(
sizeof(T) * m_capacity));
367 #if __cplusplus >= 201703L
368 if (std::is_trivially_copyable_v<T>)
370 std::memcpy(new_buffer, m_data,
sizeof(T) * m_length);
375 for (
size_t i = 0; i < m_capacity; ++i)
378 new (new_buffer + i) T(std::move(item));
383 m_allocator->free(m_data);
388 typename Set<T>::iterator Set<T>::find(
const T& element) noexcept
391 for (
auto it = begin(); it != end_it; ++it)
393 if (*it == element)
return it;
399 typename Set<T>::const_iterator Set<T>::find(
const T& element)
const noexcept
401 auto end_it = cend();
402 for (
auto it = cbegin(); it != end_it; ++it)
404 if (*it == element)
return it;
410 bool Set<T>::empty() const noexcept
412 return m_length == 0;