|
|
|
@ -152,7 +152,7 @@ private:
|
|
|
|
|
struct {
|
|
|
|
|
char* indirect;
|
|
|
|
|
size_type capacity;
|
|
|
|
|
};
|
|
|
|
|
} indirect_contents;
|
|
|
|
|
};
|
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
alignas(char*) direct_or_indirect _union = {};
|
|
|
|
@ -163,8 +163,8 @@ private:
|
|
|
|
|
|
|
|
|
|
T* direct_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.direct) + pos; }
|
|
|
|
|
const T* direct_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.direct) + pos; }
|
|
|
|
|
T* indirect_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.indirect) + pos; }
|
|
|
|
|
const T* indirect_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.indirect) + pos; }
|
|
|
|
|
T* indirect_ptr(difference_type pos) { return reinterpret_cast<T*>(_union.indirect_contents.indirect) + pos; }
|
|
|
|
|
const T* indirect_ptr(difference_type pos) const { return reinterpret_cast<const T*>(_union.indirect_contents.indirect) + pos; }
|
|
|
|
|
bool is_direct() const { return _size <= N; }
|
|
|
|
|
|
|
|
|
|
void change_capacity(size_type new_capacity) {
|
|
|
|
@ -182,17 +182,17 @@ private:
|
|
|
|
|
/* FIXME: Because malloc/realloc here won't call new_handler if allocation fails, assert
|
|
|
|
|
success. These should instead use an allocator or new/delete so that handlers
|
|
|
|
|
are called as necessary, but performance would be slightly degraded by doing so. */
|
|
|
|
|
_union.indirect = static_cast<char*>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity));
|
|
|
|
|
assert(_union.indirect);
|
|
|
|
|
_union.capacity = new_capacity;
|
|
|
|
|
_union.indirect_contents.indirect = static_cast<char*>(realloc(_union.indirect_contents.indirect, ((size_t)sizeof(T)) * new_capacity));
|
|
|
|
|
assert(_union.indirect_contents.indirect);
|
|
|
|
|
_union.indirect_contents.capacity = new_capacity;
|
|
|
|
|
} else {
|
|
|
|
|
char* new_indirect = static_cast<char*>(malloc(((size_t)sizeof(T)) * new_capacity));
|
|
|
|
|
assert(new_indirect);
|
|
|
|
|
T* src = direct_ptr(0);
|
|
|
|
|
T* dst = reinterpret_cast<T*>(new_indirect);
|
|
|
|
|
memcpy(dst, src, size() * sizeof(T));
|
|
|
|
|
_union.indirect = new_indirect;
|
|
|
|
|
_union.capacity = new_capacity;
|
|
|
|
|
_union.indirect_contents.indirect = new_indirect;
|
|
|
|
|
_union.indirect_contents.capacity = new_capacity;
|
|
|
|
|
_size += N + 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -301,7 +301,7 @@ public:
|
|
|
|
|
if (is_direct()) {
|
|
|
|
|
return N;
|
|
|
|
|
} else {
|
|
|
|
|
return _union.capacity;
|
|
|
|
|
return _union.indirect_contents.capacity;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -468,8 +468,8 @@ public:
|
|
|
|
|
clear();
|
|
|
|
|
}
|
|
|
|
|
if (!is_direct()) {
|
|
|
|
|
free(_union.indirect);
|
|
|
|
|
_union.indirect = nullptr;
|
|
|
|
|
free(_union.indirect_contents.indirect);
|
|
|
|
|
_union.indirect_contents.indirect = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -521,7 +521,7 @@ public:
|
|
|
|
|
if (is_direct()) {
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return ((size_t)(sizeof(T))) * _union.capacity;
|
|
|
|
|
return ((size_t)(sizeof(T))) * _union.indirect_contents.capacity;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|