diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/fud_allocator.hpp | 11 | ||||
-rw-r--r-- | include/fud_assert.hpp | 13 | ||||
-rw-r--r-- | include/fud_c_file.hpp | 6 | ||||
-rw-r--r-- | include/fud_result.hpp | 55 | ||||
-rw-r--r-- | include/fud_span.hpp | 120 | ||||
-rw-r--r-- | include/fud_status.hpp | 9 | ||||
-rw-r--r-- | include/fud_string.hpp | 3 | ||||
-rw-r--r-- | include/libfud.hpp | 8 |
8 files changed, 186 insertions, 39 deletions
diff --git a/include/fud_allocator.hpp b/include/fud_allocator.hpp index 8955fae..a9fbd67 100644 --- a/include/fud_allocator.hpp +++ b/include/fud_allocator.hpp @@ -32,8 +32,7 @@ class Allocator { virtual Result<void*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) = 0; - /* ...should this be void? */ - virtual void deallocate(void* pointer, size_t bytes, size_t alignment = alignof(std::max_align_t)) = 0; + virtual FudStatus deallocate(void* pointer, size_t bytes) = 0; virtual bool isEqual(const Allocator& rhs) const = 0; }; @@ -48,8 +47,7 @@ class FudAllocator : public Allocator { virtual Result<void*, FudStatus> allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)) override; - /* ...should this be void? */ - virtual void deallocate(void* pointer, size_t bytes, size_t alignment = alignof(std::max_align_t)) override; + virtual FudStatus deallocate(void* pointer, size_t bytes) override; virtual bool isEqual(const Allocator& rhs) const override; }; @@ -59,12 +57,9 @@ extern FudAllocator globalFudAllocator; /** \brief The default allocation function for globalFudAllocator. */ extern void* fudAlloc(size_t size); -/** \brief The default allocation function for globalFudAllocator. */ -extern void* fudRealloc(void* ptr, size_t size); - +/** \brief The default deallocation function for globalFudAllocator. */ extern void fudFree(void* ptr); - } // namespace fud #endif diff --git a/include/fud_assert.hpp b/include/fud_assert.hpp index 6b21fdc..ecfaa2f 100644 --- a/include/fud_assert.hpp +++ b/include/fud_assert.hpp @@ -22,9 +22,22 @@ // #include <stacktrace> #include <source_location> +#include "fud_span.hpp" namespace fud { +constexpr std::size_t MAX_FILE_CHARS = 256; +constexpr std::size_t MAX_FUNCTION_CHARS = 256; +constexpr std::size_t BITS_PER_OCTAL = 3; +constexpr auto MAX_LINE_CHARS = BITS_PER_OCTAL * sizeof(decltype(std::source_location{}.line())) + 3; +constexpr std::size_t MAX_ASSERT_CHARS = 512 - MAX_LINE_CHARS; +constexpr std::size_t ASSERT_MSG_SIZE = MAX_FILE_CHARS + MAX_LINE_CHARS + MAX_FUNCTION_CHARS + MAX_ASSERT_CHARS; + +void assertFormat( + const char* assertion, + std::source_location sourceLocation, + Span<char, ASSERT_MSG_SIZE> buffer); + [[noreturn]] void assertFail( const char* assertion, std::source_location sourceLocation = std::source_location::current()); diff --git a/include/fud_c_file.hpp b/include/fud_c_file.hpp index 4905643..b54b044 100644 --- a/include/fud_c_file.hpp +++ b/include/fud_c_file.hpp @@ -220,7 +220,7 @@ class CFile { } if (offset > LONG_MAX || SIZE_MAX - offset < length || destinationSize < length) { - result.status = FudStatus::InvalidInput; + result.status = FudStatus::ArgumentInvalid; return result; } @@ -232,7 +232,7 @@ class CFile { auto fileSize = fileSizeResult.getOkay(); if (offset + length > fileSize) { - result.status = FudStatus::InvalidInput; + result.status = FudStatus::ArgumentInvalid; return result; } @@ -306,7 +306,7 @@ class CFile { } if (offset > LONG_MAX || SIZE_MAX - offset < length || sourceSize < length) { - result.status = FudStatus::InvalidInput; + result.status = FudStatus::ArgumentInvalid; return result; } diff --git a/include/fud_result.hpp b/include/fud_result.hpp index 5dabaf5..4bfb819 100644 --- a/include/fud_result.hpp +++ b/include/fud_result.hpp @@ -28,6 +28,22 @@ class [[nodiscard]] Result { public: using ResultType = Result<T, E>; + Result(const T& value) : m_value{value} + { + } + + Result(const E& value) : m_value{value} + { + } + + Result(T&& value) : m_value{std::move(value)} + { + } + + Result(E&& value) : m_value{std::move(value)} + { + } + static ResultType okay(const T& okay) { return ResultType{okay}; @@ -49,22 +65,26 @@ class [[nodiscard]] Result { } template <typename F> - static ResultType okay(const Result<T, F>& okayRes) { + static ResultType okay(const Result<T, F>& okayRes) + { return ResultType{okayRes.getOkay()}; } template <typename F> - static ResultType okay(Result<T, F>&& okayRes) { + static ResultType okay(Result<T, F>&& okayRes) + { return ResultType{okayRes.takeOkay()}; } template <typename U> - static ResultType error(const Result<U, E>& errorRes) { + static ResultType error(const Result<U, E>& errorRes) + { return ResultType{errorRes.getError()}; } template <typename U> - static ResultType error(Result<U, E>&& errorRes) { + static ResultType error(Result<U, E>&& errorRes) + { return ResultType{errorRes.takeError()}; } @@ -99,29 +119,22 @@ class [[nodiscard]] Result { } private: - explicit Result() : m_value() - { - } - - explicit Result(const T& value) : m_value{value} - { - } - - explicit Result(const E& value) : m_value{value} - { - } - - explicit Result(T&& value): m_value{std::move(value)} - { - } - - explicit Result(E&& value) : m_value{std::move(value)} + Result() : m_value() { } std::variant<T, E> m_value; }; +#define M_TakeOrReturn(HYGIENE_EXPRESSION) \ + ({ \ + auto HYGIENE_RESULT{(HYGIENE_EXPRESSION)}; \ + if (HYGIENE_RESULT.isError()) { \ + return HYGIENE_RESULT.takeError(); \ + } \ + HYGIENE_RESULT.takeOkay(); \ + }) + } // namespace fud #endif diff --git a/include/fud_span.hpp b/include/fud_span.hpp new file mode 100644 index 0000000..e8c5704 --- /dev/null +++ b/include/fud_span.hpp @@ -0,0 +1,120 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FUD_SPAN_HPP +#define FUD_SPAN_HPP + +#include <cstdlib> + +#include "fud_array.hpp" + +namespace fud { + +template <typename T, size_t Size> +struct Span { + static_assert(Size > 0); + using ValueType = T; + + static Span make(Array<T, Size>& array) { + Span<T, Size> output{}; + output.m_data = array.data(); + return output; + } + + template <typename U> + static Span make(const Array<U, Size>& array) { + static_assert(std::convertible_to<U, T>); + Span<T, Size> output{}; + output.m_data = array.data(); + return output; + } + + T* m_data; + + [[nodiscard]] constexpr size_t size() const + { + return Size; + } + + constexpr T& front() + { + return m_data[0]; + } + + constexpr const T& front() const + { + return m_data[0]; + } + + constexpr T& back() + { + return m_data[Size - 1]; + } + + constexpr const T& back() const + { + return m_data[Size - 1]; + } + + constexpr T* data() noexcept + { + return m_data; + } + + constexpr const T* data() const noexcept + { + return m_data; + } + + constexpr T* begin() noexcept + { + return m_data; + } + + constexpr const T* begin() const noexcept + { + return m_data; + } + + constexpr T* end() noexcept + { + return m_data + Size; + } + + constexpr const T* end() const noexcept + { + return m_data + Size; + } + + constexpr T& operator[](size_t index) + { + return m_data[index]; + } + + constexpr const T& operator[](size_t index) const + { + return m_data[index]; + } + + constexpr bool operator==(const Span<T, Size>&) const noexcept = default; + + constexpr auto operator<=>(const Span<T, Size>& other) const noexcept = default; +}; + +} // namespace fud + +#endif diff --git a/include/fud_status.hpp b/include/fud_status.hpp index 5ebf229..bda646b 100644 --- a/include/fud_status.hpp +++ b/include/fud_status.hpp @@ -28,7 +28,8 @@ enum class [[nodiscard]] FudStatus ObjectInvalid, OperationInvalid, AllocFailure, - InvalidInput, + DeallocFailure, + ArgumentInvalid, Utf8Invalid, Failure, NotFound, @@ -58,8 +59,10 @@ constexpr const char* FudStatusToString(FudStatus status) return "OperationInvalid"; case FudStatus::AllocFailure: return "AllocFailure"; - case FudStatus::InvalidInput: - return "InvalidInput"; + case FudStatus::DeallocFailure: + return "DeallocFailure"; + case FudStatus::ArgumentInvalid: + return "ArgumentInvalid"; case FudStatus::Utf8Invalid: return "Utf8Invalid"; case FudStatus::Failure: diff --git a/include/fud_string.hpp b/include/fud_string.hpp index 4367aae..ba05450 100644 --- a/include/fud_string.hpp +++ b/include/fud_string.hpp @@ -72,7 +72,7 @@ class String { auto lengthResult = cStringLength(cString); if (lengthResult < 0 || lengthResult >= SSIZE_MAX) { - return StringResult::error(FudStatus::InvalidInput); + return StringResult::error(FudStatus::ArgumentInvalid); } auto stringLength = static_cast<size_t>(lengthResult); if (SIZE_MAX - totalLength < stringLength) { @@ -89,6 +89,7 @@ class String { output.m_allocator = allocator; if (output.m_length >= output.m_capacity) { output.m_capacity = output.m_length + 1; + /* Avoid using compiler expansions in headers */ auto dataResult = output.m_allocator->allocate(output.m_capacity); if (dataResult.isError()) { return StringResult::error(dataResult.getError()); diff --git a/include/libfud.hpp b/include/libfud.hpp index 5bc1630..bff791d 100644 --- a/include/libfud.hpp +++ b/include/libfud.hpp @@ -19,6 +19,7 @@ #define LIBFUD_HPP #include "fud_array.hpp" +#include "fud_allocator.hpp" #include "fud_result.hpp" #include "fud_status.hpp" #include "fud_string.hpp" @@ -43,12 +44,13 @@ FUD fud(); * \brief Get an environmental variable if it exists. * * \param[in] name The name of the variable to look up. + * \param[in] allocator The allocator used by the string returned. * * \retstmt The value of the string bound to the variable if it exists. * \retcode FudStatus::NullPointer if name is a null pointer. * \retcode FudStatus::NotFound if no binding for the variable exists. */ -Result<String, FudStatus> getEnv(const char* name); +Result<String, FudStatus> getEnv(const char* name, Allocator* allocator= &globalFudAllocator); template <typename T> concept CStringRepr = requires(T strObj) { @@ -56,9 +58,9 @@ concept CStringRepr = requires(T strObj) { }; template <CStringRepr T> -Result<String, FudStatus> getEnv(const T& name) +Result<String, FudStatus> getEnv(const T& name, Allocator* allocator = &globalFudAllocator) { - return getEnv(name.c_str()); + return getEnv(name.c_str(), allocator); } } // namespace fud |