From 6c7fd1db481ff10a16ecab958c6542784fa60b9c Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Wed, 30 Oct 2024 09:51:54 -0500 Subject: Use std::byte* instead of void* for allocators. --- include/fud_allocator.hpp | 25 ++++++++++++----- include/fud_c_file.hpp | 40 ++++++++++++++-------------- include/fud_drain.hpp | 12 ++++++++- include/fud_file.hpp | 68 +++++++++++++++++++++++++++-------------------- include/fud_format.hpp | 61 +++++++++++++++++++----------------------- include/fud_vector.hpp | 14 +++++++--- 6 files changed, 126 insertions(+), 94 deletions(-) (limited to 'include') 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 allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) = 0; + virtual Result 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 allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) override; + virtual Result 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 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 #include @@ -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(*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(*this); - ReadResult result{}; + DrainResult result{}; if (length == 0) { return result; } @@ -227,9 +227,9 @@ class CFile { } auto* destBytes = static_cast(destination); - result.bytesRead = fread(destBytes, 1, length, self.m_file); + result.bytesDrained = fread(destBytes, 1, length, self.m_file); static_cast(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 - [[nodiscard]] ReadResult read(T& destination, size_t length) + [[nodiscard]] DrainResult read(T& destination, size_t length) { static_assert(not std::is_pointer_v); auto& self = static_cast(*this); @@ -247,39 +247,39 @@ class CFile { } template - [[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); auto& self = static_cast(*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(*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(*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(*this); - WriteResult result{}; + DrainResult result{}; if (length == 0) { return result; } @@ -315,9 +315,9 @@ class CFile { } const auto* sourceBytes = static_cast(source); - result.bytesWritten = fwrite(sourceBytes, 1, length, self.m_file); + result.bytesDrained = fwrite(sourceBytes, 1, length, self.m_file); static_cast(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 - [[nodiscard]] WriteResult write(const T& source) + [[nodiscard]] DrainResult write(const T& source) { static_assert(not std::is_pointer_v); auto& self = static_cast(*this); @@ -335,19 +335,19 @@ class CFile { } template - [[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); auto& self = static_cast(*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 - [[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); auto& self = static_cast(*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 +concept Drainable = requires (Sink sink, Source source) +{ + { sink.drain(source) } -> std::same_as; }; } // 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 @@ -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(hasFlag(OpenFlagEnum::Append)) * O_APPEND; + openFlags |= static_cast(hasFlag(OpenFlagEnum::Truncate)) * O_TRUNC; + openFlags |= static_cast(hasFlag(OpenFlagEnum::CloseOnExec)) * O_CLOEXEC; + openFlags |= static_cast(hasFlag(OpenFlagEnum::DataSync)) * O_DSYNC; + openFlags |= static_cast(hasFlag(OpenFlagEnum::Direct)) * O_DIRECT; + openFlags |= static_cast(hasFlag(OpenFlagEnum::NoAtime)) * O_NOATIME; + openFlags |= static_cast(hasFlag(OpenFlagEnum::NonBlock)) * O_NONBLOCK; + openFlags |= static_cast(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(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; @@ -129,8 +129,7 @@ class RegularFile { StringView filename, FileAccessMode mode, OpenFlags flags, - Option dirFdoption, - Allocator* allocator = &globalFudAllocator); + Option dirFdoption); static FileResult create( StringView filename, @@ -138,8 +137,7 @@ class RegularFile { OpenFlags flags, Permissions permissions, bool exclusive, - Option dirFdOption, - Allocator* allocator = &globalFudAllocator); + Option 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 m_readBuffer{Vector::NullVector()}; + Vector m_writeBuffer{Vector::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 +template requires Drainable FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt); -template +template requires Drainable FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Args&&... args); template @@ -341,7 +335,7 @@ size_t findSpec(StringView scanView); } // namespace impl -template +template requires Drainable FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Args&&... args) { static_cast(sink); @@ -355,7 +349,7 @@ FormatResult format(Sink& sink, FormatCharMode formatMode, FormatString fmt, Arg return impl::vFormat(sink, formatMode, fmt, formatArguments); } -template +template requires Drainable 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(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 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 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 NullVector() noexcept { + Vector output{}; + output.m_allocator = &globalNullAllocator; + return output; + } + static Result, FudStatus> withCapacity(size_t capacity, Allocator* allocator = &globalFudAllocator) { Vector output{}; @@ -104,7 +110,7 @@ class Vector { } output.m_allocator = allocator; - output.m_data = static_cast(dataPtrResult.getOkay()); + output.m_data = reinterpret_cast(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(dataPtrResult.takeOkay()); + auto* dataPtr = reinterpret_cast(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(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(m_data), m_capacity); if (status == FudStatus::Success) { status = deallocStatus; } -- cgit v1.2.3