// 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 // for memcpy namespace tjp { namespace core { template InPlaceArray::InPlaceArray (size_t size, T t) { resize(size, t); } template InPlaceArray::InPlaceArray () { } template //template InPlaceArray::InPlaceArray(const InPlaceArray &rhs) { append(rhs.begin(), rhs.end()); } template //template InPlaceArray::InPlaceArray(const T *begin, const T *end) { append(begin, end); } template //template InPlaceArray::InPlaceArray(const T *data, size_t size) { append(data, data + size); } //template //InPlaceArray::InPlaceArray(InPlaceArray &&rhs) //{ // append(rhs.begin(), rhs.end()); //} template //template InPlaceArray &InPlaceArray::operator =(const InPlaceArray &rhs) { if (this == &rhs) return *this; clear(); append(rhs.begin(), rhs.end()); return *this; } template //template InPlaceArray &InPlaceArray::operator =(const Array &rhs) { if (&v.array != &rhs) v.array = rhs; length = N; return *this; } template InPlaceArray::InPlaceArray(const std::initializer_list &rhs) { for (auto &element: rhs) push_back(element); } template void InPlaceArray::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 void InPlaceArray::append_items(const T *begin_, const T *end_) { for (auto i = begin_; i!=end_; ++i) push_back(*i); } template void InPlaceArray::emplace_items(T *begin_, T *end_) { for (auto i = begin_; i!=end_; ++i) emplace_back(std::move(*i)); } template void InPlaceArray::append(const T *begin, const T *end) { if constexpr (std::is_trivially_copyable::value) return append_block(begin, end); else return append_items(begin, end); } template void InPlaceArray::emplace(T *begin, T *end) { if constexpr (std::is_trivially_copyable::value) return append_block(begin, end); else return emplace_items(begin, end); } template InPlaceArray::~InPlaceArray () { clear(); } template void InPlaceArray::shorten_items(size_t length_) { while (length > length_) pop_back(); } template void InPlaceArray::shorten_block(size_t length_) { if (length > length_) length = (Size)length_; } template void InPlaceArray::shorten(size_t length_) { if constexpr (std::is_trivially_destructible::value) return shorten_block(length_); else return shorten_items(length_); } template void InPlaceArray::resize(size_t length_, T t) { shorten(length_); handle_assert(length_ <= N) { throw exceptions::OutOfBounds(); } if constexpr (std::is_trivially_copyable::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 void InPlaceArray::push_back (const T &element) { handle_assert(length < N) { throw exceptions::OutOfBounds(); } ++length; if constexpr (std::is_trivially_copyable::value) { back() = element; } else { construct(&back(), element); } } template void InPlaceArray::push_back (T &&element) { handle_assert(length < N) { throw exceptions::OutOfBounds(); } ++length; construct(&back(), std::move(element)); } template void InPlaceArray::pop_back () { debug_assert (length > 0); // decrease length if (length > 0) { --length; destruct(&v.array[length]); } } template template T &InPlaceArray::emplace_back (Args&& ...element) { handle_assert(length < N) { throw exceptions::OutOfBounds(); } ++length; auto &t = back(); construct(&t, std::forward(element)...); return t; } template const T &InPlaceArray::at(size_t i) const { return v.array[i]; } template T &InPlaceArray::at(size_t i) { return v.array[i]; } template const T &InPlaceArray::operator[] (size_t i) const { return at(i); } template T &InPlaceArray::operator[] (size_t i) { return at(i); } template size_t InPlaceArray::size () const { return length; } template void InPlaceArray::clear () { shorten(0); } template bool InPlaceArray::empty () const { return length == 0; } template bool operator <(const InPlaceArray &lhs, const InPlaceArray &rhs) { auto max = std::min(lhs.size(), rhs.size()); for (auto i=0; i bool operator ==(const InPlaceArray &lhs, const InPlaceArray &rhs) { if (lhs.size() != rhs.size()) return false; for (auto i=0; i bool operator !=(const InPlaceArray &lhs, const InPlaceArray &rhs) { return !(lhs == rhs); } } // namespace utilities } // namespace