summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2024-10-30 09:51:54 -0500
committerDominick Allen <djallen@librehumanitas.org>2024-10-30 09:51:54 -0500
commit6c7fd1db481ff10a16ecab958c6542784fa60b9c (patch)
treee0162f930ec44a7c53b07061311d52910c36e481
parent8dcb1de91e15ff7fc66279cd9cd9ad8a70f624e0 (diff)
Use std::byte* instead of void* for allocators.
-rw-r--r--include/fud_allocator.hpp25
-rw-r--r--include/fud_c_file.hpp40
-rw-r--r--include/fud_drain.hpp12
-rw-r--r--include/fud_file.hpp68
-rw-r--r--include/fud_format.hpp61
-rw-r--r--include/fud_vector.hpp14
-rw-r--r--source/fud_allocator.cpp29
-rw-r--r--source/fud_assert.cpp4
-rw-r--r--source/fud_file.cpp20
-rw-r--r--source/fud_string.cpp95
-rw-r--r--test/test_allocator.cpp2
-rw-r--r--test/test_common.cpp14
-rw-r--r--test/test_common.hpp9
-rw-r--r--test/test_directory.cpp4
-rw-r--r--test/test_string.cpp2
-rw-r--r--test/test_utf8.cpp12
16 files changed, 222 insertions, 189 deletions
diff --git a/include/fud_allocator.hpp b/include/fud_allocator.hpp
index d4feccf..e4078ac 100644
--- a/include/fud_allocator.hpp
+++ b/include/fud_allocator.hpp
@@ -30,9 +30,9 @@ class alignas(std::max_align_t) Allocator {
public:
virtual ~Allocator() = default;
- virtual Result<void*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) = 0;
+ virtual Result<std::byte*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) = 0;
- virtual FudStatus deallocate(void* pointer, size_t bytes) = 0;
+ virtual FudStatus deallocate(std::byte* pointer, size_t bytes) = 0;
virtual bool isEqual(const Allocator& rhs) const = 0;
};
@@ -46,20 +46,33 @@ class FudAllocator : public Allocator {
public:
virtual ~FudAllocator() override = default;
- virtual Result<void*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) override;
+ virtual Result<std::byte*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) override;
- virtual FudStatus deallocate(void* pointer, size_t bytes) override;
+ virtual FudStatus deallocate(std::byte* pointer, size_t bytes) override;
virtual bool isEqual(const Allocator& rhs) const override;
};
extern FudAllocator globalFudAllocator;
+class NullAllocator : public Allocator {
+ public:
+ virtual ~NullAllocator() override = default;
+
+ virtual Result<std::byte*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) override;
+
+ virtual FudStatus deallocate(std::byte* pointer, size_t bytes) override;
+
+ virtual bool isEqual(const Allocator& rhs) const override;
+};
+
+extern NullAllocator globalNullAllocator;
+
/** \brief The default allocation function for globalFudAllocator. */
-extern void* fudAlloc(size_t size);
+extern std::byte* fudAlloc(size_t size);
/** \brief The default deallocation function for globalFudAllocator. */
-extern void fudFree(void* ptr);
+extern void fudFree(std::byte* ptr);
} // namespace fud
diff --git a/include/fud_c_file.hpp b/include/fud_c_file.hpp
index bf148c2..e0be680 100644
--- a/include/fud_c_file.hpp
+++ b/include/fud_c_file.hpp
@@ -18,11 +18,11 @@
#ifndef FUD_C_FILE_HPP
#define FUD_C_FILE_HPP
+#include "fud_drain.hpp"
#include "fud_permissions.hpp"
#include "fud_result.hpp"
#include "fud_status.hpp"
#include "fud_string.hpp"
-#include "fud_file.hpp"
#include <cstdint>
#include <cstdio>
@@ -184,16 +184,16 @@ class CFile {
return RetType::okay(fileSize);
}
- [[nodiscard]] ReadResult read(void* destination, size_t destinationSize, size_t length)
+ [[nodiscard]] DrainResult read(void* destination, size_t destinationSize, size_t length)
{
auto& self = static_cast<Derived&>(*this);
return self.read(destination, destinationSize, length, 0);
}
- [[nodiscard]] ReadResult read(void* destination, size_t destinationSize, size_t length, size_t offset)
+ [[nodiscard]] DrainResult read(void* destination, size_t destinationSize, size_t length, size_t offset)
{
auto& self = static_cast<Derived&>(*this);
- ReadResult result{};
+ DrainResult result{};
if (length == 0) {
return result;
}
@@ -227,9 +227,9 @@ class CFile {
}
auto* destBytes = static_cast<char*>(destination);
- result.bytesRead = fread(destBytes, 1, length, self.m_file);
+ result.bytesDrained = fread(destBytes, 1, length, self.m_file);
static_cast<void>(self.reset());
- if (result.bytesRead != length) {
+ if (result.bytesDrained != length) {
result.status = FudStatus::Partial;
} else {
result.status = FudStatus::Success;
@@ -239,7 +239,7 @@ class CFile {
}
template <typename T>
- [[nodiscard]] ReadResult read(T& destination, size_t length)
+ [[nodiscard]] DrainResult read(T& destination, size_t length)
{
static_assert(not std::is_pointer_v<decltype(destination)>);
auto& self = static_cast<Derived&>(*this);
@@ -247,39 +247,39 @@ class CFile {
}
template <typename T>
- [[nodiscard]] ReadResult read(T& destination, size_t length, size_t offset)
+ [[nodiscard]] DrainResult read(T& destination, size_t length, size_t offset)
{
static_assert(not std::is_pointer_v<decltype(destination)>);
auto& self = static_cast<Derived&>(*this);
return self.read(&destination, sizeof(destination), length, offset);
}
- [[nodiscard]] WriteResult write(const void* source, size_t sourceSize)
+ [[nodiscard]] DrainResult write(const void* source, size_t sourceSize)
{
auto& self = static_cast<Derived&>(*this);
auto offsetResult = self.size();
if (offsetResult.isError()) {
- return WriteResult{0, offsetResult.getError()};
+ return DrainResult{0, offsetResult.getError()};
}
return self.write(source, sourceSize, sourceSize, offsetResult.getOkay());
}
- [[nodiscard]] WriteResult write(const void* source, size_t sourceSize, size_t length)
+ [[nodiscard]] DrainResult write(const void* source, size_t sourceSize, size_t length)
{
auto& self = static_cast<Derived&>(*this);
auto offsetResult = self.size();
if (offsetResult.isError()) {
- return WriteResult{0, offsetResult.getError()};
+ return DrainResult{0, offsetResult.getError()};
}
return self.write(source, sourceSize, length, offsetResult.getOkay());
}
- [[nodiscard]] WriteResult write(const void* source, size_t sourceSize, size_t length, size_t offset)
+ [[nodiscard]] DrainResult write(const void* source, size_t sourceSize, size_t length, size_t offset)
{
auto& self = static_cast<Derived&>(*this);
- WriteResult result{};
+ DrainResult result{};
if (length == 0) {
return result;
}
@@ -315,9 +315,9 @@ class CFile {
}
const auto* sourceBytes = static_cast<const char*>(source);
- result.bytesWritten = fwrite(sourceBytes, 1, length, self.m_file);
+ result.bytesDrained = fwrite(sourceBytes, 1, length, self.m_file);
static_cast<void>(self.reset());
- if (result.bytesWritten != length) {
+ if (result.bytesDrained != length) {
result.status = FudStatus::Partial;
} else {
result.status = FudStatus::Success;
@@ -327,7 +327,7 @@ class CFile {
}
template <typename T>
- [[nodiscard]] WriteResult write(const T& source)
+ [[nodiscard]] DrainResult write(const T& source)
{
static_assert(not std::is_pointer_v<decltype(source)>);
auto& self = static_cast<Derived&>(*this);
@@ -335,19 +335,19 @@ class CFile {
}
template <typename T>
- [[nodiscard]] WriteResult write(const T& source, size_t sourceSize, size_t length)
+ [[nodiscard]] DrainResult write(const T& source, size_t sourceSize, size_t length)
{
static_assert(not std::is_pointer_v<decltype(source)>);
auto& self = static_cast<Derived&>(*this);
auto offsetResult = self.size();
if (offsetResult.isError()) {
- return WriteResult{0, offsetResult.getError()};
+ return DrainResult{0, offsetResult.getError()};
}
return self.write(source, sourceSize, length, offsetResult.getOkay());
}
template <typename T>
- [[nodiscard]] WriteResult write(const T& source, size_t sourceSize, size_t length, size_t offset)
+ [[nodiscard]] DrainResult write(const T& source, size_t sourceSize, size_t length, size_t offset)
{
static_assert(not std::is_pointer_v<decltype(source)>);
auto& self = static_cast<Derived&>(*this);
diff --git a/include/fud_drain.hpp b/include/fud_drain.hpp
index 5b78b10..d630bc7 100644
--- a/include/fud_drain.hpp
+++ b/include/fud_drain.hpp
@@ -26,8 +26,18 @@
namespace fud {
struct DrainResult {
- size_t bytesWritten;
+ size_t bytesDrained;
FudStatus status;
+ [[nodiscard]] constexpr bool isOkay()
+ {
+ return status == FudStatus::Success;
+ }
+};
+
+template <typename Sink, typename Source>
+concept Drainable = requires (Sink sink, Source source)
+{
+ { sink.drain(source) } -> std::same_as<DrainResult>;
};
} // namespace fud
diff --git a/include/fud_file.hpp b/include/fud_file.hpp
index 9ef2cbc..51826a6 100644
--- a/include/fud_file.hpp
+++ b/include/fud_file.hpp
@@ -18,12 +18,13 @@
#ifndef FUD_FILE_HPP
#define FUD_FILE_HPP
-#include "fud_allocator.hpp"
#include "fud_option.hpp"
#include "fud_permissions.hpp"
#include "fud_result.hpp"
#include "fud_status.hpp"
#include "fud_string_view.hpp"
+#include "fud_vector.hpp"
+#include "fud_drain.hpp"
#include <fcntl.h>
@@ -37,16 +38,17 @@ enum class FileAccessMode : uint8_t
ReadWrite = Read | Write
};
-enum class OpenFlagEnum : uint32_t
+// enum class OpenFlagEnum : uint32_t
+enum class OpenFlagEnum : uint8_t
{
- Append = O_APPEND,
- Truncate = O_TRUNC,
- CloseOnExec = O_CLOEXEC,
- DataSync = O_DSYNC,
- Direct = O_DIRECT,
- NoAtime = O_NOATIME,
- NonBlock = O_NONBLOCK,
- FileSync = O_SYNC
+ Append = 0x01,
+ Truncate = Append << 1,
+ CloseOnExec = Truncate << 1,
+ DataSync = CloseOnExec << 1,
+ Direct = DataSync << 1,
+ NoAtime = Direct << 1,
+ NonBlock = NoAtime << 1,
+ FileSync = NonBlock << 1
};
class OpenFlags {
@@ -90,12 +92,20 @@ class OpenFlags {
return mode;
}
- constexpr FlagType flags() const noexcept
- {
- return m_mask;
+ constexpr uint32_t flags() const noexcept {
+ uint32_t openFlags = 0;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::Append)) * O_APPEND;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::Truncate)) * O_TRUNC;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::CloseOnExec)) * O_CLOEXEC;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::DataSync)) * O_DSYNC;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::Direct)) * O_DIRECT;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::NoAtime)) * O_NOATIME;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::NonBlock)) * O_NONBLOCK;
+ openFlags |= static_cast<uint32_t>(hasFlag(OpenFlagEnum::FileSync)) * O_SYNC;
+ return openFlags;
}
- constexpr bool hasFlag(OpenFlagEnum flag) noexcept
+ constexpr bool hasFlag(OpenFlagEnum flag) const noexcept
{
return (m_mask & static_cast<FlagType>(flag)) != 0;
}
@@ -110,16 +120,6 @@ constexpr OpenFlags operator|(OpenFlagEnum lhs, OpenFlagEnum rhs)
return mode | rhs;
}
-struct [[nodiscard]] ReadResult {
- size_t bytesRead{0};
- FudStatus status{FudStatus::Success};
-};
-
-struct [[nodiscard]] WriteResult {
- size_t bytesWritten{0};
- FudStatus status{FudStatus::Success};
-};
-
class RegularFile;
using FileResult = Result<RegularFile, FudStatus>;
@@ -129,8 +129,7 @@ class RegularFile {
StringView filename,
FileAccessMode mode,
OpenFlags flags,
- Option<int> dirFdoption,
- Allocator* allocator = &globalFudAllocator);
+ Option<int> dirFdoption);
static FileResult create(
StringView filename,
@@ -138,8 +137,7 @@ class RegularFile {
OpenFlags flags,
Permissions permissions,
bool exclusive,
- Option<int> dirFdOption,
- Allocator* allocator = &globalFudAllocator);
+ Option<int> dirFdOption);
FudStatus close();
@@ -163,8 +161,20 @@ class RegularFile {
private:
int m_fd{-1};
- FileAccessMode m_modeFlags{};
OpenFlags m_openFlags{};
+ FileAccessMode m_modeFlags{};
+};
+
+class BufferedRegularFile {
+public:
+ DrainResult write(const void* source, size_t sourceSize, size_t length, size_t offset);
+ // DrainResult read(void* sink, );
+private:
+ Vector<std::byte> m_readBuffer{Vector<std::byte>::NullVector()};
+ Vector<std::byte> m_writeBuffer{Vector<std::byte>::NullVector()};
+ RegularFile m_file;
+ bool m_readBuffered{false};
+ bool m_writeBuffered{false};
};
} // namespace fud
diff --git a/include/fud_format.hpp b/include/fud_format.hpp
index 4d38c26..2102dc9 100644
--- a/include/fud_format.hpp
+++ b/include/fud_format.hpp
@@ -20,6 +20,7 @@
// #include "fud_assert.hpp"
#include "dragonbox/dragonbox.h"
+#include "fud_drain.hpp"
#include "fud_array.hpp"
#include "fud_option.hpp"
#include "fud_result.hpp"
@@ -270,21 +271,14 @@ enum class FormatCharMode
ValidUtf8
};
-struct FormatResult {
- size_t bytesWritten{0};
- FudStatus status{FudStatus::Failure};
- [[nodiscard]] constexpr bool isOkay()
- {
- return status == FudStatus::Success;
- }
-};
+using FormatResult = DrainResult;
/* TODO : require concept of a sink that takes pushBack() -> FudStatus */
/* TODO : sink concept also requires drain() -> FudStatus */
-template <typename Sink>
+template <typename Sink> requires Drainable<Sink, StringView>
FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt);
-template <typename Sink, typename... Args>
+template <typename Sink, typename... Args> requires Drainable<Sink, StringView>
FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Args&&... args);
template <typename Sink>
@@ -341,7 +335,7 @@ size_t findSpec(StringView scanView);
} // namespace impl
-template <typename Sink, typename... Args>
+template <typename Sink, typename... Args> requires Drainable<Sink, StringView>
FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Args&&... args)
{
static_cast<void>(sink);
@@ -355,7 +349,7 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Arg
return impl::vFormat(sink, formatMode, fmt, formatArguments);
}
-template <typename Sink>
+template <typename Sink> requires Drainable<Sink, StringView>
FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt)
{
if (formatMode != FormatCharMode::Unchecked) {
@@ -368,8 +362,7 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt)
return {0, FudStatus::FormatInvalid};
}
- auto drainResult = sink.drain(fmt.view());
- return FormatResult{drainResult.bytesWritten, drainResult.status};
+ return sink.drain(fmt.view());
}
namespace impl {
@@ -419,7 +412,7 @@ FormatResult vFormat(Sink& sink, FormatCharMode formatMode, FormatString fmt, co
fudAssert(specIndex <= scanView.length());
StringView run{specIndex, scanView.data()};
auto drainResult = sink.drain(run);
- result.bytesWritten += drainResult.bytesWritten;
+ result.bytesDrained += drainResult.bytesDrained;
if (drainResult.status != FudStatus::Success) {
result.status = drainResult.status;
return result;
@@ -451,7 +444,7 @@ FormatResult vFormat(Sink& sink, FormatCharMode formatMode, FormatString fmt, co
result.status = argResult.status;
return result;
}
- result.bytesWritten += argResult.bytesWritten;
+ result.bytesDrained += argResult.bytesDrained;
if (!formatSpec.takesPosition()) {
argIndex++;
argIndex += static_cast<uint8_t>(formatSpec.takesWidth);
@@ -904,7 +897,7 @@ FormatResult drainIntegral(
if (sign.length() > 0) {
auto drainResult = sink.drain(sign);
- result.bytesWritten += drainResult.bytesWritten;
+ result.bytesDrained += drainResult.bytesDrained;
result.status = drainResult.status;
}
@@ -914,7 +907,7 @@ FormatResult drainIntegral(
if (prefix.length() > 0) {
auto drainResult = sink.drain(prefix);
- result.bytesWritten += drainResult.bytesWritten;
+ result.bytesDrained += drainResult.bytesDrained;
result.status = drainResult.status;
}
@@ -925,7 +918,7 @@ FormatResult drainIntegral(
if (padZero) {
auto zeroPadSize = width - calculatedWidth;
auto padResult = fillPad(sink, '0', zeroPadSize);
- result.bytesWritten += padResult.bytesWritten;
+ result.bytesDrained += padResult.bytesDrained;
result.status = padResult.status;
}
@@ -934,7 +927,7 @@ FormatResult drainIntegral(
}
auto drainNumberResult = sink.drain(buffer);
- result.bytesWritten += drainNumberResult.bytesWritten;
+ result.bytesDrained += drainNumberResult.bytesDrained;
result.status = drainNumberResult.status;
if (result.status != FudStatus::Success) {
@@ -942,7 +935,7 @@ FormatResult drainIntegral(
}
auto rightPadResult = rightPad(sink, align, width, fill, calculatedWidth);
- result.bytesWritten += rightPadResult.bytesWritten;
+ result.bytesDrained += rightPadResult.bytesDrained;
result.status = rightPadResult.status;
return result;
@@ -964,19 +957,19 @@ template <typename Sink>
for (auto bufferSize : bufferSizes) {
while (count > bufferSize) {
auto drainResult = sink.drain(StringView{bufferSize, backingBuffer.data()});
- result.bytesWritten += drainResult.bytesWritten;
+ result.bytesDrained += drainResult.bytesDrained;
result.status = drainResult.status;
if (result.status != FudStatus::Success) {
return result;
}
- count -= drainResult.bytesWritten;
+ count -= drainResult.bytesDrained;
}
}
if (count > 0) {
fudAssert(count < backingBuffer.size());
auto drainResult = sink.drain(StringView{count, backingBuffer.data()});
- result.bytesWritten += drainResult.bytesWritten;
+ result.bytesDrained += drainResult.bytesDrained;
result.status = drainResult.status;
}
@@ -1201,45 +1194,45 @@ template <typename Sink, typename DecimalRepr>
if (width > calculatedWidth && not padZero) {
auto padResult = leftPad(sink, align, width, fill, calculatedWidth);
- result.bytesWritten += padResult.bytesWritten;
+ result.bytesDrained += padResult.bytesDrained;
result.status = padResult.status;
}
if (result.status == FudStatus::Success && sign.length() > 0) {
auto drainResult = sink.drain(sign);
- result.bytesWritten += drainResult.bytesWritten;
+ result.bytesDrained += drainResult.bytesDrained;
result.status = drainResult.status;
}
if (result.status == FudStatus::Success && padZero && width > calculatedWidth) {
auto zeroPadSize = width - calculatedWidth;
auto padResult = fillPad(sink, '0', zeroPadSize);
- result.bytesWritten += padResult.bytesWritten;
+ result.bytesDrained += padResult.bytesDrained;
result.status = padResult.status;
}
if (result.status == FudStatus::Success) {
auto drainNumberResult = sink.drain(numberView);
- result.bytesWritten += drainNumberResult.bytesWritten;
+ result.bytesDrained += drainNumberResult.bytesDrained;
result.status = drainNumberResult.status;
}
if (result.status == FudStatus::Success && precision > precisionPlaces) {
auto remainingPlaces = precision - precisionPlaces;
auto precisionResult = fillPad(sink, '0', remainingPlaces);
- result.bytesWritten += precisionResult.bytesWritten;
+ result.bytesDrained += precisionResult.bytesDrained;
result.status = precisionResult.status;
}
if (result.status == FudStatus::Success) {
auto exponentDrainResult = sink.drain(exponentView);
- result.bytesWritten += exponentDrainResult.bytesWritten;
+ result.bytesDrained += exponentDrainResult.bytesDrained;
result.status = exponentDrainResult.status;
}
if (result.status == FudStatus::Success) {
auto padResult = rightPad(sink, align, width, fill, calculatedWidth);
- result.bytesWritten += padResult.bytesWritten;
+ result.bytesDrained += padResult.bytesDrained;
result.status = padResult.status;
}
@@ -1441,7 +1434,7 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for
}
auto padResult = impl::leftPad(sink, align, width, fill, calculatedWidth);
- result.bytesWritten += padResult.bytesWritten;
+ result.bytesDrained += padResult.bytesDrained;
result.status = padResult.status;
if (result.status != FudStatus::Success) {
@@ -1449,7 +1442,7 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for
}
auto drainViewResult = sink.drain(arg);
- result.bytesWritten += drainViewResult.bytesWritten;
+ result.bytesDrained += drainViewResult.bytesDrained;
result.status = drainViewResult.status;
if (result.status != FudStatus::Success) {
@@ -1457,7 +1450,7 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, const FormatSpec& for
}
padResult = impl::rightPad(sink, align, width, fill, calculatedWidth);
- result.bytesWritten += padResult.bytesWritten;
+ result.bytesDrained += padResult.bytesDrained;
result.status = padResult.status;
return result;
diff --git a/include/fud_vector.hpp b/include/fud_vector.hpp
index 2b5de9a..52876fd 100644
--- a/include/fud_vector.hpp
+++ b/include/fud_vector.hpp
@@ -70,6 +70,12 @@ class Vector {
rhs.m_capacity = 0;
}
+ static constexpr Vector<T> NullVector() noexcept {
+ Vector<T> output{};
+ output.m_allocator = &globalNullAllocator;
+ return output;
+ }
+
static Result<Vector<T>, FudStatus> withCapacity(size_t capacity, Allocator* allocator = &globalFudAllocator)
{
Vector<T> output{};
@@ -104,7 +110,7 @@ class Vector {
}
output.m_allocator = allocator;
- output.m_data = static_cast<T*>(dataPtrResult.getOkay());
+ output.m_data = reinterpret_cast<T*>(dataPtrResult.getOkay());
output.m_length = 0;
output.m_capacity = capacity;
return FudStatus::Success;
@@ -341,7 +347,7 @@ class Vector {
return dataPtrResult.takeError();
}
- auto* dataPtr = static_cast<T*>(dataPtrResult.takeOkay());
+ auto* dataPtr = reinterpret_cast<T*>(dataPtrResult.takeOkay());
for (size_t index = 0; index < m_length; ++index) {
const auto* ptr = new (dataPtr + index) T(std::move(m_data[index]));
fudAssert(ptr != nullptr);
@@ -350,7 +356,7 @@ class Vector {
auto status = FudStatus::Success;
if (m_capacity > 0) {
- status = m_allocator->deallocate(m_data, m_capacity);
+ status = m_allocator->deallocate(reinterpret_cast<std::byte*>(m_data), m_capacity);
}
m_data = dataPtr;
@@ -666,7 +672,7 @@ class Vector {
auto status = clear();
if (m_data != nullptr && m_allocator != nullptr) {
- auto deallocStatus = m_allocator->deallocate(m_data, m_capacity);
+ auto deallocStatus = m_allocator->deallocate(reinterpret_cast<std::byte*>(m_data), m_capacity);
if (status == FudStatus::Success) {
status = deallocStatus;
}
diff --git a/source/fud_allocator.cpp b/source/fud_allocator.cpp
index 8daf969..d5127fa 100644
--- a/source/fud_allocator.cpp
+++ b/source/fud_allocator.cpp
@@ -19,18 +19,18 @@
namespace fud {
-Result<void*, FudStatus> FudAllocator::allocate(size_t bytes, size_t alignment)
+Result<std::byte*, FudStatus> FudAllocator::allocate(size_t bytes, size_t alignment)
{
- using RetType = Result<void*, FudStatus>;
+ using RetType = Result<std::byte*, FudStatus>;
static_cast<void>(alignment);
- auto* pointer = static_cast<std::byte*>(fudAlloc(bytes));
+ auto* pointer = fudAlloc(bytes);
if (pointer == nullptr) {
return RetType::error(FudStatus::AllocFailure);
}
return RetType::okay(pointer);
}
-FudStatus FudAllocator::deallocate(void* pointer, size_t bytes)
+FudStatus FudAllocator::deallocate(std::byte* pointer, size_t bytes)
{
if (pointer == nullptr || bytes == 0) {
return FudStatus::ArgumentInvalid;
@@ -46,4 +46,25 @@ bool FudAllocator::isEqual(const Allocator& rhs) const
FudAllocator globalFudAllocator{};
+Result<std::byte*, FudStatus> NullAllocator::allocate(size_t bytes, size_t alignment)
+{
+ static_cast<void>(bytes);
+ static_cast<void>(alignment);
+ return FudError{FudStatus::Failure};
+}
+
+FudStatus NullAllocator::deallocate(std::byte* pointer, size_t bytes)
+{
+ static_cast<void>(pointer);
+ static_cast<void>(bytes);
+ return FudStatus::Failure;
+}
+
+bool NullAllocator::isEqual(const Allocator& rhs) const
+{
+ return &rhs == static_cast<const Allocator*>(this);
+}
+
+NullAllocator globalNullAllocator{};
+
} // namespace fud
diff --git a/source/fud_assert.cpp b/source/fud_assert.cpp
index 7838e22..966f44c 100644
--- a/source/fud_assert.cpp
+++ b/source/fud_assert.cpp
@@ -42,8 +42,8 @@ DrainResult BufferSink::drain(StringView source)
return result;
}
/* TODO: give users control over this functionality */
- result.bytesWritten = fwrite(reinterpret_cast<const char*>(source.m_data), 1, source.m_length, stderr);
- if (result.bytesWritten != source.m_length) {
+ result.bytesDrained = fwrite(reinterpret_cast<const char*>(source.m_data), 1, source.m_length, stderr);
+ if (result.bytesDrained != source.m_length) {
result.status = FudStatus::Full;
}
return result;
diff --git a/source/fud_file.cpp b/source/fud_file.cpp
index 8f84648..94f1f27 100644
--- a/source/fud_file.cpp
+++ b/source/fud_file.cpp
@@ -30,13 +30,8 @@ FileResult RegularFile::open(
StringView filename,
FileAccessMode mode,
OpenFlags flags,
- Option<int> dirFdOption,
- Allocator* allocator)
+ Option<int> dirFdOption)
{
- if (allocator == nullptr) {
- return FileResult::error(FudStatus::NullPointer);
- }
-
if (!filename.nullTerminated()) {
return FileResult::error(FudStatus::ArgumentInvalid);
}
@@ -115,6 +110,8 @@ FileResult RegularFile::open(
return FileResult::error(FudStatus::ObjectInvalid);
}
+ file.m_openFlags = flags;
+
return FileResult::okay(std::move(file));
}
@@ -124,13 +121,8 @@ FileResult RegularFile::create(
OpenFlags flags,
Permissions permissions,
bool exclusive,
- Option<int> dirFdOption,
- Allocator* allocator)
+ Option<int> dirFdOption)
{
- if (allocator == nullptr) {
- return FileResult::error(FudStatus::NullPointer);
- }
-
if (!filename.nullTerminated()) {
return FileResult::error(FudStatus::ArgumentInvalid);
}
@@ -218,7 +210,7 @@ RegularFile::~RegularFile()
static_cast<void>(this->close());
}
-RegularFile::RegularFile(RegularFile&& rhs) noexcept : m_fd{rhs.m_fd}, m_modeFlags{rhs.m_modeFlags}
+RegularFile::RegularFile(RegularFile&& rhs) noexcept : m_fd{rhs.m_fd}, m_openFlags{rhs.m_openFlags}, m_modeFlags{rhs.m_modeFlags}
{
rhs.m_fd = -1;
}
@@ -232,6 +224,7 @@ RegularFile& RegularFile::operator=(RegularFile&& rhs) noexcept
static_cast<void>(this->close());
m_fd = rhs.m_fd;
+ m_openFlags = rhs.m_openFlags;
m_modeFlags = rhs.m_modeFlags;
rhs.m_fd = -1;
@@ -250,6 +243,7 @@ FudStatus RegularFile::take(RegularFile& rhs)
}
m_fd = rhs.m_fd;
+ m_openFlags = rhs.m_openFlags;
m_modeFlags = rhs.m_modeFlags;
rhs.m_fd = -1;
diff --git a/source/fud_string.cpp b/source/fud_string.cpp
index 058c813..4a20630 100644
--- a/source/fud_string.cpp
+++ b/source/fud_string.cpp
@@ -52,9 +52,9 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator)
return StringResult::error(FudStatus::ArgumentInvalid);
}
- auto length = static_cast<size_t>(lenResult);
+ auto outputLength = static_cast<size_t>(lenResult);
if constexpr (static_cast<size_t>(std::numeric_limits<ssize_t>::max()) > maxStringLength) {
- if (length > maxStringLength) {
+ if (outputLength > maxStringLength) {
return StringResult::error(FudStatus::ArgumentInvalid);
}
}
@@ -62,30 +62,21 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator)
String output{};
output.m_allocator = reinterpret_cast<uintptr_t>(allocator);
- utf8* data{nullptr};
- size_t capacity = length + 1;
- bool isLarge = capacity > SsoBufSize;
+ utf8* outputData{nullptr};
+ size_t outputCapacity = outputLength + 1;
+ bool isLarge = outputCapacity > SsoBufSize;
if (isLarge) {
- output.m_repr.large.capacity = capacity;
- output.m_repr.large.length = length;
- auto dataResult = output.allocator()->allocate(capacity);
- if (dataResult.isError()) {
- return StringResult::error(dataResult.getError());
+ auto status = output.makeLarge(outputCapacity, outputLength, outputData);
+ if (status != FudStatus::Success) {
+ return StringResult::error(status);
}
- output.m_repr.large.data = static_cast<utf8*>(dataResult.getOkay());
- data = output.m_repr.large.data;
- output.setLarge();
} else {
- capacity = SsoBufSize;
- static_assert(SsoBufSize < std::numeric_limits<int8_t>::max());
- output.m_repr.small.length = length & smallStringLengthMask;
- data = output.m_repr.small.buffer.data();
- output.setSmall();
+ output.makeSmall(outputCapacity, outputLength, outputData);
}
- fudAssert(data != nullptr);
+ fudAssert(outputData != nullptr);
- auto copyStatus = copyMem(data, capacity, cString, length);
+ auto copyStatus = copyMem(outputData, outputCapacity, cString, outputLength);
fudAssert(copyStatus == FudStatus::Success);
auto terminateStatus = output.nullTerminate();
@@ -102,25 +93,20 @@ StringResult String::from(const String& rhs)
String output{};
output.m_allocator = rhs.m_allocator;
- utf8* data{nullptr};
- size_t capacity{0};
- size_t length{0};
+ utf8* outputData{nullptr};
+ size_t outputCapacity{0};
+ size_t outputLength{0};
if (rhs.isLarge()) {
- output.m_repr.large = rhs.m_repr.large;
- output.m_repr.large.data = static_cast<utf8*>(
- M_TakeOrReturn(StringResult, output.allocator()->allocate(output.m_repr.large.capacity)));
- data = output.m_repr.large.data;
- capacity = output.m_repr.large.capacity;
- length = output.m_repr.large.length;
+ auto status = output.makeLarge(outputCapacity, outputLength, outputData);
+ if (status != FudStatus::Success) {
+ return StringResult::error(status);
+ }
} else {
- output.m_repr.small = rhs.m_repr.small;
- data = output.m_repr.small.buffer.data();
- capacity = SsoBufSize;
- length = output.m_repr.small.length;
+ output.makeSmall(outputCapacity, outputLength, outputData);
}
- fudAssert(data != nullptr);
+ fudAssert(outputData != nullptr);
- auto copyResult = copyMem(output.dataMut(), capacity, rhs.data(), length);
+ auto copyResult = copyMem(output.dataMut(), outputCapacity, rhs.data(), outputLength);
fudAssert(copyResult == FudStatus::Success);
auto nullTerminateStatus = output.nullTerminate();
@@ -193,28 +179,29 @@ FudStatus String::copy(const String& rhs)
m_allocator = rhs.m_allocator;
m_repr = rhs.m_repr;
- utf8* data{nullptr};
- size_t capacity{};
- size_t length{};
+ utf8* outputData{nullptr};
+ size_t outputCapacity{};
+ size_t outputLength{};
if (isLarge()) {
auto allocResult = allocator()->allocate(m_repr.large.capacity);
if (allocResult.isError()) {
return allocResult.takeError();
}
- m_repr.large.data = static_cast<utf8*>(allocResult.takeOkay());
- capacity = m_repr.large.capacity;
- length = m_repr.large.length;
- data = m_repr.large.data;
+ m_repr.large.data = reinterpret_cast<utf8*>(allocResult.takeOkay());
+ outputCapacity = m_repr.large.capacity;
+ outputLength = m_repr.large.length;
+ outputData = m_repr.large.data;
+
} else {
- capacity = SsoBufSize;
- length = m_repr.small.length;
- data = m_repr.small.buffer.data();
+ outputCapacity = SsoBufSize;
+ outputLength = m_repr.small.length;
+ outputData = m_repr.small.buffer.data();
}
- fudAssert(data != nullptr);
+ fudAssert(outputData != nullptr);
- auto copyResult = copyMem(dataMut(), capacity, rhs.data(), length);
+ auto copyResult = copyMem(dataMut(), outputCapacity, rhs.data(), outputLength);
fudAssert(copyResult == FudStatus::Success);
auto nullTerminateStatus = nullTerminate();
fudAssert(nullTerminateStatus == FudStatus::Success);
@@ -243,7 +230,7 @@ void String::cleanup()
{
const auto* allocPtr = allocator();
if (isLarge() && m_repr.large.data != nullptr && allocPtr != nullptr) {
- auto deallocStatus = allocator()->deallocate(m_repr.large.data, m_repr.large.capacity);
+ auto deallocStatus = allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity);
static_cast<void>(deallocStatus);
m_repr.large.data = nullptr;
}
@@ -271,7 +258,7 @@ FudStatus String::resize(size_t newCapacity)
auto copyResult = copyMem(dataMut(), temp.size(), temp.data(), len);
fudAssert(copyResult == FudStatus::Success);
- auto deallocStatus = allocator()->deallocate(m_repr.large.data, m_repr.large.capacity);
+ auto deallocStatus = allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity);
setSmall();
m_repr.small.length = len & smallStringLengthMask;
copyMem(m_repr.small.buffer, temp);
@@ -284,7 +271,7 @@ FudStatus String::resize(size_t newCapacity)
if (allocResult.isError()) {
return allocResult.takeError();
}
- auto* newData = static_cast<utf8*>(allocResult.takeOkay());
+ auto* newData = reinterpret_cast<utf8*>(allocResult.takeOkay());
fudAssert(newData != nullptr);
auto copyResult = copyMem(newData, newCapacity, data(), length());
@@ -292,7 +279,7 @@ FudStatus String::resize(size_t newCapacity)
auto deallocStatus = FudStatus::Success;
if (isLarge()) {
- deallocStatus = allocator()->deallocate(dataMut(), m_repr.large.capacity);
+ deallocStatus = allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity);
}
size_t len = length();
@@ -569,7 +556,7 @@ DrainResult String::drain(StringView source)
auto status = copyMem(destPtr, remainingLength(), firstPart.m_data, firstPart.m_length);
fudAssert(status == FudStatus::Success);
addToLength(firstPart.m_length);
- result.bytesWritten += firstPart.m_length;
+ result.bytesDrained += firstPart.m_length;
status = nullTerminate();
source.advanceUnsafe(firstPart.m_length);
fudAssert(status == FudStatus::Success);
@@ -603,7 +590,7 @@ DrainResult String::drain(StringView source)
auto* destPtr = dataMut() + length();
result.status = copyMem(destPtr, remainingLength(), source.data(), source.length());
fudAssert(result.status == FudStatus::Success);
- result.bytesWritten += source.length();
+ result.bytesDrained += source.length();
setLength(newLength);
result.status = nullTerminate();
@@ -767,7 +754,7 @@ FudStatus String::makeLarge(size_t cap, size_t len, utf8*& outputData)
if (dataResult.isError()) {
return dataResult.getError();
}
- m_repr.large.data = static_cast<utf8*>(dataResult.getOkay());
+ m_repr.large.data = reinterpret_cast<utf8*>(dataResult.getOkay());
outputData = m_repr.large.data;
setLarge();
return FudStatus::Success;
diff --git a/test/test_allocator.cpp b/test/test_allocator.cpp
index d93df1e..6382463 100644
--- a/test/test_allocator.cpp
+++ b/test/test_allocator.cpp
@@ -23,7 +23,7 @@
namespace fud {
struct FailAllocator : public MockFudAlloc {
- virtual void* operator()(size_t size) override {
+ virtual std::byte* operator()(size_t size) override {
static_cast<void>(size);
return nullptr;
}
diff --git a/test/test_common.cpp b/test/test_common.cpp
index 784cb0d..778b4b5 100644
--- a/test/test_common.cpp
+++ b/test/test_common.cpp
@@ -25,12 +25,12 @@
namespace fud {
-void* MockFudAlloc::operator()(size_t size)
+std::byte* MockFudAlloc::operator()(size_t size)
{
- return malloc(size);
+ return static_cast<std::byte*>(malloc(size));
}
-void MockFudDealloc::operator()(void* pointer)
+void MockFudDealloc::operator()(std::byte* pointer)
{
return free(pointer);
}
@@ -39,24 +39,24 @@ MockFudAlloc globalDefaultMockAlloc{};
MockFudDealloc globalDefaultMockDealloc{};
-void* MockFudAllocator::allocate(size_t size)
+std::byte* MockFudAllocator::allocate(size_t size)
{
return (*m_allocator)(size);
}
-void MockFudAllocator::deallocate(void* pointer)
+void MockFudAllocator::deallocate(std::byte* pointer)
{
return (*m_deallocator)(pointer);
}
MockFudAllocator globalMockFudAlloc{};
-void* fudAlloc(size_t size)
+std::byte* fudAlloc(size_t size)
{
return globalMockFudAlloc.allocate(size);
}
-void fudFree(void* ptr)
+void fudFree(std::byte* ptr)
{
return globalMockFudAlloc.deallocate(ptr);
}
diff --git a/test/test_common.hpp b/test/test_common.hpp
index fd16364..8912e42 100644
--- a/test/test_common.hpp
+++ b/test/test_common.hpp
@@ -57,23 +57,22 @@ static_assert(sizeof(FOUR_BYTE) == 4 + 1);
#define CHARACTER_SET LOWERCASE_CHARS u8" " UPPERCASE_CHARS
// NOLINTEND(cppcoreguidelines-macro-usage)
-constexpr size_t charSetSize = sizeof(CHARACTER_SET) - 1;
struct MockFudAlloc {
- virtual void* operator()(size_t size);
+ virtual std::byte* operator()(size_t size);
};
extern MockFudAlloc globalDefaultMockAlloc;
struct MockFudDealloc {
- virtual void operator()(void* pointer);
+ virtual void operator()(std::byte* pointer);
};
extern MockFudDealloc globalDefaultMockDealloc;
struct MockFudAllocator {
- void* allocate(size_t size);
- void deallocate(void* pointer);
+ std::byte* allocate(size_t size);
+ void deallocate(std::byte* pointer);
MockFudAlloc* m_allocator{&globalDefaultMockAlloc};
MockFudDealloc* m_deallocator{&globalDefaultMockDealloc};
diff --git a/test/test_directory.cpp b/test/test_directory.cpp
index ba1c0e1..96b9c2d 100644
--- a/test/test_directory.cpp
+++ b/test/test_directory.cpp
@@ -60,9 +60,9 @@ TEST(FudDirectory, Basic)
CBinaryFile file{std::move(fileResult).takeOkay()};
ASSERT_EQ(file.open(), FudStatus::Success);
Array<utf8, 5> data{u8"test"};
- WriteResult expected{data.size(), FudStatus::Success};
+ DrainResult expected{data.size(), FudStatus::Success};
auto writeResult = file.write(data);
- ASSERT_EQ(writeResult.bytesWritten, expected.bytesWritten);
+ ASSERT_EQ(writeResult.bytesDrained, expected.bytesDrained);
ASSERT_EQ(writeResult.status, expected.status);
}
diff --git a/test/test_string.cpp b/test/test_string.cpp
index 9f5b24e..6bcbd37 100644
--- a/test/test_string.cpp
+++ b/test/test_string.cpp
@@ -25,7 +25,7 @@ namespace fud {
TEST(FudString, CStringLength)
{
- const char* nullPointer = nullPointer;
+ const char* nullPointer{nullptr};
ASSERT_EQ(cStringLength(nullPointer), -1);
ASSERT_EQ(cStringLength(""), 0);
ASSERT_EQ(cStringLength("a"), 1);
diff --git a/test/test_utf8.cpp b/test/test_utf8.cpp
index 591d1a3..69a1643 100644
--- a/test/test_utf8.cpp
+++ b/test/test_utf8.cpp
@@ -127,17 +127,17 @@ TEST(Utf8Test, Utf8MultiByte)
constexpr size_t bufSize = data.size();
EXPECT_EQ(data[bufSize - 1], '\0');
- class FixedAllocator final : public Allocator {
+ class FixedAllocator : public Allocator {
private:
- Array<utf8, bufSize> m_memory{};
+ Array<std::byte, bufSize> m_memory{};
size_t m_allocated{0};
public:
- virtual ~FixedAllocator() override final = default;
+ virtual ~FixedAllocator() override = default;
- virtual Result<void*, FudStatus> allocate(size_t bytes, size_t alignment) override final
+ virtual Result<std::byte*, FudStatus> allocate(size_t bytes, size_t alignment) override final
{
- using RetType = Result<void*, FudStatus>;
+ using RetType = Result<std::byte*, FudStatus>;
static_cast<void>(alignment);
if (bytes > m_memory.size() - m_allocated) {
return RetType::error(FudStatus::AllocFailure);
@@ -147,7 +147,7 @@ TEST(Utf8Test, Utf8MultiByte)
return RetType::okay(data);
}
- virtual FudStatus deallocate(void* pointer, size_t bytes) override final
+ virtual FudStatus deallocate(std::byte* pointer, size_t bytes) override final
{
static_cast<void>(pointer);
static_cast<void>(bytes);