mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-20 07:15:38 +00:00
FIFOQueue: Optimize PopRange() for trivially-copyable types
This commit is contained in:
parent
1963d80d2c
commit
da2dc5fa1e
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -71,7 +71,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// faster version of push_back_range for POD types which can be memcpy()ed
|
// faster version of push_back_range for POD types which can be memcpy()ed
|
||||||
template<class Y = T, std::enable_if_t<std::is_standard_layout_v<Y>&& std::is_trivial_v<Y>, int> = 0>
|
template<class Y = T, std::enable_if_t<std::is_standard_layout_v<Y> && std::is_trivial_v<Y>, int> = 0>
|
||||||
void PushRange(const T* data, u32 size)
|
void PushRange(const T* data, u32 size)
|
||||||
{
|
{
|
||||||
DebugAssert((m_size + size) <= CAPACITY);
|
DebugAssert((m_size + size) <= CAPACITY);
|
||||||
|
@ -137,10 +137,25 @@ public:
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Y = T, std::enable_if_t<std::is_standard_layout_v<Y> && std::is_trivial_v<Y>, int> = 0>
|
||||||
void PopRange(T* out_data, u32 count)
|
void PopRange(T* out_data, u32 count)
|
||||||
{
|
{
|
||||||
DebugAssert(m_size >= count);
|
DebugAssert(m_size >= count);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
const u32 contig_count = std::min(count, CAPACITY - m_head);
|
||||||
|
std::memcpy(out_data, &m_ptr[m_head], sizeof(T) * contig_count);
|
||||||
|
out_data += contig_count;
|
||||||
|
m_head = (m_head + contig_count) % CAPACITY;
|
||||||
|
m_size -= contig_count;
|
||||||
|
count -= contig_count;
|
||||||
|
} while (count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Y = T, std::enable_if_t<!std::is_standard_layout_v<Y> || !std::is_trivial_v<Y>, int> = 0>
|
||||||
|
void PopRange(T* out_data, u32 count)
|
||||||
|
{
|
||||||
|
DebugAssert(m_size >= count);
|
||||||
for (u32 i = 0; i < count; i++)
|
for (u32 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
out_data[i] = std::move(m_ptr[m_head]);
|
out_data[i] = std::move(m_ptr[m_head]);
|
||||||
|
|
Loading…
Reference in a new issue