forked from qt-creator/qt-creator
Utils: Modernize SmallString
Use more C++ api and constexpr. With C++ 17 we can use even more. Change-Id: I33934cd7e087c311bf98501442df848bdb108279 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -90,39 +90,35 @@ public:
|
|||||||
constexpr
|
constexpr
|
||||||
BasicSmallString(const char(&string)[ArraySize])
|
BasicSmallString(const char(&string)[ArraySize])
|
||||||
: m_data(string)
|
: m_data(string)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
BasicSmallString(const char *string, size_type size, size_type capacity)
|
BasicSmallString(const char *string, size_type size, size_type capacity)
|
||||||
{
|
{
|
||||||
if (Q_LIKELY(capacity <= shortStringCapacity())) {
|
if (Q_LIKELY(capacity <= shortStringCapacity())) {
|
||||||
std::memcpy(m_data.shortString.string, string, size);
|
std::char_traits<char>::copy(m_data.shortString.string, string, size);
|
||||||
m_data.shortString.string[size] = 0;
|
m_data.shortString.string[size] = 0;
|
||||||
m_data.shortString.control.setShortStringSize(size);
|
m_data.shortString.control.setShortStringSize(size);
|
||||||
m_data.shortString.control.setIsShortString(true);
|
m_data.shortString.control.setIsShortString(true);
|
||||||
m_data.shortString.control.setIsReadOnlyReference(false);
|
m_data.shortString.control.setIsReadOnlyReference(false);
|
||||||
} else {
|
} else {
|
||||||
m_data.allocated.data.pointer = Memory::allocate(capacity + 1);
|
m_data.allocated.data.pointer = Memory::allocate(capacity + 1);
|
||||||
std::memcpy(m_data.allocated.data.pointer, string, size);
|
std::char_traits<char>::copy(m_data.allocated.data.pointer, string, size);
|
||||||
initializeLongString(size, capacity);
|
initializeLongString(size, capacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit BasicSmallString(SmallStringView stringView)
|
explicit BasicSmallString(SmallStringView stringView)
|
||||||
: BasicSmallString(stringView.data(), stringView.size(), stringView.size())
|
: BasicSmallString(stringView.data(), stringView.size(), stringView.size())
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
BasicSmallString(const char *string, size_type size)
|
BasicSmallString(const char *string, size_type size)
|
||||||
: BasicSmallString(string, size, size)
|
: BasicSmallString(string, size, size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type,
|
template<typename Type, typename = std::enable_if_t<std::is_pointer<Type>::value>>
|
||||||
typename = std::enable_if_t<std::is_pointer<Type>::value>
|
|
||||||
>
|
|
||||||
BasicSmallString(Type characterPointer)
|
BasicSmallString(Type characterPointer)
|
||||||
: BasicSmallString(characterPointer, std::strlen(characterPointer))
|
: BasicSmallString(characterPointer, std::char_traits<char>::length(characterPointer))
|
||||||
{
|
{
|
||||||
static_assert(!std::is_array<Type>::value, "Input type is array and not char pointer!");
|
static_assert(!std::is_array<Type>::value, "Input type is array and not char pointer!");
|
||||||
}
|
}
|
||||||
@@ -253,7 +249,7 @@ public:
|
|||||||
static
|
static
|
||||||
BasicSmallString fromUtf8(const char *characterPointer)
|
BasicSmallString fromUtf8(const char *characterPointer)
|
||||||
{
|
{
|
||||||
return BasicSmallString(characterPointer, std::strlen(characterPointer));
|
return BasicSmallString(characterPointer, std::char_traits<char>::length(characterPointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(size_type newCapacity)
|
void reserve(size_type newCapacity)
|
||||||
@@ -271,7 +267,7 @@ public:
|
|||||||
const char *oldData = data();
|
const char *oldData = data();
|
||||||
|
|
||||||
char *newData = Memory::allocate(newCapacity + 1);
|
char *newData = Memory::allocate(newCapacity + 1);
|
||||||
std::memcpy(newData, oldData, oldSize);
|
std::char_traits<char>::copy(newData, oldData, oldSize);
|
||||||
m_data.allocated.data.pointer = newData;
|
m_data.allocated.data.pointer = newData;
|
||||||
initializeLongString(oldSize, newCapacity);
|
initializeLongString(oldSize, newCapacity);
|
||||||
}
|
}
|
||||||
@@ -380,7 +376,7 @@ public:
|
|||||||
|
|
||||||
bool contains(char characterToSearch) const
|
bool contains(char characterToSearch) const
|
||||||
{
|
{
|
||||||
auto found = std::memchr(data(), characterToSearch, size());
|
auto found = std::char_traits<char>::find(data(), size(), characterToSearch);
|
||||||
|
|
||||||
return found != nullptr;
|
return found != nullptr;
|
||||||
}
|
}
|
||||||
@@ -388,7 +384,9 @@ public:
|
|||||||
bool startsWith(SmallStringView subStringToSearch) const noexcept
|
bool startsWith(SmallStringView subStringToSearch) const noexcept
|
||||||
{
|
{
|
||||||
if (size() >= subStringToSearch.size())
|
if (size() >= subStringToSearch.size())
|
||||||
return !std::memcmp(data(), subStringToSearch.data(), subStringToSearch.size());
|
return !std::char_traits<char>::compare(data(),
|
||||||
|
subStringToSearch.data(),
|
||||||
|
subStringToSearch.size());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -401,9 +399,10 @@ public:
|
|||||||
bool endsWith(SmallStringView subStringToSearch) const noexcept
|
bool endsWith(SmallStringView subStringToSearch) const noexcept
|
||||||
{
|
{
|
||||||
if (size() >= subStringToSearch.size()) {
|
if (size() >= subStringToSearch.size()) {
|
||||||
const int comparison = std::memcmp(end().data() - subStringToSearch.size(),
|
const int comparison = std::char_traits<char>::compare(end().data()
|
||||||
subStringToSearch.data(),
|
- subStringToSearch.size(),
|
||||||
subStringToSearch.size());
|
subStringToSearch.data(),
|
||||||
|
subStringToSearch.size());
|
||||||
return comparison == 0;
|
return comparison == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,7 +461,7 @@ public:
|
|||||||
size_type newSize = oldSize + string.size();
|
size_type newSize = oldSize + string.size();
|
||||||
|
|
||||||
reserve(optimalCapacity(newSize));
|
reserve(optimalCapacity(newSize));
|
||||||
std::memcpy(data() + oldSize, string.data(), string.size());
|
std::char_traits<char>::copy(data() + oldSize, string.data(), string.size());
|
||||||
at(newSize) = 0;
|
at(newSize) = 0;
|
||||||
setSize(newSize);
|
setSize(newSize);
|
||||||
}
|
}
|
||||||
@@ -724,7 +723,7 @@ private:
|
|||||||
at(size) = 0;
|
at(size) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeLongString(size_type size, size_type capacity)
|
constexpr void initializeLongString(size_type size, size_type capacity)
|
||||||
{
|
{
|
||||||
m_data.allocated.data.pointer[size] = 0;
|
m_data.allocated.data.pointer[size] = 0;
|
||||||
m_data.allocated.data.size = size;
|
m_data.allocated.data.size = size;
|
||||||
@@ -757,7 +756,7 @@ private:
|
|||||||
while (found != end()) {
|
while (found != end()) {
|
||||||
start = found + toText.size();
|
start = found + toText.size();
|
||||||
|
|
||||||
std::memcpy(found.data(), toText.data(), toText.size());
|
std::char_traits<char>::copy(found.data(), toText.data(), toText.size());
|
||||||
|
|
||||||
found = std::search(start,
|
found = std::search(start,
|
||||||
end(),
|
end(),
|
||||||
|
@@ -25,6 +25,18 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
#define constexpr17 constexpr
|
||||||
|
#else
|
||||||
|
#define constexpr17 inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __cplusplus >= 202002L
|
||||||
|
#define constexpr20 constexpr
|
||||||
|
#else
|
||||||
|
#define constexpr20 inline
|
||||||
|
#endif
|
||||||
|
|
||||||
using uint = unsigned int;
|
using uint = unsigned int;
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -35,9 +47,4 @@ class BasicSmallString;
|
|||||||
using SmallString = BasicSmallString<31>;
|
using SmallString = BasicSmallString<31>;
|
||||||
using PathString = BasicSmallString<190>;
|
using PathString = BasicSmallString<190>;
|
||||||
|
|
||||||
inline
|
|
||||||
int compare(SmallStringView first, SmallStringView second) noexcept;
|
|
||||||
inline
|
|
||||||
int reverseCompare(SmallStringView first, SmallStringView second) noexcept;
|
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
@@ -32,123 +32,94 @@ namespace Utils {
|
|||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
template <class Category,
|
template<class Category,
|
||||||
class Type,
|
class Type,
|
||||||
typename DistanceType = ptrdiff_t,
|
typename DistanceType = ptrdiff_t,
|
||||||
typename Pointer = Type*,
|
typename Pointer = Type *,
|
||||||
typename Reference = Type&>
|
typename Reference = Type &>
|
||||||
struct SmallStringIterator : public std::iterator<Category, Type, DistanceType, Pointer, Reference>
|
struct SmallStringIterator
|
||||||
{
|
{
|
||||||
constexpr
|
using iterator_category = Category;
|
||||||
SmallStringIterator() noexcept = default;
|
using value_type = Type;
|
||||||
|
using difference_type = DistanceType;
|
||||||
|
using pointer = Pointer;
|
||||||
|
using reference = Reference;
|
||||||
|
|
||||||
constexpr
|
constexpr SmallStringIterator() noexcept = default;
|
||||||
SmallStringIterator(Pointer ptr) noexcept : pointer_(ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallStringIterator operator++() noexcept
|
constexpr SmallStringIterator(Pointer ptr) noexcept
|
||||||
{
|
: pointer_(ptr)
|
||||||
return ++pointer_;
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
SmallStringIterator operator++(int) noexcept
|
constexpr SmallStringIterator operator++() noexcept { return ++pointer_; }
|
||||||
{
|
|
||||||
return pointer_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallStringIterator operator--() noexcept
|
constexpr SmallStringIterator operator++(int) noexcept { return pointer_++; }
|
||||||
{
|
|
||||||
return --pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallStringIterator operator--(int) noexcept
|
constexpr SmallStringIterator operator--() noexcept { return --pointer_; }
|
||||||
{
|
|
||||||
return pointer_--;
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallStringIterator operator+(DistanceType difference) const noexcept
|
constexpr SmallStringIterator operator--(int) noexcept { return pointer_--; }
|
||||||
|
|
||||||
|
constexpr SmallStringIterator operator+(DistanceType difference) const noexcept
|
||||||
{
|
{
|
||||||
return pointer_ + difference;
|
return pointer_ + difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallStringIterator operator-(DistanceType difference) const noexcept
|
constexpr SmallStringIterator operator-(DistanceType difference) const noexcept
|
||||||
{
|
{
|
||||||
return pointer_ - difference;
|
return pointer_ - difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallStringIterator operator+(std::size_t difference) const noexcept
|
constexpr SmallStringIterator operator+(std::size_t difference) const noexcept
|
||||||
{
|
{
|
||||||
return pointer_ + difference;
|
return pointer_ + difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallStringIterator operator-(std::size_t difference) const noexcept
|
constexpr SmallStringIterator operator-(std::size_t difference) const noexcept
|
||||||
{
|
{
|
||||||
return pointer_ - difference;
|
return pointer_ - difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
DistanceType operator-(SmallStringIterator other) const noexcept
|
constexpr DistanceType operator-(SmallStringIterator other) const noexcept
|
||||||
{
|
{
|
||||||
return pointer_ - other.data();
|
return pointer_ - other.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallStringIterator operator+=(DistanceType difference) noexcept
|
constexpr SmallStringIterator operator+=(DistanceType difference) noexcept
|
||||||
{
|
{
|
||||||
return pointer_ += difference;
|
return pointer_ += difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallStringIterator operator-=(DistanceType difference) noexcept
|
constexpr SmallStringIterator operator-=(DistanceType difference) noexcept
|
||||||
{
|
{
|
||||||
return pointer_ -= difference;
|
return pointer_ -= difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference operator*() noexcept
|
constexpr Reference operator*() noexcept { return *pointer_; }
|
||||||
{
|
|
||||||
return *pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Reference operator*() const noexcept
|
const Reference operator*() const noexcept { return *pointer_; }
|
||||||
{
|
|
||||||
return *pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pointer operator->() noexcept
|
constexpr Pointer operator->() noexcept { return pointer_; }
|
||||||
{
|
|
||||||
return pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Pointer operator->() const noexcept
|
constexpr const Pointer operator->() const noexcept { return pointer_; }
|
||||||
{
|
|
||||||
return pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr
|
constexpr bool operator==(SmallStringIterator other) const noexcept
|
||||||
bool operator==(SmallStringIterator other) const noexcept
|
|
||||||
{
|
{
|
||||||
return pointer_ == other.pointer_;
|
return pointer_ == other.pointer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr
|
constexpr bool operator!=(SmallStringIterator other) const noexcept
|
||||||
bool operator!=(SmallStringIterator other) const noexcept
|
|
||||||
{
|
{
|
||||||
return pointer_ != other.pointer_;
|
return pointer_ != other.pointer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr
|
constexpr bool operator<(SmallStringIterator other) const noexcept
|
||||||
bool operator<(SmallStringIterator other) const noexcept
|
|
||||||
{
|
{
|
||||||
return pointer_ < other.pointer_;
|
return pointer_ < other.pointer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pointer data() noexcept
|
constexpr Pointer data() noexcept { return pointer_; }
|
||||||
{
|
|
||||||
return pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Pointer data() const noexcept
|
constexpr const Pointer data() const noexcept { return pointer_; }
|
||||||
{
|
|
||||||
return pointer_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pointer pointer_ = nullptr;
|
Pointer pointer_ = nullptr;
|
||||||
|
@@ -49,30 +49,21 @@ struct ControlBlock
|
|||||||
m_isReference(isReference)
|
m_isReference(isReference)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void setShortStringSize(size_type size)
|
constexpr void setShortStringSize(size_type size)
|
||||||
{
|
{
|
||||||
m_shortStringSize = static_cast<SizeType>(size);
|
m_shortStringSize = static_cast<SizeType>(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_type shortStringSize() const
|
constexpr size_type shortStringSize() const { return m_shortStringSize; }
|
||||||
{
|
|
||||||
return m_shortStringSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setIsReadOnlyReference(bool isReadOnlyReference)
|
constexpr void setIsReadOnlyReference(bool isReadOnlyReference)
|
||||||
{
|
{
|
||||||
m_isReadOnlyReference = isReadOnlyReference;
|
m_isReadOnlyReference = isReadOnlyReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIsReference(bool isReference)
|
constexpr void setIsReference(bool isReference) { m_isReference = isReference; }
|
||||||
{
|
|
||||||
m_isReference = isReference;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setIsShortString(bool isShortString)
|
constexpr void setIsShortString(bool isShortString) { m_isReference = !isShortString; }
|
||||||
{
|
|
||||||
m_isReference = !isShortString;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr
|
constexpr
|
||||||
SizeType stringSize() const
|
SizeType stringSize() const
|
||||||
@@ -168,7 +159,7 @@ struct StringDataLayout {
|
|||||||
|
|
||||||
template<size_type Size,
|
template<size_type Size,
|
||||||
typename std::enable_if_t<Size <= MaximumShortStringDataAreaSize, int> = 0>
|
typename std::enable_if_t<Size <= MaximumShortStringDataAreaSize, int> = 0>
|
||||||
StringDataLayout(const char(&string)[Size]) noexcept
|
constexpr StringDataLayout(const char (&string)[Size]) noexcept
|
||||||
: shortString(ShortStringLayout<MaximumShortStringDataAreaSize>{})
|
: shortString(ShortStringLayout<MaximumShortStringDataAreaSize>{})
|
||||||
{
|
{
|
||||||
for (size_type i = 0; i < Size; ++i)
|
for (size_type i = 0; i < Size; ++i)
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "smallstringfwd.h"
|
||||||
#include "smallstringiterator.h"
|
#include "smallstringiterator.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
@@ -53,36 +54,32 @@ public:
|
|||||||
|
|
||||||
constexpr SmallStringView() = default;
|
constexpr SmallStringView() = default;
|
||||||
|
|
||||||
SmallStringView(const char *characterPointer) noexcept
|
constexpr17 SmallStringView(const char *characterPointer) noexcept
|
||||||
: m_pointer(characterPointer)
|
: m_pointer(characterPointer)
|
||||||
, m_size(std::strlen(characterPointer))
|
, m_size(std::char_traits<char>::length(characterPointer))
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr
|
|
||||||
SmallStringView(const char *const string, const size_type size) noexcept
|
|
||||||
: m_pointer(string),
|
|
||||||
m_size(size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SmallStringView(const const_iterator begin, const const_iterator end) noexcept
|
|
||||||
: m_pointer(begin.data()),
|
|
||||||
m_size(std::size_t(end - begin))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename String,
|
|
||||||
typename Utils::enable_if_has_char_data_pointer<String> = 0>
|
|
||||||
SmallStringView(const String &string) noexcept
|
|
||||||
: m_pointer(string.data()),
|
|
||||||
m_size(string.size())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
static
|
constexpr SmallStringView(const char *const string, const size_type size) noexcept
|
||||||
SmallStringView fromUtf8(const char *const characterPointer)
|
: m_pointer(string)
|
||||||
|
, m_size(size)
|
||||||
{
|
{
|
||||||
return SmallStringView(characterPointer, std::strlen(characterPointer));
|
}
|
||||||
|
|
||||||
|
constexpr SmallStringView(const const_iterator begin, const const_iterator end) noexcept
|
||||||
|
: m_pointer(begin.data())
|
||||||
|
, m_size(std::size_t(end - begin))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename String, typename Utils::enable_if_has_char_data_pointer<String> = 0>
|
||||||
|
constexpr SmallStringView(const String &string) noexcept
|
||||||
|
: m_pointer(string.data())
|
||||||
|
, m_size(string.size())
|
||||||
|
{}
|
||||||
|
|
||||||
|
static constexpr17 SmallStringView fromUtf8(const char *const characterPointer)
|
||||||
|
{
|
||||||
|
return SmallStringView(characterPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr
|
constexpr
|
||||||
@@ -133,93 +130,85 @@ public:
|
|||||||
return data() + size();
|
return data() + size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const_reverse_iterator rbegin() const noexcept
|
constexpr17 const_reverse_iterator rbegin() const noexcept
|
||||||
{
|
{
|
||||||
return const_reverse_iterator(end());
|
return const_reverse_iterator(end());
|
||||||
}
|
}
|
||||||
|
|
||||||
const_reverse_iterator rend() const noexcept
|
constexpr17 const_reverse_iterator rend() const noexcept
|
||||||
{
|
{
|
||||||
return const_reverse_iterator(begin());
|
return const_reverse_iterator(begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
operator std::string() const
|
constexpr20 operator std::string() const { return std::string(data(), size()); }
|
||||||
{
|
|
||||||
return std::string(data(), size());
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit operator QString() const
|
explicit operator QString() const
|
||||||
{
|
{
|
||||||
return QString::fromUtf8(data(), int(size()));
|
return QString::fromUtf8(data(), int(size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool startsWith(SmallStringView subStringToSearch) const noexcept
|
constexpr17 bool startsWith(SmallStringView subStringToSearch) const noexcept
|
||||||
{
|
{
|
||||||
if (size() >= subStringToSearch.size())
|
if (size() >= subStringToSearch.size())
|
||||||
return !std::memcmp(m_pointer, subStringToSearch.data(), subStringToSearch.size());
|
return !std::char_traits<char>::compare(m_pointer,
|
||||||
|
subStringToSearch.data(),
|
||||||
|
subStringToSearch.size());
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool startsWith(char characterToSearch) const noexcept
|
constexpr bool startsWith(char characterToSearch) const noexcept
|
||||||
{
|
{
|
||||||
return m_pointer[0] == characterToSearch;
|
return m_pointer[0] == characterToSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
char back() const { return m_pointer[m_size - 1]; }
|
constexpr char back() const { return m_pointer[m_size - 1]; }
|
||||||
|
|
||||||
char operator[](std::size_t index) { return m_pointer[index]; }
|
constexpr char operator[](std::size_t index) { return m_pointer[index]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *m_pointer = "";
|
const char *m_pointer = "";
|
||||||
size_type m_size = 0;
|
size_type m_size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
constexpr17 bool operator==(SmallStringView first, SmallStringView second) noexcept
|
||||||
bool operator==(SmallStringView first, SmallStringView second) noexcept
|
|
||||||
{
|
{
|
||||||
return first.size() == second.size() && std::memcmp(first.data(), second.data(), first.size()) == 0;
|
return first.size() == second.size()
|
||||||
|
&& std::char_traits<char>::compare(first.data(), second.data(), first.size()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
constexpr17 bool operator!=(SmallStringView first, SmallStringView second) noexcept
|
||||||
bool operator!=(SmallStringView first, SmallStringView second) noexcept
|
|
||||||
{
|
{
|
||||||
return !(first == second);
|
return !(first == second);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
constexpr17 int compare(SmallStringView first, SmallStringView second) noexcept
|
||||||
int compare(SmallStringView first, SmallStringView second) noexcept
|
|
||||||
{
|
{
|
||||||
int sizeDifference = int(first.size() - second.size());
|
int sizeDifference = int(first.size() - second.size());
|
||||||
|
|
||||||
if (sizeDifference == 0)
|
if (sizeDifference == 0)
|
||||||
return std::memcmp(first.data(), second.data(), first.size());
|
return std::char_traits<char>::compare(first.data(), second.data(), first.size());
|
||||||
|
|
||||||
return sizeDifference;
|
return sizeDifference;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
constexpr17 bool operator<(SmallStringView first, SmallStringView second) noexcept
|
||||||
bool operator<(SmallStringView first, SmallStringView second) noexcept
|
|
||||||
{
|
{
|
||||||
return compare(first, second) < 0;
|
return compare(first, second) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
constexpr17 bool operator>(SmallStringView first, SmallStringView second) noexcept
|
||||||
bool operator>(SmallStringView first, SmallStringView second) noexcept
|
|
||||||
{
|
{
|
||||||
return second < first;
|
return second < first;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
inline
|
constexpr int reverse_memcmp(const char *first, const char *second, size_t n)
|
||||||
int reverse_memcmp(const char *first, const char *second, size_t n)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
const char *currentFirst = first + n - 1;
|
const char *currentFirst = first + n - 1;
|
||||||
const char *currentSecond = second + n - 1;
|
const char *currentSecond = second + n - 1;
|
||||||
|
|
||||||
while (n > 0)
|
while (n > 0) {
|
||||||
{
|
|
||||||
// If the current characters differ, return an appropriately signed
|
// If the current characters differ, return an appropriately signed
|
||||||
// value; otherwise, keep searching backwards
|
// value; otherwise, keep searching backwards
|
||||||
int difference = *currentFirst - *currentSecond;
|
int difference = *currentFirst - *currentSecond;
|
||||||
@@ -233,10 +222,9 @@ int reverse_memcmp(const char *first, const char *second, size_t n)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Internal
|
||||||
|
|
||||||
inline
|
constexpr int reverseCompare(SmallStringView first, SmallStringView second) noexcept
|
||||||
int reverseCompare(SmallStringView first, SmallStringView second) noexcept
|
|
||||||
{
|
{
|
||||||
int sizeDifference = int(first.size() - second.size());
|
int sizeDifference = int(first.size() - second.size());
|
||||||
|
|
||||||
@@ -248,10 +236,7 @@ int reverseCompare(SmallStringView first, SmallStringView second) noexcept
|
|||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
#ifdef __cpp_user_defined_literals
|
|
||||||
inline
|
|
||||||
constexpr Utils::SmallStringView operator""_sv(const char *const string, size_t size)
|
constexpr Utils::SmallStringView operator""_sv(const char *const string, size_t size)
|
||||||
{
|
{
|
||||||
return Utils::SmallStringView(string, size);
|
return Utils::SmallStringView(string, size);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
Reference in New Issue
Block a user