summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2025-01-04 09:56:12 -0600
committerDominick Allen <djallen@librehumanitas.org>2025-01-04 09:56:12 -0600
commit0b400af9519444deef4cc6ad2c43c30e2092ab4f (patch)
treee6b0d78a2c292a7df5724f150e123b55d7871819 /include
parent253385f4bca5ccd2fee22fea8333dfe435c0df0a (diff)
Fix bug related to string copying.
Diffstat (limited to 'include')
-rw-r--r--include/fud_directory.hpp4
-rw-r--r--include/fud_option.hpp17
-rw-r--r--include/fud_sqlite.hpp11
-rw-r--r--include/fud_string_convert.hpp4
-rw-r--r--include/fud_string_view.hpp11
-rw-r--r--include/libfud.hpp7
6 files changed, 39 insertions, 15 deletions
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<T, option_detail::NullOptionType>);
static constexpr bool IsRef = std::is_reference_v<T>;
- using ValueType = typename std::remove_reference<T>::type;
- static constexpr size_t Size = IsRef ? sizeof(std::reference_wrapper<ValueType>) : sizeof(ValueType);
public:
+ using ValueType = std::remove_reference_t<T>;
+ static constexpr size_t Size = IsRef ? sizeof(std::reference_wrapper<ValueType>) : 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<ValueType>(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<const std::reference_wrapper<ValueType>*>(m_data.data());
} else {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return *reinterpret_cast<const ValueType*>(m_data.data());
}
}
@@ -170,8 +175,10 @@ class Option {
{
fudAssert(m_engaged);
if constexpr (IsRef) {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return *reinterpret_cast<std::reference_wrapper<ValueType>*>(m_data.data());
} else {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return *reinterpret_cast<ValueType*>(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<const ValueType*>(m_data.data()));
}
@@ -200,7 +208,7 @@ class Option {
}
template <typename F>
- constexpr auto map(F&& func) const & -> Option<decltype(std::forward<F>(func)(value()))>
+ constexpr auto map(F&& func) const& -> Option<decltype(std::forward<F>(func)(value()))>
{
using U = decltype(std::forward<F>(func)(value()));
// static_assert(std::is_same_v<decltype(std::forward<F>(func)(value())), Option<U>>());
@@ -217,6 +225,7 @@ class Option {
if constexpr (IsRef) {
// reinterpret_cast<std::reference_wrapper<ValueType>*>(m_data.data());
} else {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<ValueType*>(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<SqliteErrorMsg> 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<bool, FudStatus> checkNegative(StringView& view, size_t& skipIndex);
Result<uint8_t, FudStatus> getRadix(StringView& view, size_t& skipIndex, Option<uint8_t> specifiedRadixOption);
template <typename T>
+// NOLINTNEXTLINE(performance-unnecessary-value-param)
StringConvertResult<T> unsignedFromString(StringView nextView, size_t skipIndex, Option<uint8_t> specifiedRadixOption)
{
static_assert(std::is_unsigned_v<T> && std::is_integral_v<T>);
@@ -114,6 +115,7 @@ StringConvertResult<T> 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<T> 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<T> 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<const utf8*>(input)};
}
+ [[nodiscard]] std::string_view as_string_view() const {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ return std::string_view{reinterpret_cast<const char*>(m_data), m_length};
+ }
+
[[nodiscard]] constexpr Span<const utf8> asSpan() const
{
return Span<const utf8>{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<std::strong_ordering, FudStatus> 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<String, FudStatus> getEnv(const char* name, Allocator* allocator= &globalFudAllocator);
+Result<Option<String>, 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 <CStringRepr T>
-Result<String, FudStatus> getEnv(const T& name, Allocator* allocator = &globalFudAllocator)
+Result<Option<String>, FudStatus> getEnv(const T& name, Allocator* allocator = &globalFudAllocator)
{
return getEnv(name.c_str(), allocator);
}