better emplace implementation

This commit is contained in:
Richard Thier 2024-08-30 13:34:06 +02:00
parent 853f301b0f
commit 39a7d8effe

View File

@ -29,7 +29,7 @@ class TurboList {
uint32_t capacity;
TL_NOINLINE void grow_and_insert(T elem) noexcept {
TL_NOINLINE T& grow_and_insert(T elem) noexcept {
// assert(mid == 0);
if(old) FREE(old);
old = nex;
@ -38,7 +38,7 @@ class TurboList {
nex = (int *) MALLOC(this->capacity * sizeof(T));
// Will go into the INSERT code path here
insert(elem);
return insert(elem);
}
public:
@ -72,7 +72,7 @@ public:
}
}
inline void insert(T elem) noexcept {
inline T& insert(T elem) noexcept {
if(TL_LIKELY(end < capacity)) {
// INSERT
@ -87,17 +87,43 @@ public:
mid -= hasmid;
nex[mid] = hasmid ? old[mid] : nex[mid];
nex[end++] = elem;
return (nex[end++] = elem);
} else {
// GROW
grow_and_insert(elem);
return grow_and_insert(elem);
}
}
template<typename... Args>
inline void emplace(Args&&... args) {
// FIXME: placement new needed
insert(T(std::forward<Args>(args)...));
inline T& emplace(Args&&... args) {
if(TL_LIKELY(end < capacity)) {
// INSERT
/* Same as this:
if(mid > 0) {
nex[mid - 1] = old[mid - 1];
--mid;
}
*/
bool hasmid = (mid > 0);
mid -= hasmid;
nex[mid] = hasmid ? old[mid] : nex[mid];
// Placement new
return *new (nex + end++) T(std::forward<Args>(args)...);
} else {
// GROW
//
// Rem.: I just chose this to be less optimized than
// it is possible by making a copy and reusing
// the existing grow and insert code instead of
// writing a new "grow_and_emplace" again.
//
// This happens rarely so its probably fine and
// makes less template instantiations, smaller binary.
return grow_and_insert(T(std::forward<Args>(args)...));
}
}
inline uint32_t size() noexcept {