aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils/smallstringlayout.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/utils/smallstringlayout.h')
-rw-r--r--src/libs/utils/smallstringlayout.h176
1 files changed, 119 insertions, 57 deletions
diff --git a/src/libs/utils/smallstringlayout.h b/src/libs/utils/smallstringlayout.h
index 3a93fe8805..5f1406951e 100644
--- a/src/libs/utils/smallstringlayout.h
+++ b/src/libs/utils/smallstringlayout.h
@@ -28,113 +28,162 @@
#include <QtGlobal>
#include <cstdint>
+#include <memory>
#include <type_traits>
-#if defined(Q_CC_MSVC) && !defined(_WIN64)
-# define ALIGNAS_16
-#else
-# define ALIGNAS_16 alignas(16)
-#endif
-
namespace Utils {
namespace Internal {
using size_type = std::size_t;
-template<bool Bool>
-struct block_type
+template <uint MaximumShortStringDataAreaSize,
+ typename ControlType = typename std::conditional_t<(MaximumShortStringDataAreaSize < 64), uint8_t, uint16_t>>
+struct ControlBlock
{
- using type = uint8_t;
-};
+ using SizeType = ControlType;
+ constexpr ControlBlock() noexcept = default;
+ constexpr ControlBlock(ControlType shortStringSize, bool isReadOnlyReference, bool isReference) noexcept
+ : m_shortStringSize(shortStringSize),
+ m_isReadOnlyReference(isReadOnlyReference),
+ m_isReference(isReference)
+ {}
+
+ void setShortStringSize(size_type size)
+ {
+ m_shortStringSize = static_cast<SizeType>(size);
+ }
+
+ size_type shortStringSize() const
+ {
+ return m_shortStringSize;
+ }
+
+ void setIsReadOnlyReference(bool isReadOnlyReference)
+ {
+ m_isReadOnlyReference = isReadOnlyReference;
+ }
+
+ void setIsReference(bool isReference)
+ {
+ m_isReference = isReference;
+ }
-template<>
-struct block_type<false> {
- using type = uint16_t;
+ void setIsShortString(bool isShortString)
+ {
+ m_isReference = !isShortString;
+ }
+
+ constexpr
+ SizeType stringSize() const
+ {
+ return m_shortStringSize;
+ }
+
+ constexpr
+ bool isReadOnlyReference() const
+ {
+ return m_isReadOnlyReference;
+ }
+
+ constexpr
+ bool isReference() const
+ {
+ return m_isReference;
+ }
+
+ constexpr
+ bool isShortString() const
+ {
+ return !m_isReference;
+ }
+
+private:
+ ControlType m_shortStringSize : (sizeof(ControlType) * 8) - 2;
+ ControlType m_isReadOnlyReference : 1;
+ ControlType m_isReference : 1;
};
-template <uint MaximumShortStringDataAreaSize,
- typename BlockType = typename block_type<(MaximumShortStringDataAreaSize < 64)>::type>
-struct AllocatedLayout {
- struct Data {
+template <uint MaximumShortStringDataAreaSize>
+struct AllocatedLayout
+{
+ struct Data
+ {
char *pointer;
size_type size;
size_type capacity;
- } data;
- char dummy[MaximumShortStringDataAreaSize - sizeof(Data)];
- BlockType shortStringSize : (sizeof(BlockType) * 8) - 2;
- BlockType isReadOnlyReference : 1;
- BlockType isReference : 1;
+ };
+
+ ControlBlock<MaximumShortStringDataAreaSize> control;
+ Data data;
};
-template <uint MaximumShortStringDataAreaSize,
- typename BlockType = typename block_type<(MaximumShortStringDataAreaSize < 64)>::type>
-struct ReferenceLayout {
- struct Data {
+template <uint MaximumShortStringDataAreaSize>
+struct ReferenceLayout
+{
+ constexpr ReferenceLayout() noexcept = default;
+ constexpr ReferenceLayout(const char *stringPointer,
+ size_type size,
+ size_type capacity) noexcept
+ : control(0, true, true),
+ data{stringPointer, size, capacity}
+ {}
+
+ struct Data
+ {
const char *pointer;
size_type size;
size_type capacity;
- } data;
- char dummy[MaximumShortStringDataAreaSize - sizeof(Data)];
- BlockType shortStringSize : (sizeof(BlockType) * 8) - 2;
- BlockType isReadOnlyReference : 1;
- BlockType isReference : 1;
+ };
+
+ ControlBlock<MaximumShortStringDataAreaSize> control;
+ Data data;
};
-template <uint MaximumShortStringDataAreaSize,
- typename BlockType = typename block_type<(MaximumShortStringDataAreaSize < 64)>::type>
-struct ShortStringLayout {
+template <uint MaximumShortStringDataAreaSize>
+struct ShortStringLayout
+{
+ ControlBlock<MaximumShortStringDataAreaSize> control;
char string[MaximumShortStringDataAreaSize];
- BlockType shortStringSize : (sizeof(BlockType) * 8) - 2;
- BlockType isReadOnlyReference : 1;
- BlockType isReference : 1;
};
template <uint MaximumShortStringDataAreaSize>
-struct ALIGNAS_16 StringDataLayout {
+struct StringDataLayout {
static_assert(MaximumShortStringDataAreaSize >= 15, "Size must be greater equal than 15 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!");
- constexpr StringDataLayout() noexcept = default;
+ constexpr
+ StringDataLayout() noexcept
+ {
+ reset();
+ }
constexpr StringDataLayout(const char *string,
size_type size) noexcept
- : reference({{string, size, 0}, {}, 0, true, true})
+ : reference(string, size, 0)
{
}
template<size_type Size,
typename std::enable_if_t<Size <= MaximumShortStringDataAreaSize, int> = 0>
- constexpr StringDataLayout(const char(&string)[Size]) noexcept
-#if __cpp_constexpr < 201304
- : reference({{string, Size - 1, 0}, {}, 0, true, true})
-#else
+ StringDataLayout(const char(&string)[Size]) noexcept
: shortString(ShortStringLayout<MaximumShortStringDataAreaSize>{})
-#endif
{
-#if __cpp_constexpr >= 201304
for (size_type i = 0; i < Size; ++i)
shortString.string[i] = string[i];
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Woverflow"
- shortString.shortStringSize = std::uint8_t(Size) - 1;
-#pragma GCC diagnostic pop
-#endif
- shortString.isReference = false;
- shortString.isReadOnlyReference = false;
-
-#endif
+ shortString.control.setShortStringSize(Size - 1);
+ shortString.control.setIsShortString(true);
+ shortString.control.setIsReadOnlyReference(false);
}
template<size_type Size,
typename std::enable_if_t<!(Size <= MaximumShortStringDataAreaSize), int> = 1>
constexpr StringDataLayout(const char(&string)[Size]) noexcept
- : reference({{string, Size - 1, 0}, {}, 0, true, true})
+ : reference(string, Size - 1, 0)
{
}
@@ -144,6 +193,19 @@ struct ALIGNAS_16 StringDataLayout {
return MaximumShortStringDataAreaSize - 1;
}
+ void reset()
+ {
+ shortString.control = ControlBlock<MaximumShortStringDataAreaSize>();
+ shortString.string[0] = '\0';
+ }
+
+ StringDataLayout &operator=(const StringDataLayout &other)
+ {
+ this->shortString = other.shortString;
+
+ return *this;
+ }
+
union {
AllocatedLayout<MaximumShortStringDataAreaSize> allocated;
ReferenceLayout<MaximumShortStringDataAreaSize> reference;