aboutsummaryrefslogtreecommitdiff
path: root/zencore/include
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-05-24 13:16:46 +0200
committerStefan Boberg <[email protected]>2021-05-24 13:16:46 +0200
commit4d5daa5ab598d0389890894cb713ddb4b366c3ca (patch)
tree8fa3c0bd6027a105d06b1fa1a803a28fd508846c /zencore/include
parentAdded RefPtr::IsNull() (diff)
downloadzen-4d5daa5ab598d0389890894cb713ddb4b366c3ca.tar.xz
zen-4d5daa5ab598d0389890894cb713ddb4b366c3ca.zip
Added some functionality to support CompositeBuffer implementation
Diffstat (limited to 'zencore/include')
-rw-r--r--zencore/include/zencore/memory.h146
1 files changed, 138 insertions, 8 deletions
diff --git a/zencore/include/zencore/memory.h b/zencore/include/zencore/memory.h
index 5851ed137..1c681872b 100644
--- a/zencore/include/zencore/memory.h
+++ b/zencore/include/zencore/memory.h
@@ -8,10 +8,13 @@
#include <zencore/thread.h>
#include <algorithm>
+#include <span>
#include <vector>
namespace zen {
+struct MemoryView;
+
class MemoryArena
{
public:
@@ -81,8 +84,25 @@ struct MutableMemoryView
return Size == InView.GetSize() && (memcmp(m_Data, InView.m_Data, Size) == 0);
}
+ /** Modifies the view to be the given number of bytes from the right. */
+ inline void RightInline(uint64_t InSize)
+ {
+ const uint64_t OldSize = GetSize();
+ const uint64_t NewSize = zen::Min(OldSize, InSize);
+ m_Data = GetDataAtOffsetNoCheck(OldSize - NewSize);
+ m_DataEnd = m_Data + NewSize;
+ }
+
+ /** Returns the right-most part of the view by taking the given number of bytes from the right. */
+ [[nodiscard]] inline MutableMemoryView Right(uint64_t InSize) const
+ {
+ MutableMemoryView View(*this);
+ View.RightChopInline(InSize);
+ return View;
+ }
+
/** Modifies the view by chopping the given number of bytes from the left. */
- inline void RightChopInline(uint64_t InSize)
+ inline constexpr void RightChopInline(uint64_t InSize)
{
const uint64_t Offset = zen::Min(GetSize(), InSize);
m_Data = GetDataAtOffsetNoCheck(Offset);
@@ -99,12 +119,29 @@ struct MutableMemoryView
/** Modifies the view to be the given number of bytes from the left. */
constexpr inline void LeftInline(uint64_t InSize) { m_DataEnd = std::min(m_DataEnd, m_Data + InSize); }
+ /** Returns the right-most part of the view by chopping the given number of bytes from the left. */
+ [[nodiscard]] inline MutableMemoryView RightChop(uint64_t InSize) const
+ {
+ MutableMemoryView View(*this);
+ View.RightChopInline(InSize);
+ return View;
+ }
+
+ inline constexpr MutableMemoryView& operator+=(size_t InSize)
+ {
+ RightChopInline(InSize);
+ return *this;
+ }
+
+ /** Copies bytes from the input view into this view, and returns the remainder of this view. */
+ inline MutableMemoryView CopyFrom(MemoryView InView) const;
+
private:
uint8_t* m_Data = nullptr;
uint8_t* m_DataEnd = nullptr;
/** Returns the data pointer advanced by an offset in bytes. */
- inline uint8_t* GetDataAtOffsetNoCheck(uint64_t InOffset) const { return m_Data + InOffset; }
+ inline constexpr uint8_t* GetDataAtOffsetNoCheck(uint64_t InOffset) const { return m_Data + InOffset; }
};
struct MemoryView
@@ -143,14 +180,14 @@ struct MemoryView
return Size == InView.GetSize() && (memcmp(m_Data, InView.GetData(), Size) == 0);
}
- inline MemoryView& operator+=(size_t InSize)
+ inline constexpr MemoryView& operator+=(size_t InSize)
{
RightChopInline(InSize);
return *this;
}
/** Modifies the view by chopping the given number of bytes from the left. */
- inline void RightChopInline(uint64_t InSize)
+ inline constexpr void RightChopInline(uint64_t InSize)
{
const uint64_t Offset = std::min(GetSize(), InSize);
m_Data = GetDataAtOffsetNoCheck(Offset);
@@ -163,6 +200,23 @@ struct MemoryView
return View;
}
+ /** Returns the right-most part of the view by taking the given number of bytes from the right. */
+ [[nodiscard]] inline MemoryView Right(uint64_t InSize) const
+ {
+ MemoryView View(*this);
+ View.RightInline(InSize);
+ return View;
+ }
+
+ /** Modifies the view to be the given number of bytes from the right. */
+ inline void RightInline(uint64_t InSize)
+ {
+ const uint64_t OldSize = GetSize();
+ const uint64_t NewSize = zen::Min(OldSize, InSize);
+ m_Data = GetDataAtOffsetNoCheck(OldSize - NewSize);
+ m_DataEnd = m_Data + NewSize;
+ }
+
/** Returns the left-most part of the view by taking the given number of bytes from the left. */
constexpr inline MemoryView Left(uint64_t InSize) const
{
@@ -172,7 +226,26 @@ struct MemoryView
}
/** Modifies the view to be the given number of bytes from the left. */
- constexpr inline void LeftInline(uint64_t InSize) { m_DataEnd = std::min(m_DataEnd, m_Data + InSize); }
+ constexpr inline void LeftInline(uint64_t InSize)
+ {
+ InSize = zen::Min(GetSize(), InSize);
+ m_DataEnd = std::min(m_DataEnd, m_Data + InSize);
+ }
+
+ /** Modifies the view to be the middle part by taking up to the given number of bytes from the given offset. */
+ inline void MidInline(uint64_t InOffset, uint64_t InSize = ~uint64_t(0))
+ {
+ RightChopInline(InOffset);
+ LeftInline(InSize);
+ }
+
+ /** Returns the middle part of the view by taking up to the given number of bytes from the given position. */
+ [[nodiscard]] inline MemoryView Mid(uint64_t InOffset, uint64_t InSize = ~uint64_t(0)) const
+ {
+ MemoryView View(*this);
+ View.MidInline(InOffset, InSize);
+ return View;
+ }
constexpr void Reset()
{
@@ -185,9 +258,45 @@ private:
const uint8_t* m_DataEnd = nullptr;
/** Returns the data pointer advanced by an offset in bytes. */
- inline const uint8_t* GetDataAtOffsetNoCheck(uint64_t InOffset) const { return m_Data + InOffset; }
+ inline constexpr const uint8_t* GetDataAtOffsetNoCheck(uint64_t InOffset) const { return m_Data + InOffset; }
};
+inline MutableMemoryView
+MutableMemoryView::CopyFrom(MemoryView InView) const
+{
+ ZEN_ASSERT(InView.GetSize() <= GetSize());
+ memcpy(m_Data, InView.GetData(), InView.GetSize());
+ return RightChop(InView.GetSize());
+}
+
+/** Advances the start of the view by an offset, which is clamped to stay within the view. */
+constexpr inline MemoryView
+operator+(const MemoryView& View, uint64_t Offset)
+{
+ return MemoryView(View) += Offset;
+}
+
+/** Advances the start of the view by an offset, which is clamped to stay within the view. */
+constexpr inline MemoryView
+operator+(uint64_t Offset, const MemoryView& View)
+{
+ return MemoryView(View) += Offset;
+}
+
+/** Advances the start of the view by an offset, which is clamped to stay within the view. */
+constexpr inline MutableMemoryView
+operator+(const MutableMemoryView& View, uint64_t Offset)
+{
+ return MutableMemoryView(View) += Offset;
+}
+
+/** Advances the start of the view by an offset, which is clamped to stay within the view. */
+constexpr inline MutableMemoryView
+operator+(uint64_t Offset, const MutableMemoryView& View)
+{
+ return MutableMemoryView(View) += Offset;
+}
+
/**
* Make a non-owning view of the memory of the initializer list.
*
@@ -205,8 +314,29 @@ template<std::ranges::contiguous_range R>
[[nodiscard]] constexpr inline MemoryView
MakeMemoryView(const R& Container)
{
- const auto& Front = *std::begin(Container);
- return MemoryView(std::addressof(Front), std::size(Container) * sizeof(Front));
+ std::span Span = Container;
+ return MemoryView(Span.data(), Span.size() * sizeof(decltype(Span)::element_type));
+}
+
+/**
+ * Make a non-owning view of the memory of the initializer list.
+ *
+ * This overload is only available when the element type does not need to be deduced.
+ */
+template<typename T>
+[[nodiscard]] inline MutableMemoryView
+MakeMutableMemoryView(std::initializer_list<typename std::type_identity<T>::type> List)
+{
+ return MutableMemoryView(List.begin(), List.size() * sizeof(T));
+}
+
+/** Make a non-owning view of the memory of the contiguous container. */
+template<std::ranges::contiguous_range R>
+[[nodiscard]] constexpr inline MutableMemoryView
+MakeMutableMemoryView(R& Container)
+{
+ std::span Span = Container;
+ return MutableMemoryView(Span.data(), Span.size() * sizeof(decltype(Span)::element_type));
}
void memory_forcelink(); // internal