Utils: Optimize smallstring a little more

For string with a larger area we use spend a little bit memory on less
execution time.

Change-Id: I261ada4120de974ce40daaa7f0922af4dd115996
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2024-05-12 22:13:03 +02:00
committed by Tim Jenssen
parent c463807dda
commit a7309597fa
15 changed files with 192 additions and 202 deletions

View File

@@ -19,11 +19,11 @@ public:
: m_sqlStatementBuilder(templateText())
{}
void setTableName(Utils::SmallString &&tableName)
void setTableName(Utils::SmallStringView tableName)
{
m_sqlStatementBuilder.clear();
this->m_tableName = std::move(tableName);
this->m_tableName = tableName;
}
void addColumn(Utils::SmallStringView columnName,
@@ -291,7 +291,7 @@ private:
void bindAll() const
{
m_sqlStatementBuilder.bind("$table", m_tableName.clone());
m_sqlStatementBuilder.bind("$table", m_tableName);
bindTemporary();
bindIfNotExists();

View File

@@ -145,7 +145,7 @@ public:
{
CreateTableSqlStatementBuilder<ColumnType> builder;
builder.setTableName(m_tableName.clone());
builder.setTableName(m_tableName);
builder.setUseWithoutRowId(m_withoutRowId);
builder.setUseIfNotExists(m_useIfNotExists);
builder.setUseTemporaryTable(m_useTemporaryTable);

View File

@@ -23,7 +23,7 @@ void SqlStatementBuilder::bindEmptyText(Utils::SmallString &&name)
changeBinding(std::move(name), {});
}
void SqlStatementBuilder::bind(Utils::SmallString &&name, Utils::SmallString &&text)
void SqlStatementBuilder::bind(Utils::SmallStringView name, Utils::SmallStringView text)
{
clearSqlStatement();
checkBindingTextIsNotEmpty(text);
@@ -31,7 +31,7 @@ void SqlStatementBuilder::bind(Utils::SmallString &&name, Utils::SmallString &&t
changeBinding(std::move(name), std::move(text));
}
void SqlStatementBuilder::bind(Utils::SmallString &&name, const Utils::SmallStringVector &textVector)
void SqlStatementBuilder::bind(Utils::SmallStringView name, const Utils::SmallStringVector &textVector)
{
clearSqlStatement();
checkBindingTextVectorIsNotEmpty(textVector);
@@ -39,7 +39,7 @@ void SqlStatementBuilder::bind(Utils::SmallString &&name, const Utils::SmallStri
changeBinding(std::move(name), textVector.join(", "));
}
void SqlStatementBuilder::bind(Utils::SmallString &&name, int value)
void SqlStatementBuilder::bind(Utils::SmallStringView name, int value)
{
clearSqlStatement();
checkIfPlaceHolderExists(name);
@@ -60,7 +60,8 @@ Utils::SmallStringVector integerVectorToStringVector(const std::vector<int> &int
return stringVector;
}
}
void SqlStatementBuilder::bind(Utils::SmallString &&name, const std::vector<int> &integerVector)
void SqlStatementBuilder::bind(Utils::SmallStringView name, const std::vector<int> &integerVector)
{
clearSqlStatement();
checkBindingIntegerVectorIsNotEmpty(integerVector);

View File

@@ -19,10 +19,10 @@ public:
SqlStatementBuilder(Utils::SmallStringView m_sqlTemplate);
void bindEmptyText(Utils::SmallString &&name);
void bind(Utils::SmallString &&name, Utils::SmallString &&text);
void bind(Utils::SmallString &&name, const Utils::SmallStringVector &textVector);
void bind(Utils::SmallString &&name, int value);
void bind(Utils::SmallString &&name, const std::vector<int> &integerVector);
void bind(Utils::SmallStringView name, Utils::SmallStringView text);
void bind(Utils::SmallStringView name, const Utils::SmallStringVector &textVector);
void bind(Utils::SmallStringView name, int value);
void bind(Utils::SmallStringView name, const std::vector<int> &integerVector);
void bindWithInsertTemplateParameters(Utils::SmallString &&name,
const Utils::SmallStringVector &columns);
void bindWithUpdateTemplateParameters(Utils::SmallString &&name,
@@ -56,8 +56,8 @@ protected:
Utils::SmallString sqlTemplate);
private:
Utils::BasicSmallString<510> m_sqlTemplate;
mutable Utils::BasicSmallString<510> m_sqlStatement;
Utils::BasicSmallString<496> m_sqlTemplate;
mutable Utils::BasicSmallString<496> m_sqlStatement;
mutable std::vector<BindingPair> m_bindings;
};

View File

@@ -47,7 +47,7 @@ public:
using size_type = std::size_t;
static_assert(Size < 64 ? sizeof(Internal::StringDataLayout<Size>) == Size + 1
: sizeof(Internal::StringDataLayout<Size>) == Size + 2,
: sizeof(Internal::StringDataLayout<Size>) == Size + 16,
"Size is wrong");
BasicSmallString() noexcept = default;
@@ -63,16 +63,8 @@ public:
{}
BasicSmallString(const char *string, size_type size, size_type capacity) noexcept
{
if (Q_LIKELY(capacity <= shortStringCapacity())) {
m_data.control = Internal::ControlBlock<Size>(size, false, false);
std::char_traits<char>::copy(m_data.shortString, string, size);
} else {
auto pointer = Memory::allocate(capacity);
std::char_traits<char>::copy(pointer, string, size);
initializeLongString(pointer, size, capacity);
}
}
: m_data{string, size, capacity}
{}
explicit BasicSmallString(SmallStringView stringView) noexcept
: BasicSmallString(stringView.data(), stringView.size(), stringView.size())
@@ -126,7 +118,7 @@ public:
~BasicSmallString() noexcept
{
if (Q_UNLIKELY(hasAllocatedMemory()))
Memory::deallocate(m_data.reference.pointer);
Memory::deallocate(m_data.data());
}
BasicSmallString(const BasicSmallString &other) noexcept
@@ -170,17 +162,6 @@ public:
}
BasicSmallString take() noexcept { return std::move(*this); }
BasicSmallString clone() const noexcept
{
BasicSmallString clonedString(m_data);
if (Q_UNLIKELY(hasAllocatedMemory()))
new (&clonedString) BasicSmallString{m_data.reference.pointer,
m_data.reference.size,
m_data.reference.capacity};
return clonedString;
}
friend void swap(BasicSmallString &first, BasicSmallString &second) noexcept
{
@@ -229,8 +210,8 @@ public:
{
if (fitsNotInCapacity(newCapacity)) {
if (Q_UNLIKELY(hasAllocatedMemory())) {
m_data.reference.pointer = Memory::reallocate(m_data.reference.pointer, newCapacity);
m_data.reference.capacity = newCapacity;
m_data.setPointer(Memory::reallocate(m_data.data(), newCapacity));
m_data.setAllocatedCapacity(newCapacity);
} else {
auto oldSize = size();
new (this) BasicSmallString{data(), oldSize, std::max(newCapacity, oldSize)};
@@ -252,15 +233,9 @@ public:
m_data = Internal::StringDataLayout<Size>();
}
char *data() noexcept
{
return Q_LIKELY(isShortString()) ? m_data.shortString : m_data.reference.pointer;
}
char *data() noexcept { return m_data.data(); }
const char *data() const noexcept
{
return Q_LIKELY(isShortString()) ? m_data.shortString : m_data.reference.pointer;
}
const char *data() const noexcept { return m_data.data(); }
iterator begin() noexcept
{
@@ -387,21 +362,9 @@ public:
return at(size() - 1) == character;
}
size_type size() const noexcept
{
if (!isShortString())
return m_data.reference.size;
size_type size() const noexcept { return m_data.size(); }
return m_data.control.shortStringSize();
}
size_type capacity() const noexcept
{
if (!isShortString())
return m_data.reference.capacity;
return shortStringCapacity();
}
size_type capacity() const noexcept { return m_data.capacity(); }
bool isEmpty() const noexcept
{
@@ -608,11 +571,6 @@ public:
return size;
}
constexpr size_type shortStringSize() const noexcept
{
return m_data.control.shortStringSize();
}
static BasicSmallString join(std::initializer_list<SmallStringView> list,
Utils::SmallStringView separator) noexcept
{
@@ -708,17 +666,12 @@ public:
}
unittest_public:
constexpr
bool isShortString() const noexcept
constexpr bool isShortString() const noexcept
{
return m_data.control.isShortString();
return m_data.isShortString();
}
constexpr
bool isReadOnlyReference() const noexcept
{
return m_data.control.isReadOnlyReference();
}
constexpr bool isReadOnlyReference() const noexcept { return m_data.isReadOnlyReference(); }
constexpr
bool hasAllocatedMemory() const noexcept
@@ -728,10 +681,7 @@ unittest_public:
bool fitsNotInCapacity(size_type capacity) const noexcept
{
if (isShortString())
return capacity > shortStringCapacity();
return capacity > m_data.reference.capacity;
return capacity > m_data.capacity();
}
static size_type optimalHeapCapacity(const size_type size) noexcept
@@ -790,13 +740,6 @@ private:
}
}
constexpr void initializeLongString(char *pointer, size_type size, size_type capacity) noexcept
{
m_data.control = Internal::ControlBlock<Size>(0, false, true);
m_data.reference.pointer = pointer;
m_data.reference.size = size;
m_data.reference.capacity = capacity;
}
char &at(size_type index) noexcept { return *(data() + index); }
@@ -922,13 +865,7 @@ private:
}
}
void setSize(size_type size) noexcept
{
if (isShortString())
m_data.control.setShortStringSize(size);
else
m_data.reference.size = size;
}
void setSize(size_type size) noexcept { m_data.setSize(size); }
private:
Internal::StringDataLayout<Size> m_data;
@@ -962,7 +899,7 @@ Type clone(const Type &vector)
}
using SmallString = BasicSmallString<31>;
using PathString = BasicSmallString<190>;
using PathString = BasicSmallString<176>;
inline SmallString operator+(SmallStringView first, SmallStringView second) noexcept
{

View File

@@ -17,6 +17,6 @@ class SmallStringView;
template <uint Size>
class BasicSmallString;
using SmallString = BasicSmallString<31>;
using PathString = BasicSmallString<190>;
using PathString = BasicSmallString<176>;
} // namespace Utils

View File

@@ -3,6 +3,8 @@
#pragma once
#include "smallstringmemory.h"
#include <QtGlobal>
#include <algorithm>
@@ -110,7 +112,27 @@ struct alignas(16) StringDataLayout
}
}
constexpr static size_type shortStringCapacity() noexcept
StringDataLayout(const char *string, size_type size, size_type capacity) noexcept
{
if (Q_LIKELY(capacity <= shortStringCapacity())) {
control = Internal::ControlBlock<MaximumShortStringDataAreaSize>(size, false, false);
std::char_traits<char>::copy(shortString, string, size);
} else {
auto pointer = Memory::allocate(capacity);
std::char_traits<char>::copy(pointer, string, size);
initializeLongString(pointer, size, capacity);
}
}
constexpr void initializeLongString(char *pointer, size_type size, size_type capacity) noexcept
{
control = Internal::ControlBlock<MaximumShortStringDataAreaSize>(0, false, true);
reference.pointer = pointer;
reference.size = size;
reference.capacity = capacity;
}
static constexpr size_type shortStringCapacity() noexcept
{
return MaximumShortStringDataAreaSize;
}
@@ -126,6 +148,45 @@ struct alignas(16) StringDataLayout
#endif
}
void setSize(size_type size) noexcept
{
if (isShortString())
control.setShortStringSize(size);
else
reference.size = size;
}
size_type size() const noexcept
{
if (!control.isShortString())
return reference.size;
return control.shortStringSize();
}
bool isShortString() const noexcept { return control.isShortString(); }
size_type capacity() const noexcept
{
if (!isShortString())
return reference.capacity;
return shortStringCapacity();
}
constexpr bool isReadOnlyReference() const noexcept { return control.isReadOnlyReference(); }
char *data() noexcept { return Q_LIKELY(isShortString()) ? shortString : reference.pointer; }
const char *data() const noexcept
{
return Q_LIKELY(isShortString()) ? shortString : reference.pointer;
}
void setPointer(char *p) noexcept { reference.pointer = p; }
void setAllocatedCapacity(size_type capacity) noexcept { reference.capacity = capacity; }
union {
struct
{
@@ -145,45 +206,46 @@ struct alignas(16) StringDataLayout<MaximumShortStringDataAreaSize,
std::enable_if_t<MaximumShortStringDataAreaSize >= 32>>
{
static_assert(MaximumShortStringDataAreaSize > 31, "Size must be greater than 31 bytes!");
static_assert(MaximumShortStringDataAreaSize < 64
? ((MaximumShortStringDataAreaSize + 1) % 16) == 0
: ((MaximumShortStringDataAreaSize + 2) % 16) == 0,
"Size + 1 must be dividable by 16 if under 64 and Size + 2 must be dividable by "
"16 if over 64!");
static_assert(((MaximumShortStringDataAreaSize + 16) % 16) == 0,
"Size + 16 must be dividable by 16!");
constexpr StringDataLayout() noexcept { reset(); }
constexpr StringDataLayout(const char *string, size_type size) noexcept
: controlReference{0, true, true}
, reference{{string}, size, 0}
: constPointer{string}
, size_{static_cast<int>(size)}
, capacity_{0}
{}
template<size_type Size>
constexpr StringDataLayout(const char (&string)[Size]) noexcept
{
constexpr auto size = Size - 1;
constexpr size_type size = Size - 1;
size_ = size;
if constexpr (size <= MaximumShortStringDataAreaSize) {
control = {size, false, false};
pointer = buffer;
capacity_ = MaximumShortStringDataAreaSize;
for (size_type i = 0; i < size; ++i)
shortString[i] = string[i];
buffer[i] = string[i];
#if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
if (std::is_constant_evaluated()) {
for (size_type i = size; i < MaximumShortStringDataAreaSize; ++i)
shortString[i] = 0;
buffer[i] = 0;
}
#endif
} else {
control = {0, true, true};
reference = {{string}, size, 0};
constPointer = string;
capacity_ = 0;
}
}
void copyHere(const StringDataLayout &other) noexcept
{
constexpr auto controlBlockSize = sizeof(ControlBlock<MaximumShortStringDataAreaSize>);
auto shortStringLayoutSize = other.control.stringSize() + controlBlockSize;
constexpr auto referenceLayoutSize = sizeof(ReferenceLayout);
std::memcpy(this, &other, std::max(shortStringLayoutSize, referenceLayoutSize));
auto isShortString = other.isShortString();
auto shortStringSize = isShortString ? other.size() : 0;
auto areaSize = 8 + shortStringSize;
pointer = isShortString ? buffer : other.pointer;
std::memcpy(&size_, &other.size_, areaSize);
}
StringDataLayout(const StringDataLayout &other) noexcept { copyHere(other); }
@@ -195,6 +257,18 @@ struct alignas(16) StringDataLayout<MaximumShortStringDataAreaSize,
return *this;
}
StringDataLayout(const char *string, size_type size, size_type capacity) noexcept
: size_{static_cast<int>(size)}
, capacity_{static_cast<int>(capacity)}
{
if (Q_LIKELY(capacity <= shortStringCapacity())) {
std::char_traits<char>::copy(buffer, string, size);
pointer = buffer;
} else {
pointer = Memory::allocate(capacity);
std::char_traits<char>::copy(pointer, string, size);
}
}
constexpr static size_type shortStringCapacity() noexcept
{
return MaximumShortStringDataAreaSize;
@@ -202,27 +276,39 @@ struct alignas(16) StringDataLayout<MaximumShortStringDataAreaSize,
constexpr void reset() noexcept
{
control = ControlBlock<MaximumShortStringDataAreaSize>();
#if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
if (std::is_constant_evaluated()) {
for (size_type i = 0; i < MaximumShortStringDataAreaSize; ++i)
shortString[i] = 0;
}
#endif
pointer = nullptr;
size_ = 0;
capacity_ = MaximumShortStringDataAreaSize;
}
void setSize(size_type size) noexcept { size_ = size; }
size_type size() const noexcept { return size_; }
bool isShortString() const noexcept { return pointer == buffer; }
size_type capacity() const noexcept { return capacity_; }
constexpr bool isReadOnlyReference() const noexcept { return capacity_ == 0; }
char *data() noexcept { return pointer; }
const char *data() const noexcept { return constPointer; }
void setPointer(char *p) noexcept { pointer = p; }
void setAllocatedCapacity(size_type capacity) noexcept { capacity_ = capacity; }
constexpr size_type shortStringSize() const noexcept { return size_; }
union {
struct
{
ControlBlock<MaximumShortStringDataAreaSize> control;
char shortString[MaximumShortStringDataAreaSize];
};
struct
{
ControlBlock<MaximumShortStringDataAreaSize> controlReference;
ReferenceLayout reference;
};
char *pointer;
const char *constPointer;
};
int size_;
int capacity_;
char buffer[MaximumShortStringDataAreaSize];
};
} // namespace Internal

View File

@@ -128,6 +128,6 @@ private:
using SmallStringVector = BasicSmallStringVector<BasicSmallString<31>>;
using PathStringVector = BasicSmallStringVector<BasicSmallString<190>>;
using PathStringVector = BasicSmallStringVector<BasicSmallString<176>>;
using StringViewVector = BasicSmallStringVector<SmallStringView>;
} // namespace Utils;

