Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
Buffer.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/Internal/IGrowableBuffer.h"
5#include "../Memory/Memory.h"
6#include "../Memory/Segment.h"
7
8namespace SC
9{
10
13
14namespace detail
15{
16struct SC_MEMORY_EXPORT SegmentBuffer : public SegmentTrivial<char>, public SegmentSelfRelativePointer<char>
17{
18 static constexpr bool IsArray = false;
19};
20} // namespace detail
21
29struct SC_MEMORY_EXPORT Buffer : public Segment<detail::SegmentBuffer>
30{
31 using Segment::Segment;
32};
33
37template <int N>
38struct SmallBuffer : public Buffer
39{
40 SmallBuffer(SegmentAllocator allocator = SegmentAllocator::Global) noexcept : Buffer(N, allocator) {}
41 SmallBuffer(const Buffer& other) noexcept : SmallBuffer() { Buffer::operator=(other); }
42 SmallBuffer(Buffer&& other) noexcept : SmallBuffer() { Buffer::operator=(move(other)); }
43 Buffer& operator=(const Buffer& other) noexcept { return Buffer::operator=(other); }
44 Buffer& operator=(Buffer&& other) noexcept { return Buffer::operator=(move(other)); }
45
46 // clang-format off
47 SmallBuffer(const SmallBuffer& other) noexcept : SmallBuffer() { Buffer::operator=(other); }
48 SmallBuffer(SmallBuffer&& other) noexcept : SmallBuffer() { Buffer::operator=(move(other)); }
49 SmallBuffer& operator=(const SmallBuffer& other) noexcept { Buffer::operator=(other); return *this; }
50 SmallBuffer& operator=(SmallBuffer&& other) noexcept { Buffer::operator=(move(other)); return *this; }
51 // clang-format on
52
53 protected:
54 SmallBuffer(int num, SegmentAllocator allocator) : Buffer(N, allocator) { (void)num; }
55
56 private:
57 uint64_t inlineCapacity = N;
58 char inlineBuffer[N];
59};
60
61using BufferTL = detail::SegmentCustom<Buffer, Buffer, 0, SegmentAllocator::ThreadLocal>;
62template <int N>
63using SmallBufferTL = detail::SegmentCustom<SmallBuffer<N>, Buffer, N, SegmentAllocator::ThreadLocal>;
64
65#if SC_COMPILER_MSVC
66// Adding the SC_MEMORY_EXPORT on Buffer declaration causes MSVC to issue error C2491
67struct SC_MEMORY_EXPORT Buffer;
68#endif
69
70// Enables File library from reading data from file descriptor into a Buffer
71template <>
72struct SC_MEMORY_EXPORT GrowableBuffer<Buffer> : public IGrowableBuffer
73{
74 Buffer& buffer;
75 GrowableBuffer(Buffer& buffer) noexcept;
76 ~GrowableBuffer() noexcept;
77 static bool tryGrowTo(IGrowableBuffer&, size_t newSize) noexcept;
78 void finalize() noexcept;
79};
80
81template <int N>
82struct SC_MEMORY_EXPORT GrowableBuffer<SmallBuffer<N>> : public IGrowableBuffer
83{
84 Buffer& buffer;
85 GrowableBuffer(Buffer& buffer) noexcept : IGrowableBuffer(&GrowableBuffer::tryGrowTo), buffer(buffer)
86 {
87 IGrowableBuffer::directAccess = {buffer.size(), buffer.capacity(), buffer.data()};
88 }
89 ~GrowableBuffer() noexcept { finalize(); }
90
91 static bool tryGrowTo(IGrowableBuffer& gb, size_t newSize) noexcept
92 {
93 GrowableBuffer& self = static_cast<GrowableBuffer&>(gb);
94 const bool result = self.buffer.resizeWithoutInitializing(newSize);
95 self.directAccess = {self.buffer.size(), self.buffer.capacity(), self.buffer.data()};
96 return result;
97 }
98 void finalize() noexcept { (void)buffer.resizeWithoutInitializing(IGrowableBuffer::directAccess.sizeInBytes); }
99};
101} // namespace SC
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition Compiler.h:273
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:33
An heap allocated byte buffer that can optionally use an inline buffer.
Definition Buffer.h:30
A slice of contiguous memory, prefixed by and header containing size and capacity.
Definition Segment.h:114
A SC::Buffer with a dedicated custom inline buffer to avoid heap allocation.
Definition Buffer.h:39