flatten 20260225
This commit is contained in:
333
tjp/core/containers/InPlaceArray.inl
Executable file
333
tjp/core/containers/InPlaceArray.inl
Executable file
@@ -0,0 +1,333 @@
|
||||
// License: Modified MIT (NON-AI)
|
||||
// See the LICENSE file in the root directory for license information.
|
||||
// Copyright 2025 Timothy Prepscius
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../assert/debug_assert.h"
|
||||
#include "../assert/handle_assert.hpp"
|
||||
#include "../algorithm/mem_copy.hpp"
|
||||
|
||||
#include "../exception/OutOfBounds.hpp"
|
||||
|
||||
#include <cstring> // for memcpy
|
||||
|
||||
namespace tjp {
|
||||
namespace core {
|
||||
|
||||
template<typename T, size_t N>
|
||||
InPlaceArray<T, N>::InPlaceArray (size_t size, T t)
|
||||
{
|
||||
resize(size, t);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
InPlaceArray<T, N>::InPlaceArray ()
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
//template<size_t N2>
|
||||
InPlaceArray<T, N>::InPlaceArray(const InPlaceArray<T, N> &rhs)
|
||||
{
|
||||
append(rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
//template<size_t N2>
|
||||
InPlaceArray<T, N>::InPlaceArray(const T *begin, const T *end)
|
||||
{
|
||||
append(begin, end);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
//template<size_t N2>
|
||||
InPlaceArray<T, N>::InPlaceArray(const T *data, size_t size)
|
||||
{
|
||||
append(data, data + size);
|
||||
}
|
||||
|
||||
|
||||
//template<typename T, size_t N>
|
||||
//InPlaceArray<T, N>::InPlaceArray(InPlaceArray<T, N> &&rhs)
|
||||
//{
|
||||
// append(rhs.begin(), rhs.end());
|
||||
//}
|
||||
|
||||
template<typename T, size_t N>
|
||||
//template<size_t N2>
|
||||
InPlaceArray<T,N> &InPlaceArray<T, N>::operator =(const InPlaceArray<T, N> &rhs)
|
||||
{
|
||||
if (this == &rhs)
|
||||
return *this;
|
||||
|
||||
clear();
|
||||
append(rhs.begin(), rhs.end());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
//template<size_t N2>
|
||||
InPlaceArray<T,N> &InPlaceArray<T, N>::operator =(const Array &rhs)
|
||||
{
|
||||
if (&v.array != &rhs)
|
||||
v.array = rhs;
|
||||
|
||||
length = N;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
InPlaceArray<T, N>::InPlaceArray(const std::initializer_list<T> &rhs)
|
||||
{
|
||||
for (auto &element: rhs)
|
||||
push_back(element);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::append_block(const T *begin_, const T *end_)
|
||||
{
|
||||
auto size = (end_ - begin_);
|
||||
|
||||
handle_assert(length + size <= N) {
|
||||
throw exceptions::OutOfBounds();
|
||||
}
|
||||
|
||||
mem_copy((char *)end(), (char *)begin_, size * sizeof(T));
|
||||
length += size;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::append_items(const T *begin_, const T *end_)
|
||||
{
|
||||
for (auto i = begin_; i!=end_; ++i)
|
||||
push_back(*i);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::emplace_items(T *begin_, T *end_)
|
||||
{
|
||||
for (auto i = begin_; i!=end_; ++i)
|
||||
emplace_back(std::move(*i));
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::append(const T *begin, const T *end)
|
||||
{
|
||||
if constexpr (std::is_trivially_copyable<T>::value)
|
||||
return append_block(begin, end);
|
||||
else
|
||||
return append_items(begin, end);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::emplace(T *begin, T *end)
|
||||
{
|
||||
if constexpr (std::is_trivially_copyable<T>::value)
|
||||
return append_block(begin, end);
|
||||
else
|
||||
return emplace_items(begin, end);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
InPlaceArray<T, N>::~InPlaceArray ()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::shorten_items(size_t length_)
|
||||
{
|
||||
while (length > length_)
|
||||
pop_back();
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::shorten_block(size_t length_)
|
||||
{
|
||||
if (length > length_)
|
||||
length = (Size)length_;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::shorten(size_t length_)
|
||||
{
|
||||
if constexpr (std::is_trivially_destructible<T>::value)
|
||||
return shorten_block(length_);
|
||||
else
|
||||
return shorten_items(length_);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::resize(size_t length_, T t)
|
||||
{
|
||||
shorten(length_);
|
||||
|
||||
handle_assert(length_ <= N) {
|
||||
throw exceptions::OutOfBounds();
|
||||
}
|
||||
|
||||
if constexpr (std::is_trivially_copyable<T>::value)
|
||||
{
|
||||
if (length < length_)
|
||||
{
|
||||
auto *data_ = data();
|
||||
auto *begin = data_ + length;
|
||||
auto *end = data_ + length_;
|
||||
|
||||
std::fill(begin, end, t);
|
||||
length = (Size)length_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (length < length_)
|
||||
push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::push_back (const T &element)
|
||||
{
|
||||
handle_assert(length < N) {
|
||||
throw exceptions::OutOfBounds();
|
||||
}
|
||||
|
||||
++length;
|
||||
|
||||
if constexpr (std::is_trivially_copyable<T>::value)
|
||||
{
|
||||
back() = element;
|
||||
}
|
||||
else
|
||||
{
|
||||
construct(&back(), element);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::push_back (T &&element)
|
||||
{
|
||||
handle_assert(length < N) {
|
||||
throw exceptions::OutOfBounds();
|
||||
}
|
||||
|
||||
++length;
|
||||
construct(&back(), std::move(element));
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::pop_back ()
|
||||
{
|
||||
debug_assert (length > 0);
|
||||
|
||||
// decrease length
|
||||
if (length > 0)
|
||||
{
|
||||
--length;
|
||||
destruct(&v.array[length]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
template<typename ... Args>
|
||||
T &InPlaceArray<T, N>::emplace_back (Args&& ...element)
|
||||
{
|
||||
handle_assert(length < N) {
|
||||
throw exceptions::OutOfBounds();
|
||||
}
|
||||
|
||||
++length;
|
||||
auto &t = back();
|
||||
construct(&t, std::forward<Args>(element)...);
|
||||
return t;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
const T &InPlaceArray<T, N>::at(size_t i) const
|
||||
{
|
||||
return v.array[i];
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
T &InPlaceArray<T, N>::at(size_t i)
|
||||
{
|
||||
return v.array[i];
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
const T &InPlaceArray<T, N>::operator[] (size_t i) const
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
T &InPlaceArray<T, N>::operator[] (size_t i)
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
size_t InPlaceArray<T, N>::size () const
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
void InPlaceArray<T, N>::clear ()
|
||||
{
|
||||
shorten(0);
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
bool InPlaceArray<T, N>::empty () const
|
||||
{
|
||||
return length == 0;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
bool operator <(const InPlaceArray<T, N> &lhs, const InPlaceArray<T, N> &rhs)
|
||||
{
|
||||
auto max = std::min(lhs.size(), rhs.size());
|
||||
|
||||
for (auto i=0; i<max; ++i)
|
||||
{
|
||||
auto &l = lhs.at(i);
|
||||
auto &r = rhs.at(i);
|
||||
|
||||
if (l != r)
|
||||
return l < r;
|
||||
}
|
||||
|
||||
return lhs.size() < rhs.size();
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
bool operator ==(const InPlaceArray<T, N> &lhs, const InPlaceArray<T, N> &rhs)
|
||||
{
|
||||
if (lhs.size() != rhs.size())
|
||||
return false;
|
||||
|
||||
for (auto i=0; i<lhs.size(); ++i)
|
||||
{
|
||||
auto &l = lhs.at(i);
|
||||
auto &r = rhs.at(i);
|
||||
|
||||
if (l != r)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, size_t N>
|
||||
bool operator !=(const InPlaceArray<T, N> &lhs, const InPlaceArray<T, N> &rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
} // namespace utilities
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user