View File

@@ -242,7 +242,7 @@ struct TypeTraits
static_assert(sizeof(TypeTraits) == sizeof(unsigned int) * 2,
"TypeTraits must be of size unsigned long long!");
using TypeNameString = ::Utils::BasicSmallString<63>;
using TypeNameString = ::Utils::BasicSmallString<64>;
class VersionNumber
{
@@ -374,7 +374,7 @@ struct ItemLibraryProperty
using ItemLibraryProperties = QVarLengthArray<ItemLibraryProperty, 5>;
using ToolTipString = Utils::BasicSmallString<94>;
using ToolTipString = Utils::BasicSmallString<96>;
struct ItemLibraryEntry
{

View File

@@ -47,7 +47,7 @@ public:
}
explicit SourcePath(const Utils::PathString &sourcePath)
: SourcePath(sourcePath.clone())
: SourcePath(Utils::PathString{sourcePath})
{
}

View File

@@ -157,7 +157,7 @@ void PrintTo(const Utils::SmallString &text, ::std::ostream *os)
*os << "\"" << text << "\"";
}
void PrintTo(const Utils::BasicSmallString<94> &text, ::std::ostream *os)
void PrintTo(const Utils::BasicSmallString<96> &text, ::std::ostream *os)
{
*os << "\"" << text << "\"";
}

