mirror of https://github.com/orefkov/simstr.git
Обход ошибки Clang - при компиляции clang-cl атрибуты empty_base и no_unique_address не уживаются между собой, и размер экземпляров sstring / lstring увеличивается на 8 (4) пустых байт, добавляемых в начале объекта.
This commit is contained in:
parent
2938a4188f
commit
7b6c184e60
|
|
@ -41,8 +41,10 @@ const bool isx64 = sizeof(void*) == 8; // NOLINT
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define _no_unique_address msvc::no_unique_address
|
#define _no_unique_address msvc::no_unique_address
|
||||||
|
#define empty_bases __declspec(empty_bases)
|
||||||
#else
|
#else
|
||||||
#define _no_unique_address no_unique_address
|
#define _no_unique_address no_unique_address
|
||||||
|
#define empty_bases
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined __has_builtin
|
#if defined __has_builtin
|
||||||
|
|
@ -1733,12 +1735,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#define empty_bases __declspec(empty_bases)
|
|
||||||
#else
|
|
||||||
#define empty_bases
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Базовая структура с информацией о строке.
|
* Базовая структура с информацией о строке.
|
||||||
* Это структура для невладеющих строк.
|
* Это структура для невладеющих строк.
|
||||||
|
|
@ -2311,24 +2307,21 @@ concept immutable_str = storable_str<A, K> && !mutable_str<A, K>;
|
||||||
* какой-либо пустой класс.
|
* какой-либо пустой класс.
|
||||||
*/
|
*/
|
||||||
template<typename K, typename Impl, typename Allocator>
|
template<typename K, typename Impl, typename Allocator>
|
||||||
class str_storable {
|
class str_storable : protected Allocator {
|
||||||
public:
|
public:
|
||||||
using my_type = Impl;
|
using my_type = Impl;
|
||||||
using traits = ch_traits<K>;
|
using traits = ch_traits<K>;
|
||||||
using allocator_t = Allocator;
|
using allocator_t = Allocator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
[[_no_unique_address]]
|
|
||||||
allocator_t allocator_;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Получить аллокатор
|
* @brief Получить аллокатор
|
||||||
*/
|
*/
|
||||||
allocator_t& allocator() {
|
allocator_t& allocator() {
|
||||||
return allocator_;
|
return *static_cast<Allocator*>(this);
|
||||||
}
|
}
|
||||||
const allocator_t& allocator() const {
|
const allocator_t& allocator() const {
|
||||||
return allocator_;
|
return *static_cast<const Allocator*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
using uni = unicode_traits<K>;
|
using uni = unicode_traits<K>;
|
||||||
|
|
@ -2341,7 +2334,7 @@ protected:
|
||||||
}
|
}
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
requires std::is_constructible_v<allocator_t, Args...>
|
requires std::is_constructible_v<allocator_t, Args...>
|
||||||
explicit constexpr str_storable(size_t size, Args&&... args) : allocator_(std::forward<Args>(args)...) {
|
explicit constexpr str_storable(size_t size, Args&&... args) : Allocator(std::forward<Args>(args)...) {
|
||||||
if (size)
|
if (size)
|
||||||
d().init(size);
|
d().init(size);
|
||||||
else
|
else
|
||||||
|
|
@ -2423,7 +2416,7 @@ public:
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
requires std::is_constructible_v<allocator_t, Args...>
|
requires std::is_constructible_v<allocator_t, Args...>
|
||||||
constexpr str_storable(Args&&... args) noexcept(std::is_nothrow_constructible_v<allocator_t, Args...>)
|
constexpr str_storable(Args&&... args) noexcept(std::is_nothrow_constructible_v<allocator_t, Args...>)
|
||||||
: allocator_(std::forward<Args>(args)...) {
|
: Allocator(std::forward<Args>(args)...) {
|
||||||
d().create_empty();
|
d().create_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2434,7 +2427,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
requires std::is_constructible_v<allocator_t, Args...>
|
requires std::is_constructible_v<allocator_t, Args...>
|
||||||
constexpr str_storable(s_str other, Args&&... args) : allocator_(std::forward<Args>(args)...) {
|
constexpr str_storable(s_str other, Args&&... args) : Allocator(std::forward<Args>(args)...) {
|
||||||
if (other.length()) {
|
if (other.length()) {
|
||||||
K* ptr = d().init(other.length());
|
K* ptr = d().init(other.length());
|
||||||
traits::copy(ptr, other.symbols(), other.length());
|
traits::copy(ptr, other.symbols(), other.length());
|
||||||
|
|
@ -2450,7 +2443,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
requires std::is_constructible_v<allocator_t, Args...>
|
requires std::is_constructible_v<allocator_t, Args...>
|
||||||
constexpr str_storable(size_t repeat, s_str pattern, Args&&... args) : allocator_(std::forward<Args>(args)...) {
|
constexpr str_storable(size_t repeat, s_str pattern, Args&&... args) : Allocator(std::forward<Args>(args)...) {
|
||||||
size_t l = pattern.length(), allLen = l * repeat;
|
size_t l = pattern.length(), allLen = l * repeat;
|
||||||
if (allLen) {
|
if (allLen) {
|
||||||
K* ptr = d().init(allLen);
|
K* ptr = d().init(allLen);
|
||||||
|
|
@ -2470,7 +2463,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
requires std::is_constructible_v<allocator_t, Args...>
|
requires std::is_constructible_v<allocator_t, Args...>
|
||||||
str_storable(size_t count, K pad, Args&&... args) : allocator_(std::forward<Args>(args)...) {
|
str_storable(size_t count, K pad, Args&&... args) : Allocator(std::forward<Args>(args)...) {
|
||||||
if (count) {
|
if (count) {
|
||||||
K* str = d().init(count);
|
K* str = d().init(count);
|
||||||
traits::assign(str, count, pad);
|
traits::assign(str, count, pad);
|
||||||
|
|
@ -2488,7 +2481,7 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
requires std::is_constructible_v<allocator_t, Args...>
|
requires std::is_constructible_v<allocator_t, Args...>
|
||||||
constexpr str_storable(const StrExprForType<K> auto& expr, Args&&... args) : allocator_(std::forward<Args>(args)...) {
|
constexpr str_storable(const StrExprForType<K> auto& expr, Args&&... args) : Allocator(std::forward<Args>(args)...) {
|
||||||
size_t len = expr.length();
|
size_t len = expr.length();
|
||||||
if (len)
|
if (len)
|
||||||
*expr.place(d().init(len)) = 0;
|
*expr.place(d().init(len)) = 0;
|
||||||
|
|
@ -2507,7 +2500,7 @@ public:
|
||||||
template<StrType<K> From, typename... Args>
|
template<StrType<K> From, typename... Args>
|
||||||
requires std::is_constructible_v<allocator_t, Args...>
|
requires std::is_constructible_v<allocator_t, Args...>
|
||||||
str_storable(const From& f, s_str pattern, s_str repl, size_t offset = 0, size_t maxCount = 0, Args&&... args)
|
str_storable(const From& f, s_str pattern, s_str repl, size_t offset = 0, size_t maxCount = 0, Args&&... args)
|
||||||
: allocator_(std::forward<Args>(args)...) {
|
: Allocator(std::forward<Args>(args)...) {
|
||||||
|
|
||||||
auto findes = f.find_all(pattern, offset, maxCount);
|
auto findes = f.find_all(pattern, offset, maxCount);
|
||||||
if (!findes.size()) {
|
if (!findes.size()) {
|
||||||
|
|
@ -4224,6 +4217,7 @@ constexpr const size_t local_count = _local_count<sizeof(size_t), sizeof(T)>;
|
||||||
* - для u16s - 32 байта, хранит строки до 15 символов + 0
|
* - для u16s - 32 байта, хранит строки до 15 символов + 0
|
||||||
* - для u32s - 32 байта, хранит строки до 7 символов + 0
|
* - для u32s - 32 байта, хранит строки до 7 символов + 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template<typename K, Allocatorable Allocator = allocator_string>
|
template<typename K, Allocatorable Allocator = allocator_string>
|
||||||
class empty_bases sstring :
|
class empty_bases sstring :
|
||||||
public str_algs<K, simple_str<K>, sstring<K, Allocator>, false>,
|
public str_algs<K, simple_str<K>, sstring<K, Allocator>, false>,
|
||||||
|
|
@ -5993,6 +5987,7 @@ using stringa = sstring<u8s>;
|
||||||
using stringw = sstring<wchar_t>;
|
using stringw = sstring<wchar_t>;
|
||||||
using stringu = sstring<u16s>;
|
using stringu = sstring<u16s>;
|
||||||
using stringuu = sstring<u32s>;
|
using stringuu = sstring<u32s>;
|
||||||
|
static_assert(sizeof(stringa) == 24, "Bad size of sstring");
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Тип хеш-словаря для char строк, регистрозависимый поиск
|
* @brief Тип хеш-словаря для char строк, регистрозависимый поиск
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue