better emplace implementation
This commit is contained in:
parent
853f301b0f
commit
39a7d8effe
@ -29,7 +29,7 @@ class TurboList {
|
|||||||
|
|
||||||
uint32_t capacity;
|
uint32_t capacity;
|
||||||
|
|
||||||
TL_NOINLINE void grow_and_insert(T elem) noexcept {
|
TL_NOINLINE T& grow_and_insert(T elem) noexcept {
|
||||||
// assert(mid == 0);
|
// assert(mid == 0);
|
||||||
if(old) FREE(old);
|
if(old) FREE(old);
|
||||||
old = nex;
|
old = nex;
|
||||||
@ -38,7 +38,7 @@ class TurboList {
|
|||||||
nex = (int *) MALLOC(this->capacity * sizeof(T));
|
nex = (int *) MALLOC(this->capacity * sizeof(T));
|
||||||
|
|
||||||
// Will go into the INSERT code path here
|
// Will go into the INSERT code path here
|
||||||
insert(elem);
|
return insert(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -72,7 +72,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void insert(T elem) noexcept {
|
inline T& insert(T elem) noexcept {
|
||||||
if(TL_LIKELY(end < capacity)) {
|
if(TL_LIKELY(end < capacity)) {
|
||||||
|
|
||||||
// INSERT
|
// INSERT
|
||||||
@ -87,17 +87,43 @@ public:
|
|||||||
mid -= hasmid;
|
mid -= hasmid;
|
||||||
nex[mid] = hasmid ? old[mid] : nex[mid];
|
nex[mid] = hasmid ? old[mid] : nex[mid];
|
||||||
|
|
||||||
nex[end++] = elem;
|
return (nex[end++] = elem);
|
||||||
} else {
|
} else {
|
||||||
// GROW
|
// GROW
|
||||||
grow_and_insert(elem);
|
return grow_and_insert(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
inline void emplace(Args&&... args) {
|
inline T& emplace(Args&&... args) {
|
||||||
// FIXME: placement new needed
|
if(TL_LIKELY(end < capacity)) {
|
||||||
insert(T(std::forward<Args>(args)...));
|
|
||||||
|
// 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 {
|
inline uint32_t size() noexcept {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user