View File

@@ -93,7 +93,7 @@ void PrintTo(const std::optional<Type> &optional, ::std::ostream *os)
void PrintTo(Utils::SmallStringView text, ::std::ostream *os);
void PrintTo(const Utils::SmallString &text, ::std::ostream *os);
void PrintTo(const Utils::BasicSmallString<94> &text, ::std::ostream *os);
void PrintTo(const Utils::BasicSmallString<96> &text, ::std::ostream *os);
void PrintTo(const Utils::PathString &text, ::std::ostream *os);
} // namespace Utils

View File

@@ -214,10 +214,10 @@ TYPED_TEST(StorageCache, populate_with_empty_vector)
TYPED_TEST(StorageCache, is_not_empty_after_populate_with_some_entries)
{
typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1},
{this->filePath2.clone(), this->id4},
{this->filePath3.clone(), this->id3},
{this->filePath4.clone(), SourceContextId::create(5)}};
typename TypeParam::CacheEntries entries{{this->filePath1, this->id1},
{this->filePath2, this->id4},
{this->filePath3, this->id3},
{this->filePath4, SourceContextId::create(5)}};
ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries));
this->cache.uncheckedPopulate();
@@ -227,10 +227,10 @@ TYPED_TEST(StorageCache, is_not_empty_after_populate_with_some_entries)
TYPED_TEST(StorageCache, get_entry_after_populate_with_some_entries)
{
typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1},
{this->filePath2.clone(), this->id2},
{this->filePath3.clone(), SourceContextId::create(7)},
{this->filePath4.clone(), this->id4}};
typename TypeParam::CacheEntries entries{{this->filePath1, this->id1},
{this->filePath2, this->id2},
{this->filePath3, SourceContextId::create(7)},
{this->filePath4, this->id4}};
ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries));
this->cache.uncheckedPopulate();
@@ -241,10 +241,10 @@ TYPED_TEST(StorageCache, get_entry_after_populate_with_some_entries)
TYPED_TEST(StorageCache, entries_have_unique_ids)
{
typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1},
{this->filePath2.clone(), this->id2},
{this->filePath3.clone(), this->id3},
{this->filePath4.clone(), this->id3}};
typename TypeParam::CacheEntries entries{{this->filePath1, this->id1},
{this->filePath2, this->id2},
{this->filePath3, this->id3},
{this->filePath4, this->id3}};
ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries));
ASSERT_THROW(this->cache.populate(), StorageCacheException);
@@ -252,10 +252,10 @@ TYPED_TEST(StorageCache, entries_have_unique_ids)
TYPED_TEST(StorageCache, multiple_entries)
{
typename TypeParam::CacheEntries entries{{this->filePath1.clone(), this->id1},
{this->filePath1.clone(), this->id2},
{this->filePath3.clone(), this->id3},
{this->filePath4.clone(), this->id4}};
typename TypeParam::CacheEntries entries{{this->filePath1, this->id1},
{this->filePath1, this->id2},
{this->filePath3, this->id3},
{this->filePath4, this->id4}};
ON_CALL(this->mockStorage, fetchAllSourceContexts()).WillByDefault(Return(entries));
ASSERT_THROW(this->cache.populate(), StorageCacheException);

View File

@@ -40,7 +40,7 @@ TEST_F(SqliteTable, column_is_added_to_table)
TEST_F(SqliteTable, set_table_name)
{
table.setName(tableName.clone());
table.setName(tableName);
ASSERT_THAT(table.name(), tableName);
}
@@ -54,7 +54,7 @@ TEST_F(SqliteTable, set_use_without_rowid)
TEST_F(SqliteTable, add_index)
{
table.setName(tableName.clone());
table.setName(tableName);
auto &column = table.addColumn("name");
auto &column2 = table.addColumn("value");
@@ -67,7 +67,7 @@ TEST_F(SqliteTable, add_index)
TEST_F(SqliteTable, initialize_table)
{
table.setName(tableName.clone());
table.setName(tableName);
table.setUseIfNotExists(true);
table.setUseTemporaryTable(true);
table.setUseWithoutRowId(true);
@@ -84,7 +84,7 @@ TEST_F(SqliteTable, initialize_table)
TEST_F(SqliteTable, initialize_table_with_index)
{
InSequence sequence;
table.setName(tableName.clone());
table.setName(tableName);
auto &column = table.addColumn("name");
auto &column2 = table.addColumn("value");
table.addIndex({column});
@@ -104,7 +104,7 @@ TEST_F(SqliteTable, initialize_table_with_index)
TEST_F(SqliteTable, initialize_table_with_unique_index)
{
InSequence sequence;
table.setName(tableName.clone());
table.setName(tableName);
auto &column = table.addColumn("name");
auto &column2 = table.addColumn("value");
table.addUniqueIndex({column});
@@ -302,7 +302,7 @@ TEST_F(SqliteTable, add_foreign_key_column_with_column_and_not_null)
TEST_F(SqliteTable, add_primary_table_contraint)
{
table.setName(tableName.clone());
table.setName(tableName);
const auto &idColumn = table.addColumn("id");
const auto &nameColumn = table.addColumn("name");
table.addPrimaryKeyContraint({idColumn, nameColumn});
@@ -331,7 +331,7 @@ TEST_F(StrictSqliteTable, column_is_added_to_table)
TEST_F(StrictSqliteTable, set_table_name)
{
table.setName(tableName.clone());
table.setName(tableName);
ASSERT_THAT(table.name(), tableName);
}
@@ -345,7 +345,7 @@ TEST_F(StrictSqliteTable, set_use_without_rowid)
TEST_F(StrictSqliteTable, add_index)
{
table.setName(tableName.clone());
table.setName(tableName);
auto &column = table.addColumn("name");
auto &column2 = table.addColumn("value");
@@ -358,7 +358,7 @@ TEST_F(StrictSqliteTable, add_index)
TEST_F(StrictSqliteTable, initialize_table)
{
table.setName(tableName.clone());
table.setName(tableName);
table.setUseIfNotExists(true);
table.setUseTemporaryTable(true);
table.setUseWithoutRowId(true);
@@ -375,7 +375,7 @@ TEST_F(StrictSqliteTable, initialize_table)
TEST_F(StrictSqliteTable, initialize_table_with_index)
{
InSequence sequence;
table.setName(tableName.clone());
table.setName(tableName);
auto &column = table.addColumn("name");
auto &column2 = table.addColumn("value");
table.addIndex({column});
@@ -395,7 +395,7 @@ TEST_F(StrictSqliteTable, initialize_table_with_index)
TEST_F(StrictSqliteTable, initialize_table_with_unique_index)
{
InSequence sequence;
table.setName(tableName.clone());
table.setName(tableName);
auto &column = table.addColumn("name");
auto &column2 = table.addColumn("value");
table.addUniqueIndex({column});
@@ -599,7 +599,7 @@ TEST_F(StrictSqliteTable, add_foreign_key_column_with_column_and_not_null)
TEST_F(StrictSqliteTable, add_primary_table_contraint)
{
table.setName(tableName.clone());
table.setName(tableName);
const auto &idColumn = table.addColumn("id");
const auto &nameColumn = table.addColumn("name");
table.addPrimaryKeyContraint({idColumn, nameColumn});

View File

@@ -17,12 +17,12 @@ using Utils::SmallStringLiteral;
using Utils::SmallStringView;
static_assert(32 == sizeof(Utils::BasicSmallString<31>));
static_assert(64 == sizeof(Utils::BasicSmallString<63>));
static_assert(192 == sizeof(Utils::BasicSmallString<190>));
static_assert(80 == sizeof(Utils::BasicSmallString<64>));
static_assert(192 == sizeof(Utils::BasicSmallString<176>));
static_assert(16 == alignof(Utils::BasicSmallString<31>));
static_assert(16 == alignof(Utils::BasicSmallString<63>));
static_assert(16 == alignof(Utils::BasicSmallString<190>));
static_assert(16 == alignof(Utils::BasicSmallString<64>));
static_assert(16 == alignof(Utils::BasicSmallString<192>));
TEST(SmallString, basic_string_equal)
{
@@ -135,33 +135,6 @@ TEST(SmallString, long_const_expression_small_string_is_reference)
ASSERT_TRUE(longText.isReadOnlyReference());
}
TEST(SmallString, clone_short_small_string)
{
SmallString shortText("short string");
auto clonedText = shortText.clone();
ASSERT_THAT(clonedText, Eq("short string"));
}
TEST(SmallString, clone_long_small_string)
{
SmallString longText = SmallString::fromUtf8("very very very very very very very very very very very long string");
auto clonedText = longText.clone();
ASSERT_THAT(clonedText, Eq("very very very very very very very very very very very long string"));
}
TEST(SmallString, cloned_long_small_string_data_pointer_is_different)
{
SmallString longText = SmallString::fromUtf8("very very very very very very very very very very very long string");
auto clonedText = longText.clone();
ASSERT_THAT(clonedText.data(), Ne(longText.data()));
}
TEST(SmallString, copy_short_const_expression_small_string_is_short_small_string)
{
SmallString shortText("short string");
@@ -254,13 +227,6 @@ TEST(SmallString, long_data_access)
ASSERT_THAT(longText, StrEq(longCString));
}
TEST(SmallString, long_small_string_has_short_small_string_size_zero)
{
auto longText = SmallString::fromUtf8("very very very very very very very very very very very long string");
ASSERT_THAT(longText.shortStringSize(), 0);
}
TEST(SmallString, small_string_begin_is_equal_end_for_empty_small_string)
{
SmallString text;
@@ -1922,7 +1888,7 @@ TEST(SmallString, string_plus_operator_reverse_order)
TEST(SmallString, short_string_capacity)
{
ASSERT_THAT(SmallString().shortStringCapacity(), 31);
ASSERT_THAT(PathString().shortStringCapacity(), 190);
ASSERT_THAT(PathString().shortStringCapacity(), 176);
}
TEST(SmallString, to_view)