summaryrefslogtreecommitdiff
path: root/include/fud_fixed_vector.hpp
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2024-10-25 01:09:10 -0500
committerDominick Allen <djallen@librehumanitas.org>2024-10-25 01:09:10 -0500
commit11968f674a7de34fb7de744598a8086330cd88a3 (patch)
treebe5b885ef47c8ceab50f558c8aef6632fefc94d1 /include/fud_fixed_vector.hpp
parent512d026de016f2720060d264adec02e56123851d (diff)
Get working string formatting for unsigned numbers.
Diffstat (limited to 'include/fud_fixed_vector.hpp')
-rw-r--r--include/fud_fixed_vector.hpp276
1 files changed, 276 insertions, 0 deletions
diff --git a/include/fud_fixed_vector.hpp b/include/fud_fixed_vector.hpp
new file mode 100644
index 0000000..d0c0f0e
--- /dev/null
+++ b/include/fud_fixed_vector.hpp
@@ -0,0 +1,276 @@
+/*
+ * libfud
+ * Copyright 2024 Dominick Allen
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef FUD_FIXED_VECTOR_HPP
+#define FUD_FIXED_VECTOR_HPP
+
+#include "fud_assert.hpp"
+#include "fud_config.hpp"
+#include "fud_option.hpp"
+#include "fud_span.hpp"
+
+#include <cstddef>
+
+namespace fud {
+
+template <typename T, size_t Size>
+class FixedVector {
+ static_assert(Size > 0);
+ using ValueType = T;
+
+ private:
+ T m_data[Size]; // NOLINT(cppcoreguidelines-avoid-c-arrays)
+ size_t m_length;
+
+ public:
+ [[nodiscard]] constexpr size_t size() const
+ {
+ return Size;
+ }
+
+ constexpr T* data() noexcept
+ {
+ return m_data;
+ }
+
+ constexpr const T* data() const noexcept
+ {
+ return m_data;
+ }
+
+ constexpr T* begin() noexcept
+ {
+ return m_data;
+ }
+
+ constexpr const T* begin() const noexcept
+ {
+ return m_data;
+ }
+
+ constexpr T* end() noexcept
+ {
+ return m_data + Size;
+ }
+
+ constexpr const T* end() const noexcept
+ {
+ return m_data + Size;
+ }
+
+ constexpr T& operator[](size_t index)
+ {
+ if constexpr (fudBoundsChecking) {
+ fudAssert(m_data != nullptr);
+ fudAssert(index < m_length);
+ }
+ return m_data[index];
+ }
+
+ constexpr const T& operator[](size_t index) const
+ {
+ if constexpr (fudBoundsChecking) {
+ fudAssert(m_data != nullptr);
+ fudAssert(index < m_length);
+ }
+ return m_data[index];
+ }
+
+ constexpr bool operator==(const FixedVector<T, Size>&) const noexcept = default;
+
+ constexpr auto operator<=>(const FixedVector<T, Size>& other) const noexcept = default;
+
+ Span<T, Size> span()
+ {
+ return Span<T, Size>{data(), Size};
+ }
+
+ FudStatus resize(size_t count)
+ {
+ if (count == m_length) {
+ return FudStatus::Success;
+ }
+
+ if (count < m_length) {
+ m_length = count;
+ return FudStatus::Success;
+ }
+
+ for (size_t index = m_length; index < count; ++index) {
+ m_data = std::move(T());
+ }
+
+ m_length = count;
+ return FudStatus::Success;
+ }
+
+ FudStatus clear()
+ {
+ m_length = 0;
+ return FudStatus::Success;
+ }
+
+ constexpr Option<T&> front()
+ {
+ if (m_length > 0) {
+ return m_data[0];
+ }
+ return NullOpt;
+ }
+
+ constexpr Option<const T&> front() const
+ {
+ if (m_length > 0) {
+ return m_data[0];
+ }
+ return NullOpt;
+ }
+
+ constexpr Option<T&> back()
+ {
+ if (m_length > 0) {
+ return m_data[m_length - 1];
+ }
+ return NullOpt;
+ }
+
+ constexpr Option<const T&> back() const
+ {
+ if (m_length > 0) {
+ return m_data[m_length - 1];
+ }
+ return NullOpt;
+ }
+
+ FudStatus pushBack(const T& value)
+ {
+ if (m_length == Size) {
+ return FudStatus::Full;
+ }
+
+ m_data[m_length] = value;
+ m_length++;
+ return FudStatus::Success;
+ }
+
+ FudStatus pushBack(T&& value)
+ {
+ if (m_length == Size) {
+ return FudStatus::Full;
+ }
+
+ m_data[m_length] = std::move(value);
+ m_length++;
+ return FudStatus::Success;
+ }
+
+ Result<T, FudStatus> popBack()
+ {
+ if (m_data == nullptr) {
+ return FudStatus::ObjectInvalid;
+ }
+ if (m_length == 0) {
+ return FudStatus::Empty;
+ }
+ auto result{std::move(m_data[m_length - 1])};
+ m_length--;
+ return result;
+ }
+
+ FudStatus eraseBack()
+ {
+ if (m_data == nullptr) {
+ return FudStatus::ObjectInvalid;
+ }
+ if (m_length == 0) {
+ return FudStatus::Empty;
+ }
+ m_length--;
+ return FudStatus::Success;
+ }
+
+ FudStatus insert(size_t index, const T& value)
+ {
+ if (index > m_length) {
+ return FudStatus::IndexInvalid;
+ }
+ if (index == m_length) {
+ return pushBack(value);
+ }
+ if (m_length == Size) {
+ return FudStatus::Full;
+ }
+
+ m_data[m_length] = std::move(m_data[m_length - 1]);
+
+ for (size_t backIndex = m_length - 1; backIndex > index; --backIndex) {
+ m_data[backIndex] = std::move(m_data[backIndex - 1]);
+ }
+ m_data[index] = value;
+ m_length++;
+ return FudStatus::Success;
+ }
+
+ FudStatus insert(size_t index, T&& value)
+ {
+ if (index > m_length) {
+ return FudStatus::IndexInvalid;
+ }
+ if (index == m_length) {
+ return pushBack(std::move(value));
+ }
+ if (m_length == Size) {
+ return FudStatus::Full;
+ }
+
+ m_data[m_length] = std::move(m_data[m_length - 1]);
+
+ for (size_t backIndex = m_length - 1; backIndex > index; --backIndex) {
+ m_data[backIndex] = std::move(m_data[backIndex - 1]);
+ }
+ m_data[index] = std::move(value);
+ m_length++;
+ return FudStatus::Success;
+ }
+
+ FudStatus erase(size_t index)
+ {
+ if (index >= m_length) {
+ return FudStatus::IndexInvalid;
+ }
+
+ for (size_t fwdIndex = index; fwdIndex + 1 < m_length; fwdIndex++) {
+ m_data[fwdIndex] = std::move(m_data[fwdIndex + 1]);
+ }
+
+ m_length--;
+ return FudStatus::Success;
+ }
+
+ private:
+ FudStatus cleanup() noexcept
+ {
+ auto status = clear();
+
+ m_length = 0;
+ return status;
+ }
+};
+
+} // namespace fud
+
+#endif