Files
core_zero/tjp/core/containers/InPlaceArray.inl
Timothy Prepscius 996151a56a flatten 20260225
2026-02-25 12:43:06 -05:00

334 lines
6.1 KiB
C++
Executable File

// 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