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 +++++-- source/fud_allocator.cpp | 29 +++++++++++++-- source/fud_assert.cpp | 4 +- source/fud_file.cpp | 20 ++++------ source/fud_string.cpp | 95 ++++++++++++++++++++--------------------------- test/test_allocator.cpp | 2 +- test/test_common.cpp | 14 +++---- test/test_common.hpp | 9 ++--- test/test_directory.cpp | 4 +- test/test_string.cpp | 2 +- test/test_utf8.cpp | 12 +++--- 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 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; } 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 FudAllocator::allocate(size_t bytes, size_t alignment) +Result FudAllocator::allocate(size_t bytes, size_t alignment) { - using RetType = Result; + using RetType = Result; static_cast(alignment); - auto* pointer = static_cast(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 NullAllocator::allocate(size_t bytes, size_t alignment) +{ + static_cast(bytes); + static_cast(alignment); + return FudError{FudStatus::Failure}; +} + +FudStatus NullAllocator::deallocate(std::byte* pointer, size_t bytes) +{ + static_cast(pointer); + static_cast(bytes); + return FudStatus::Failure; +} + +bool NullAllocator::isEqual(const Allocator& rhs) const +{ + return &rhs == static_cast(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(source.m_data), 1, source.m_length, stderr); - if (result.bytesWritten != source.m_length) { + result.bytesDrained = fwrite(reinterpret_cast(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 dirFdOption, - Allocator* allocator) + Option 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 dirFdOption, - Allocator* allocator) + Option 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(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(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(lenResult); + auto outputLength = static_cast(lenResult); if constexpr (static_cast(std::numeric_limits::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(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(dataResult.getOkay()); - data = output.m_repr.large.data; - output.setLarge(); } else { - capacity = SsoBufSize; - static_assert(SsoBufSize < std::numeric_limits::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( - 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(allocResult.takeOkay()); - capacity = m_repr.large.capacity; - length = m_repr.large.length; - data = m_repr.large.data; + m_repr.large.data = reinterpret_cast(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(m_repr.large.data), m_repr.large.capacity); static_cast(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(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(allocResult.takeOkay()); + auto* newData = reinterpret_cast(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(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(dataResult.getOkay()); + m_repr.large.data = reinterpret_cast(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(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(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 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 m_memory{}; + Array m_memory{}; size_t m_allocated{0}; public: - virtual ~FixedAllocator() override final = default; + virtual ~FixedAllocator() override = default; - virtual Result allocate(size_t bytes, size_t alignment) override final + virtual Result allocate(size_t bytes, size_t alignment) override final { - using RetType = Result; + using RetType = Result; static_cast(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(pointer); static_cast(bytes); -- cgit v1.2.3