diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/fud_string.cpp | 24 | ||||
-rw-r--r-- | source/fud_string_view.cpp | 115 | ||||
-rw-r--r-- | source/libfud.cpp | 15 |
3 files changed, 116 insertions, 38 deletions
diff --git a/source/fud_string.cpp b/source/fud_string.cpp index 2a17201..37a2a4b 100644 --- a/source/fud_string.cpp +++ b/source/fud_string.cpp @@ -19,12 +19,11 @@ #include "fud_assert.hpp" -#include <type_traits> - namespace fud { StringResult String::makeFromCString(const char8_t* cString) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return makeFromCString(reinterpret_cast<const char*>(cString)); } @@ -35,6 +34,7 @@ StringResult String::makeFromCString(const char* cString) StringResult String::makeFromCString(const char8_t* cString, Allocator* allocator) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) return makeFromCString(reinterpret_cast<const char*>(cString), allocator); } @@ -61,6 +61,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator) } String output{}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) output.m_allocator = reinterpret_cast<uintptr_t>(allocator); utf8* outputData{nullptr}; @@ -86,6 +87,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator) return StringResult::okay(std::move(output)); } +//NOLINTNEXTLINE(performance-unnecessary-value-param) StringResult String::from(const String& rhs, Option<Allocator*> allocatorOption) { if (!rhs.valid()) { @@ -98,10 +100,11 @@ StringResult String::from(const String& rhs, Option<Allocator*> allocatorOption) } String output{}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) output.m_allocator = reinterpret_cast<uintptr_t>(allocator); utf8* outputData{nullptr}; - size_t outputCapacity{0}; - size_t outputLength{0}; + size_t outputCapacity{rhs.capacity()}; + size_t outputLength{rhs.length()}; if (rhs.isLarge()) { auto status = output.makeLarge(outputCapacity, outputLength, outputData); if (status != FudStatus::Success) { @@ -132,6 +135,7 @@ StringResult String::from(StringView view, Allocator* allocator) } String output{}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) output.m_allocator = reinterpret_cast<uintptr_t>(allocator); size_t outputCapacity = view.length() + 1U; bool isLarge = outputCapacity > SsoBufSize; @@ -154,7 +158,7 @@ StringResult String::from(StringView view, Allocator* allocator) return StringResult::okay(std::move(output)); } -String::String(String&& rhs) noexcept : m_allocator{rhs.m_allocator}, m_repr{std::move(rhs.m_repr)} +String::String(String&& rhs) noexcept : m_allocator{rhs.m_allocator}, m_repr{rhs.m_repr} { rhs.setSmall(); rhs.m_repr.small.length = 0; @@ -189,6 +193,7 @@ FudStatus String::copy(const String& rhs) if (allocResult.isError()) { return allocResult.takeError(); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) m_repr.large.data = reinterpret_cast<utf8*>(allocResult.takeOkay()); outputCapacity = m_repr.large.capacity; outputLength = m_repr.large.length; @@ -219,7 +224,7 @@ String& String::operator=(String&& rhs) noexcept cleanup(); m_allocator = rhs.m_allocator; - m_repr = std::move(rhs.m_repr); + m_repr = rhs.m_repr; if (isLarge()) { rhs.m_repr.large.data = nullptr; @@ -232,6 +237,7 @@ void String::cleanup() { const auto* allocPtr = allocator(); if (isLarge() && m_repr.large.data != nullptr && allocPtr != nullptr) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity); m_repr.large.data = nullptr; } @@ -259,6 +265,7 @@ FudStatus String::resize(size_t newCapacity) auto copyResult = copyMem(dataMut(), temp.size(), temp.data(), len); fudAssert(copyResult == FudStatus::Success); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity); setSmall(); m_repr.small.length = len & smallStringLengthMask; @@ -272,6 +279,7 @@ FudStatus String::resize(size_t newCapacity) if (allocResult.isError()) { return allocResult.takeError(); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto* newData = reinterpret_cast<utf8*>(allocResult.takeOkay()); fudAssert(newData != nullptr); @@ -279,6 +287,7 @@ FudStatus String::resize(size_t newCapacity) fudAssert(copyResult == FudStatus::Success); if (isLarge()) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity); } @@ -658,7 +667,7 @@ StringResult String::catenate(const char* rhs) const if (lenResult < 0 || lenResult >= static_cast<ssize_t>(maxStringLength)) { return StringResult::error(FudStatus::ArgumentInvalid); } - size_t rhsLength = static_cast<size_t>(lenResult); + auto rhsLength = static_cast<size_t>(lenResult); if (maxStringLength - length() < rhsLength) { return StringResult::error(FudStatus::Failure); @@ -804,6 +813,7 @@ FudStatus String::makeLarge(size_t cap, size_t len, utf8*& outputData) if (dataResult.isError()) { return dataResult.getError(); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) m_repr.large.data = reinterpret_cast<utf8*>(dataResult.getOkay()); outputData = m_repr.large.data; setLarge(); diff --git a/source/fud_string_view.cpp b/source/fud_string_view.cpp index ba88ad4..5c5e623 100644 --- a/source/fud_string_view.cpp +++ b/source/fud_string_view.cpp @@ -133,6 +133,96 @@ FudStatus skipWhitespace(StringView& view, size_t& skipIndex) return FudStatus::Success; } +FudStatus fud_string_compare(StringView levo, StringView dextro, int& difference) +{ + if (anyAreNull(levo.m_data, dextro.m_data)) { + return FudStatus::NullPointer; + } + + int diff = 0; + size_t index = 0; + while (diff == 0 && index < levo.length() && index < dextro.length()) { + diff = levo.m_data[index] - dextro.m_data[index]; + index++; + } + + if (diff != 0 || levo.length() == dextro.length()) { + /* nothing to do */ + } else if (levo.length() > dextro.length()) { + diff = static_cast<int>(levo.m_data[index]); + } else { + diff = -static_cast<int>(dextro.m_data[index]); + } + + difference = diff; + return FudStatus::Success; +} + +bool StringView::operator==(const StringView& rhs) const noexcept +{ + if (m_length == rhs.m_length && m_data == rhs.m_data) { + return true; + } + int difference{}; + auto compareStatus = fud_string_compare(*this, rhs, difference); + if (compareStatus != FudStatus::Success) { + if (m_data != nullptr && rhs.m_data == nullptr) { + return false; + } + if (m_data == nullptr && rhs.m_data != nullptr) { + return false; + } + fudAssert(m_data == nullptr && rhs.m_data == nullptr); + if (m_length > rhs.m_length) { + return false; + } + fudAssert(m_length < rhs.m_length); + return false; + } + if (difference > 0) { + return false; + } + if (difference < 0) { + return false; + } + return true; + +} + +auto StringView::operator<=>(const StringView& rhs) const noexcept +{ + if (this == &rhs) { + return std::strong_ordering::equivalent; + } + if (m_length == rhs.m_length && m_data == rhs.m_data) + { + return std::strong_ordering::equivalent; + } + int difference{}; + auto compareStatus = fud_string_compare(*this, rhs, difference); + if (compareStatus != FudStatus::Success) { + if (m_data != nullptr && rhs.m_data == nullptr) { + return std::strong_ordering::greater; + } + if (m_data == nullptr && rhs.m_data != nullptr) { + return std::strong_ordering::less; + } + fudAssert(m_data == nullptr && rhs.m_data == nullptr); + if (m_length > rhs.m_length) { + return std::strong_ordering::greater; + } + fudAssert(m_length < rhs.m_length); + return std::strong_ordering::less; + } + if (difference > 0) { + return std::strong_ordering::greater; + } + if (difference < 0) { + return std::strong_ordering::less; + } + return std::strong_ordering::equivalent; +} + #if 0 FudStatus fud_string_truncate(ExtBasicString* source, ssize_t newLength) @@ -226,31 +316,6 @@ FudStatus fud_string_reverse_substring(ExtBasicString* source, StringView subStr return FudStatus::Success; } -FudStatus fud_string_compare(StringView levo, StringView dextro, int* difference) -{ - if (anyAreNull(difference, levo.data, dextro.data)) { - return FudStatus::NullPointer; - } - - int diff = 0; - size_t index = 0; - while (diff == 0 && index < levo.length && index < dextro.length) { - diff = levo.data[index] - dextro.data[index]; - index++; - } - - if (diff != 0 || levo.length == dextro.length) { - /* nothing to do */ - } else if (levo.length > dextro.length) { - diff = static_cast<int>(levo.data[index]); - } else { - diff = -static_cast<int>(dextro.data[index]); - } - - *difference = diff; - return FudStatus::Success; -} - FudStatus fud_string_chr(StringView extStringView, char character, size_t* index) { if (anyAreNull(extStringView.data, index)) { diff --git a/source/libfud.cpp b/source/libfud.cpp index be43490..c4e4b5b 100644 --- a/source/libfud.cpp +++ b/source/libfud.cpp @@ -35,20 +35,23 @@ FUD fud() return fudInfo; } -Result<String, FudStatus> getEnv(const char* name, Allocator* allocator) +Result<Option<String>, FudStatus> getEnv(const char* name, Allocator* allocator) { - using RetType = Result<String, FudStatus>; - if (name == nullptr) { - return RetType::error(FudStatus::NullPointer); + return Error{FudStatus::NullPointer}; } const char* resultString = getenv(name); if (resultString == nullptr) { - return RetType::error(FudStatus::NotFound); + return Okay{Option<String>{NullOpt}}; + } + + auto result{String::makeFromCString(resultString, allocator)}; + if (result.isError()) { + return Error{result.takeError()}; } - return String::makeFromCString(resultString, allocator); + return Okay{Option<String>::take(result.takeOkay())}; } } // namespace fud |