Skip to content

Improve Container Types #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
584 changes: 584 additions & 0 deletions include/RED4ext/Containers/DynArray.hpp

Large diffs are not rendered by default.

213 changes: 213 additions & 0 deletions include/RED4ext/Containers/Span.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
#pragma once

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <stdexcept>

#include <RED4ext/Common.hpp>
#include <RED4ext/Detail/Containers/ArrayIterator.hpp>

namespace RED4ext
{
template<typename T>
struct Span
{
using ValueType = T;
using Reference = ValueType&;
using ConstReference = const Reference;
using Pointer = ValueType*;
using ConstPointer = const Pointer;

using SizeType = std::uint32_t;
using DifferenceType = std::ptrdiff_t;

using Iterator = Detail::ArrayIterator<ValueType, Span>;
using ConstIterator = Detail::ArrayIterator<const ValueType, Span>;
using ReverseIterator = std::reverse_iterator<Iterator>;
using ConstReverseIterator = std::reverse_iterator<ConstIterator>;

Span()
: beginPtr(nullptr)
, endPtr(nullptr)
{
}

Span(Pointer aBegin, Pointer aEnd)
: beginPtr(aBegin)
, endPtr(aEnd)
{
}

Span(Pointer aBegin, SizeType aCount)
: beginPtr(aBegin)
, endPtr(aBegin + aCount)
{
}

constexpr Reference operator[](SizeType aIndex)
{
assert(aIndex < Size());
return Data()[aIndex];
}

constexpr ConstReference operator[](SizeType aIndex) const
{
assert(aIndex < Size());
return Data()[aIndex];
}

[[nodiscard]] constexpr Reference At(SizeType aIndex)
{
if (aIndex >= Size())
throw std::out_of_range("Span::At: Position out of range");

return Data()[aIndex];
}

[[nodiscard]] constexpr ConstReference At(SizeType aIndex) const
{
if (aIndex >= Size())
throw std::out_of_range("Span::At: Position out of range");

return Data()[aIndex];
}

[[nodiscard]] constexpr Iterator Find(ConstReference aValue) noexcept
{
return Iterator(std::find(Begin(), End(), aValue));
}

[[nodiscard]] constexpr ConstIterator Find(ConstReference aValue) const noexcept
{
return ConstIterator(std::find(Begin(), End(), aValue));
}

[[nodiscard]] constexpr bool Contains(ConstReference aValue) const noexcept
{
return Find(aValue) != End();
}

[[nodiscard]] bool Contains(ConstIterator aPos) const noexcept
{
return Begin() <= aPos && aPos <= End();
}

[[nodiscard]] bool Contains(ConstIterator aFirst, ConstIterator aLast) const noexcept
{
return Begin() <= (std::min)(aFirst, aLast) && (std::max)(aLast, aFirst) <= End();
}

[[nodiscard]] constexpr Reference Front()
{
assert(!Empty());
return Data()[0];
}

[[nodiscard]] constexpr ConstReference Front() const
{
assert(!Empty());
return Data()[0];
}

[[nodiscard]] constexpr Reference Back()
{
assert(!Empty());
return Data()[Size() - 1];
}

[[nodiscard]] constexpr ConstReference Back() const
{
assert(!Empty());
return Data()[Size() - 1];
}

[[nodiscard]] constexpr Iterator Begin() noexcept
{
return Iterator(beginPtr);
}

[[nodiscard]] constexpr ConstIterator Begin() const noexcept
{
return ConstIterator(beginPtr);
}

[[nodiscard]] constexpr Iterator End() noexcept
{
return Iterator(endPtr);
}

[[nodiscard]] constexpr ConstIterator End() const noexcept
{
return ConstIterator(endPtr);
}

[[nodiscard]] constexpr ReverseIterator RBegin() noexcept
{
return ReverseIterator(Begin());
}

[[nodiscard]] constexpr ConstReverseIterator RBegin() const noexcept
{
return ConstReverseIterator(Begin());
}

[[nodiscard]] constexpr ReverseIterator REnd() noexcept
{
return ReverseIterator(End());
}

[[nodiscard]] constexpr ConstReverseIterator REnd() const noexcept
{
return ConstReverseIterator(End());
}

[[nodiscard]] constexpr bool Empty() const
{
return Size() == 0;
}

[[nodiscard]] constexpr Pointer Data() noexcept
{
return beginPtr;
}

[[nodiscard]] constexpr ConstPointer Data() const noexcept
{
return beginPtr;
}

[[nodiscard]] constexpr DifferenceType Size() const
{
return End() - Begin();
}

T* beginPtr; // 00
T* endPtr; // 08

#pragma region STL
[[nodiscard]] constexpr Iterator begin() noexcept
{
return Begin();
}

[[nodiscard]] constexpr ConstIterator begin() const noexcept
{
return Begin();
}

[[nodiscard]] constexpr Iterator end() noexcept
{
return End();
}

[[nodiscard]] constexpr ConstIterator end() const noexcept
{
return End();
}
#pragma endregion
};
RED4EXT_ASSERT_SIZE(Span<int32_t>, 0x10);
RED4EXT_ASSERT_OFFSET(Span<int32_t>, beginPtr, 0x0);
RED4EXT_ASSERT_OFFSET(Span<int32_t>, endPtr, 0x8);
} // namespace RED4ext
Loading