summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/fud_allocator.hpp6
-rw-r--r--include/fud_c_string.hpp15
-rw-r--r--include/fud_file.hpp11
-rw-r--r--include/fud_string.hpp32
-rw-r--r--include/fud_vector.hpp35
5 files changed, 67 insertions, 32 deletions
diff --git a/include/fud_allocator.hpp b/include/fud_allocator.hpp
index e4078ac..9b90deb 100644
--- a/include/fud_allocator.hpp
+++ b/include/fud_allocator.hpp
@@ -32,7 +32,7 @@ class alignas(std::max_align_t) Allocator {
virtual Result<std::byte*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) = 0;
- virtual FudStatus deallocate(std::byte* pointer, size_t bytes) = 0;
+ virtual void deallocate(std::byte* pointer, size_t bytes) = 0;
virtual bool isEqual(const Allocator& rhs) const = 0;
};
@@ -48,7 +48,7 @@ class FudAllocator : public Allocator {
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 void deallocate(std::byte* pointer, size_t bytes) override;
virtual bool isEqual(const Allocator& rhs) const override;
};
@@ -61,7 +61,7 @@ class NullAllocator : public Allocator {
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 void deallocate(std::byte* pointer, size_t bytes) override;
virtual bool isEqual(const Allocator& rhs) const override;
};
diff --git a/include/fud_c_string.hpp b/include/fud_c_string.hpp
index d55ba30..a1ab51a 100644
--- a/include/fud_c_string.hpp
+++ b/include/fud_c_string.hpp
@@ -20,14 +20,17 @@
#include <climits>
#include <cstddef>
+#include <limits>
#include <sys/types.h>
namespace fud {
+constexpr ssize_t MAX_C_STRING_LENGTH = std::numeric_limits<ssize_t>::max() - 1;
+
constexpr ssize_t cStringLength(const char* str, size_t maxLength)
{
- if (str == nullptr || maxLength > (SSIZE_MAX - 1)) {
+ if (str == nullptr || maxLength > MAX_C_STRING_LENGTH) {
return -1;
}
@@ -46,13 +49,14 @@ constexpr ssize_t cStringLength(const char* str, size_t maxLength)
constexpr ssize_t cStringLength(const char* str)
{
- constexpr auto maxLength = SSIZE_MAX - 1;
- return cStringLength(str, maxLength);
+ return cStringLength(str, MAX_C_STRING_LENGTH);
}
constexpr ssize_t cStringLength(const char8_t* str, size_t maxLength)
{
- if (str == nullptr || maxLength > (SSIZE_MAX - 1)) {
+ // Cannot cast str to const char* without breaking constexpr
+ // return cStringLength(reinterpret_cast<const char*>(str), maxLength);
+ if (str == nullptr || maxLength > MAX_C_STRING_LENGTH) {
return -1;
}
@@ -71,8 +75,7 @@ constexpr ssize_t cStringLength(const char8_t* str, size_t maxLength)
constexpr ssize_t cStringLength(const char8_t* str)
{
- constexpr auto maxLength = SSIZE_MAX - 1;
- return cStringLength(str, maxLength);
+ return cStringLength(str, MAX_C_STRING_LENGTH);
}
} // namespace fud
diff --git a/include/fud_file.hpp b/include/fud_file.hpp
index 51826a6..7a53468 100644
--- a/include/fud_file.hpp
+++ b/include/fud_file.hpp
@@ -165,10 +165,17 @@ class RegularFile {
FileAccessMode m_modeFlags{};
};
+enum class ReadPolicy {
+ Unbuffered,
+ ReadAhead,
+};
+
class BufferedRegularFile {
public:
- DrainResult write(const void* source, size_t sourceSize, size_t length, size_t offset);
- // DrainResult read(void* sink, );
+ /** \brief Write from source to file as sink. */
+ DrainResult write(const std::byte* source, size_t sourceSize, size_t length, size_t offset);
+ /** \brief Read from file as source to sink. */
+ DrainResult read(std::byte* sink, size_t sinkSize, size_t length, size_t offset);
private:
Vector<std::byte> m_readBuffer{Vector<std::byte>::NullVector()};
Vector<std::byte> m_writeBuffer{Vector<std::byte>::NullVector()};
diff --git a/include/fud_string.hpp b/include/fud_string.hpp
index 226bb89..59c434a 100644
--- a/include/fud_string.hpp
+++ b/include/fud_string.hpp
@@ -60,6 +60,8 @@ class String {
* \returns FudStatus::AllocFailure if the allocator fails.
*/
static StringResult makeFromCString(const char* cString);
+
+ /** @copydoc String::makeFromCString(const char* cString) */
static StringResult makeFromCString(const char8_t* cString);
/** \brief Create a string from a C String, specifying the allocator.
@@ -74,6 +76,8 @@ class String {
* \returns FudStatus::AllocFailure if the allocator fails.
*/
static StringResult makeFromCString(const char* cString, Allocator* allocator);
+
+ /** @copydoc String::makeFromCString(const char* cString, Allocator* allocator) */
static StringResult makeFromCString(const char8_t* cString, Allocator* allocator);
/** \brief Create a string from concatenating multiple C Strings.
@@ -187,20 +191,33 @@ class String {
* fud allocator. */
String() noexcept = default;
+ /* The copy constructor is deleted because it is fallible. */
String(const String& rhs) = delete;
+ /** \brief Infallibly moves the string. */
String(String&& rhs) noexcept;
- ~String();
+ /* Destructors need no documentation. */
+ ~String() noexcept;
+ /* The copy assignment operator not deleted because it is fallible. */
String& operator=(const String& rhs) = delete;
+ /** \brief Takes ownership of rhs, destroying the contents of this string in
+ * the process. The allocator is taken from rhs.
+ */
String& operator=(String&& rhs) noexcept;
- static StringResult from(const String& rhs);
+ /** \brief Create a String by copying from an existing rhs, optionally
+ * specifying a different allocator. If allocatorOption is NullOpt, the
+ * allocator from rhs is used.
+ */
+ static StringResult from(const String& rhs, Option<Allocator*> allocatorOption = NullOpt);
+ /** \brief Create a String by copying from a view, with the specified allocator. */
static StringResult from(StringView view, Allocator* allocator = &globalFudAllocator);
+ /** \brief Copy the contents of rhs, without modifying rhs. */
FudStatus copy(const String& rhs);
/** \brief The raw length of the string's data, excluding the null terminator. */
@@ -246,12 +263,19 @@ class String {
return reinterpret_cast<const char*>(data());
}
+ /** \brief Indicates if the contents of the string form a valid sequence of
+ * UTF8 code points. */
[[nodiscard]] bool utf8Valid() const;
+ /** \brief Attempts to reserve newCapacity bytes of storage. */
FudStatus reserve(size_t newCapacity);
+ /** \brief Returns the last character in the sequence if the length is
+ * greater than zero. */
[[nodiscard]] Option<utf8> back();
+ /** \brief Returns the remaining capacity for characters excluding the null
+ * terminating byte. */
[[nodiscard]] size_t remainingLength() const
{
if (length() > capacity()) {
@@ -312,7 +336,9 @@ class String {
Allocator* allocator() const
{
- return reinterpret_cast<Allocator*>(m_allocator & allocatorMask);
+ auto* allocPtr = reinterpret_cast<Allocator*>(m_allocator & allocatorMask);
+ fudAssert(allocPtr != nullptr);
+ return allocPtr;
}
[[nodiscard]] bool nullTerminated() const;
diff --git a/include/fud_vector.hpp b/include/fud_vector.hpp
index 52876fd..53b2625 100644
--- a/include/fud_vector.hpp
+++ b/include/fud_vector.hpp
@@ -39,6 +39,7 @@ class Vector {
public:
constexpr Vector() noexcept = default;
+ constexpr explicit Vector(Allocator& allocator) noexcept : m_allocator{&allocator} {}
constexpr Vector(const Vector<T>& rhs) = delete;
constexpr Vector(Vector<T>&& rhs) noexcept :
m_allocator(rhs.m_allocator), m_data(rhs.m_data), m_length{rhs.m_length}, m_capacity{rhs.m_capacity}
@@ -121,12 +122,12 @@ class Vector {
Vector<T> output{};
auto status = initializeWithCapacity(output, count, allocator);
if (status != FudStatus::Success) {
- return status;
+ return FudError{status};
}
- return output;
+ return Okay<Vector<T>>{std::move(output)};
}
- static Result<Vector<T>, FudStatus> initializeWithSize(
+ static FudStatus initializeWithSize(
Vector<T>& output,
size_t count,
Allocator* allocator = &globalFudAllocator)
@@ -145,7 +146,8 @@ class Vector {
const auto* ptr = new (output.m_data + index) T();
fudAssert(ptr != nullptr);
}
- return output;
+
+ return FudStatus::Success;
}
template <typename Builder>
@@ -157,20 +159,20 @@ class Vector {
Vector<T> output{};
auto status = initializeWithSizeFallible(output, count, std::forward<Builder>(builder), allocator);
if (status != FudStatus::Success) {
- return status;
+ return FudError{status};
}
- return output;
+ return Okay<Vector<T>>{std::move(output)};
}
template <typename Builder>
- static Result<Vector<T>, FudStatus> initializeWithSizeFallible(
+ static FudStatus initializeWithSizeFallible(
Vector<T>& output,
size_t count,
Builder&& builder,
Allocator* allocator = &globalFudAllocator)
{
- using BuilderResult = decltype(std::forward<Builder>(builder)());
- static_assert(std::is_same_v<BuilderResult, FudStatus>());
+ // using BuilderResult = decltype(std::forward<Builder>(builder)(T{}));
+ // static_assert(std::is_same_v<BuilderResult, FudStatus>);
auto status = Vector::initializeWithCapacity(output, count, allocator);
if (status != FudStatus::Success) {
@@ -180,13 +182,13 @@ class Vector {
output.m_length = count;
for (size_t index = 0; index < count; ++index) {
- auto builderResult{std::forward<Builder>(builder)(output.m_data[index])};
- if (builderResult.isError()) {
- return builderResult.takeError();
+ auto builderStatus{std::forward<Builder>(builder)(output.m_data[index])};
+ if (builderStatus != FudStatus::Success) {
+ return builderStatus;
}
}
- return output;
+ return FudStatus::Success;
}
static Result<Vector<T>, FudStatus> from(const Vector<T>& rhs, Option<Allocator*> allocatorOption = NullOpt)
@@ -356,7 +358,7 @@ class Vector {
auto status = FudStatus::Success;
if (m_capacity > 0) {
- status = m_allocator->deallocate(reinterpret_cast<std::byte*>(m_data), m_capacity);
+ m_allocator->deallocate(reinterpret_cast<std::byte*>(m_data), m_capacity);
}
m_data = dataPtr;
@@ -672,10 +674,7 @@ class Vector {
auto status = clear();
if (m_data != nullptr && m_allocator != nullptr) {
- auto deallocStatus = m_allocator->deallocate(reinterpret_cast<std::byte*>(m_data), m_capacity);
- if (status == FudStatus::Success) {
- status = deallocStatus;
- }
+ m_allocator->deallocate(reinterpret_cast<std::byte*>(m_data), m_capacity);
}
m_allocator = nullptr;