From 0b400af9519444deef4cc6ad2c43c30e2092ab4f Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Sat, 4 Jan 2025 09:56:12 -0600 Subject: Fix bug related to string copying. --- include/fud_directory.hpp | 4 ++-- include/fud_option.hpp | 17 +++++++++++++---- include/fud_sqlite.hpp | 11 ++++++----- include/fud_string_convert.hpp | 4 ++++ include/fud_string_view.hpp | 11 ++++++++++- include/libfud.hpp | 7 ++++--- 6 files changed, 39 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/fud_directory.hpp b/include/fud_directory.hpp index e935950..d7f6b1f 100644 --- a/include/fud_directory.hpp +++ b/include/fud_directory.hpp @@ -99,11 +99,11 @@ class Directory { Directory& operator=(const Directory& rhs) = delete; Directory& operator=(Directory&& rhs) noexcept = delete; - constexpr const String& name() const { + [[nodiscard]] constexpr const String& name() const { return m_name; } - constexpr int errorCode() const + [[nodiscard]] constexpr int errorCode() const { return m_errorCode; } diff --git a/include/fud_option.hpp b/include/fud_option.hpp index 3c94eaa..9d3068c 100644 --- a/include/fud_option.hpp +++ b/include/fud_option.hpp @@ -75,10 +75,11 @@ class Option { private: static_assert(!std::is_same_v); static constexpr bool IsRef = std::is_reference_v; - using ValueType = typename std::remove_reference::type; - static constexpr size_t Size = IsRef ? sizeof(std::reference_wrapper) : sizeof(ValueType); public: + using ValueType = std::remove_reference_t; + static constexpr size_t Size = IsRef ? sizeof(std::reference_wrapper) : sizeof(ValueType); + constexpr Option() noexcept : m_engaged{false} { } @@ -100,6 +101,7 @@ class Option { constexpr static Option take(T&& value) noexcept { Option option{}; + option.m_engaged = true; if constexpr (IsRef) { new (option.m_data.data()) std::reference_wrapper(std::ref(value)); } else { @@ -152,7 +154,8 @@ class Option { return !m_engaged; } - operator bool() const { + operator bool() const + { return hasValue(); } @@ -160,8 +163,10 @@ class Option { { fudAssert(m_engaged); if constexpr (IsRef) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast*>(m_data.data()); } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast(m_data.data()); } } @@ -170,8 +175,10 @@ class Option { { fudAssert(m_engaged); if constexpr (IsRef) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast*>(m_data.data()); } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return *reinterpret_cast(m_data.data()); } } @@ -180,6 +187,7 @@ class Option { { fudAssert(m_engaged); static_assert(!IsRef); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return std::move(*reinterpret_cast(m_data.data())); } @@ -200,7 +208,7 @@ class Option { } template - constexpr auto map(F&& func) const & -> Option(func)(value()))> + constexpr auto map(F&& func) const& -> Option(func)(value()))> { using U = decltype(std::forward(func)(value())); // static_assert(std::is_same_v(func)(value())), Option>()); @@ -217,6 +225,7 @@ class Option { if constexpr (IsRef) { // reinterpret_cast*>(m_data.data()); } else { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) reinterpret_cast(m_data.data())->~ValueType(); } cleanup(); diff --git a/include/fud_sqlite.hpp b/include/fud_sqlite.hpp index c56b4a1..b2d2f5b 100644 --- a/include/fud_sqlite.hpp +++ b/include/fud_sqlite.hpp @@ -28,6 +28,7 @@ namespace fud { class SqliteStatement; +// NOLINTNEXTLINE(performance-enum-size) enum class SqliteOpenMode : int { ReadOnly = SQLITE_OPEN_READONLY, @@ -59,7 +60,7 @@ class SqliteDb { SqliteDb& operator=(SqliteDb&& rhs) noexcept; - bool valid() const; + [[nodiscard]] bool valid() const; bool revalidate(); @@ -69,12 +70,12 @@ class SqliteDb { void* context, std::unique_ptr errorMessage); - constexpr int errorCode() + [[nodiscard]] constexpr int errorCode() const { return m_errorCode; } - constexpr sqlite3* handle() const + [[nodiscard]] constexpr sqlite3* handle() const { return m_dbHandle; } @@ -115,7 +116,7 @@ class SqliteStatement { SqliteStatement& operator=(SqliteStatement&& rhs) noexcept = delete; - bool valid() const; + [[nodiscard]] bool valid() const; sqlite3_stmt* statement(); @@ -123,7 +124,7 @@ class SqliteStatement { FudStatus reset(); - constexpr int errorCode() + [[nodiscard]] constexpr int errorCode() const { return m_errorCode; } diff --git a/include/fud_string_convert.hpp b/include/fud_string_convert.hpp index d7a62f0..e1b7e95 100644 --- a/include/fud_string_convert.hpp +++ b/include/fud_string_convert.hpp @@ -106,6 +106,7 @@ Result checkNegative(StringView& view, size_t& skipIndex); Result getRadix(StringView& view, size_t& skipIndex, Option specifiedRadixOption); template +// NOLINTNEXTLINE(performance-unnecessary-value-param) StringConvertResult unsignedFromString(StringView nextView, size_t skipIndex, Option specifiedRadixOption) { static_assert(std::is_unsigned_v && std::is_integral_v); @@ -114,6 +115,7 @@ StringConvertResult unsignedFromString(StringView nextView, size_t skipIndex, return FudError{FudStatus::ArgumentInvalid}; } + // NOLINTNEXTLINE(performance-unnecessary-value-param) auto radixResult = impl::getRadix(nextView, skipIndex, specifiedRadixOption); if (radixResult.isError()) { return FudError{radixResult.takeError()}; @@ -206,6 +208,7 @@ StringConvertResult signedFromString(StringView nextView, size_t skipIndex, O return FudError{FudStatus::ArgumentInvalid}; } + // NOLINTNEXTLINE(performance-unnecessary-value-param) auto radixResult = impl::getRadix(nextView, skipIndex, specifiedRadixOption); if (radixResult.isError()) { return FudError{radixResult.takeError()}; @@ -372,6 +375,7 @@ StringConvertResult floatFromString(StringView nextView, size_t skipIndex, Op return retSuccess(); } + // NOLINTNEXTLINE(performance-unnecessary-value-param) auto radixResult = impl::getRadix(nextView, skipIndex, specifiedRadixOption); if (radixResult.isError()) { return FudError{radixResult.takeError()}; diff --git a/include/fud_string_view.hpp b/include/fud_string_view.hpp index c3bc0a1..d8f67ba 100644 --- a/include/fud_string_view.hpp +++ b/include/fud_string_view.hpp @@ -84,6 +84,11 @@ struct StringView { return StringView{N - 1, reinterpret_cast(input)}; } + [[nodiscard]] std::string_view as_string_view() const { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return std::string_view{reinterpret_cast(m_data), m_length}; + } + [[nodiscard]] constexpr Span asSpan() const { return Span{m_data, m_length}; @@ -144,7 +149,11 @@ struct StringView { const utf8* m_data{nullptr}; - auto operator<=>(const StringView& rhs) const noexcept = default; + // auto operator<=>(const StringView& rhs) const noexcept = default; + auto operator<=>(const StringView& rhs) const noexcept; + bool operator==(const StringView& rhs) const noexcept; + + Result compare(const StringView& rhs); }; } // namespace fud diff --git a/include/libfud.hpp b/include/libfud.hpp index f0a2517..542c836 100644 --- a/include/libfud.hpp +++ b/include/libfud.hpp @@ -18,8 +18,9 @@ #ifndef LIBFUD_HPP #define LIBFUD_HPP -#include "fud_array.hpp" #include "fud_allocator.hpp" +#include "fud_array.hpp" +#include "fud_option.hpp" #include "fud_result.hpp" #include "fud_status.hpp" #include "fud_string.hpp" @@ -55,7 +56,7 @@ FUD fud(); * \returns FudStatus::NullPointer if name is a null pointer. * \returns FudStatus::NotFound if no binding for the variable exists. */ -Result getEnv(const char* name, Allocator* allocator= &globalFudAllocator); +Result, FudStatus> getEnv(const char* name, Allocator* allocator = &globalFudAllocator); /** \brief A concept requiring the object T to have a method c_str returning a * pointer to a C string. */ @@ -75,7 +76,7 @@ concept CStringRepr = requires(T strObj) { * \returns @getEnv return values. */ template -Result getEnv(const T& name, Allocator* allocator = &globalFudAllocator) +Result, FudStatus> getEnv(const T& name, Allocator* allocator = &globalFudAllocator) { return getEnv(name.c_str(), allocator); } -- cgit v1.2.3