You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
301 lines
7.6 KiB
C++
301 lines
7.6 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
// Description : a small memory overhead, fixed size, efficient, iterable
|
|
// queue class used for CContextView SObjectClone
|
|
|
|
|
|
#ifndef CRYINCLUDE_CRYCOMMON_MINIQUEUE_H
|
|
#define CRYINCLUDE_CRYCOMMON_MINIQUEUE_H
|
|
#pragma once
|
|
|
|
|
|
// this class implements a very small queue of plain-old-data
|
|
template <typename T, uint8 N>
|
|
struct MiniQueue
|
|
{
|
|
public:
|
|
MiniQueue()
|
|
: m_nValues(0)
|
|
, m_nOffset(0) {}
|
|
|
|
MiniQueue(const MiniQueue& mq)
|
|
{
|
|
m_nValues = mq.m_nValues;
|
|
m_nOffset = 0;
|
|
for (int i = 0; i < m_nValues; i++)
|
|
{
|
|
m_vValues[i] = mq[i];
|
|
}
|
|
}
|
|
|
|
bool Empty() const
|
|
{
|
|
return m_nValues == 0;
|
|
}
|
|
bool Full() const
|
|
{
|
|
return m_nValues == N;
|
|
}
|
|
uint8 Size() const
|
|
{
|
|
return m_nValues;
|
|
}
|
|
uint8 Capacity() const
|
|
{
|
|
return N;
|
|
}
|
|
ILINE void Push(T nValue)
|
|
{
|
|
assert(!Full());
|
|
m_vValues[(m_nOffset + m_nValues) % N] = nValue;
|
|
m_nValues++;
|
|
}
|
|
// push, but if the queue is full, then pop first
|
|
void CyclePush(T nValue)
|
|
{
|
|
if (Full())
|
|
{
|
|
Pop();
|
|
}
|
|
Push(nValue);
|
|
}
|
|
void PushFront(T nValue)
|
|
{
|
|
assert(!Full());
|
|
m_nOffset = (m_nOffset + (N - 1)) % N;
|
|
m_vValues[m_nOffset] = nValue;
|
|
m_nValues++;
|
|
}
|
|
T Front() const
|
|
{
|
|
assert(!Empty());
|
|
return m_vValues[m_nOffset];
|
|
}
|
|
T& Front()
|
|
{
|
|
assert(!Empty());
|
|
return m_vValues[m_nOffset];
|
|
}
|
|
T& operator[](int i)
|
|
{
|
|
return m_vValues[(m_nOffset + i) % N];
|
|
}
|
|
T operator[](int i) const
|
|
{
|
|
return m_vValues[(m_nOffset + i) % N];
|
|
}
|
|
T Back() const
|
|
{
|
|
assert(!Empty());
|
|
return m_vValues[(m_nOffset + m_nValues - 1) % N];
|
|
}
|
|
T& Back()
|
|
{
|
|
assert(!Empty());
|
|
return m_vValues[(m_nOffset + m_nValues - 1) % N];
|
|
}
|
|
void Pop()
|
|
{
|
|
assert(!Empty());
|
|
m_nOffset = (m_nOffset + 1) % N;
|
|
m_nValues--;
|
|
}
|
|
void PopBack()
|
|
{
|
|
assert(!Empty());
|
|
m_nValues--;
|
|
}
|
|
void Clear()
|
|
{
|
|
m_nOffset = m_nValues = 0;
|
|
}
|
|
|
|
struct SIterator
|
|
{
|
|
public:
|
|
SIterator() {}
|
|
SIterator(T* pValues, uint8 nOffset)
|
|
: m_pValues(pValues)
|
|
, m_nOffset(nOffset) {}
|
|
T& operator*()
|
|
{
|
|
return m_pValues[m_nOffset % N];
|
|
}
|
|
T* operator->()
|
|
{
|
|
return &m_pValues[m_nOffset % N];
|
|
}
|
|
SIterator& operator++()
|
|
{
|
|
m_nOffset++;
|
|
return *this;
|
|
}
|
|
SIterator operator++(int)
|
|
{
|
|
SIterator itor = *this;
|
|
++m_nOffset;
|
|
return itor;
|
|
}
|
|
SIterator& operator--()
|
|
{
|
|
m_nOffset--;
|
|
return *this;
|
|
}
|
|
SIterator& operator+=(uint8 delta)
|
|
{
|
|
m_nOffset += delta;
|
|
return *this;
|
|
}
|
|
SIterator& operator-=(uint8 delta)
|
|
{
|
|
m_nOffset -= delta;
|
|
return *this;
|
|
}
|
|
|
|
friend bool operator!=(const SIterator& a, const SIterator& b)
|
|
{
|
|
assert(a.m_pValues == b.m_pValues);
|
|
return a.m_nOffset != b.m_nOffset;
|
|
}
|
|
friend bool operator==(const SIterator& a, const SIterator& b)
|
|
{
|
|
assert(a.m_pValues == b.m_pValues);
|
|
return a.m_nOffset == b.m_nOffset;
|
|
}
|
|
|
|
friend int operator-(const SIterator& a, const SIterator& b)
|
|
{
|
|
assert(a.m_pValues == b.m_pValues);
|
|
int diff = int(a.m_nOffset) - int(b.m_nOffset);
|
|
return diff;
|
|
}
|
|
|
|
uint8 Offset() { return m_nOffset; }
|
|
|
|
private:
|
|
T* m_pValues;
|
|
uint8 m_nOffset;
|
|
};
|
|
|
|
SIterator Begin() { return SIterator(m_vValues, m_nOffset); }
|
|
SIterator End() { return SIterator(m_vValues, m_nOffset + m_nValues); }
|
|
|
|
SIterator RBegin() { return SIterator(m_vValues, m_nOffset + m_nValues - 1); }
|
|
SIterator REnd() { return SIterator(m_vValues, m_nOffset - 1); }
|
|
|
|
struct SConstIterator
|
|
{
|
|
public:
|
|
SConstIterator() {}
|
|
SConstIterator(const T* pValues, uint8 nOffset)
|
|
: m_pValues(pValues)
|
|
, m_nOffset(nOffset) {}
|
|
const T& operator*()
|
|
{
|
|
return m_pValues[m_nOffset % N];
|
|
}
|
|
const T* operator->()
|
|
{
|
|
return &m_pValues[m_nOffset % N];
|
|
}
|
|
SConstIterator& operator++()
|
|
{
|
|
m_nOffset++;
|
|
return *this;
|
|
}
|
|
SConstIterator& operator--()
|
|
{
|
|
m_nOffset--;
|
|
return *this;
|
|
}
|
|
SConstIterator& operator+=(uint8 delta)
|
|
{
|
|
m_nOffset += delta;
|
|
return *this;
|
|
}
|
|
SConstIterator& operator-=(uint8 delta)
|
|
{
|
|
m_nOffset -= delta;
|
|
return *this;
|
|
}
|
|
friend bool operator!=(const SConstIterator& a, const SConstIterator& b)
|
|
{
|
|
assert(a.m_pValues == b.m_pValues);
|
|
return a.m_nOffset != b.m_nOffset;
|
|
}
|
|
friend bool operator==(const SConstIterator& a, const SConstIterator& b)
|
|
{
|
|
assert(a.m_pValues == b.m_pValues);
|
|
return a.m_nOffset == b.m_nOffset;
|
|
}
|
|
|
|
friend int operator-(const SConstIterator& a, const SConstIterator& b)
|
|
{
|
|
assert(a.m_pValues == b.m_pValues);
|
|
int diff = int(a.m_nOffset) - int(b.m_nOffset);
|
|
return diff;
|
|
}
|
|
|
|
uint8 Offset() { return m_nOffset; }
|
|
|
|
private:
|
|
const T* m_pValues;
|
|
uint8 m_nOffset;
|
|
};
|
|
|
|
SConstIterator Begin() const { return SConstIterator(m_vValues, m_nOffset); }
|
|
SConstIterator End() const { return SConstIterator(m_vValues, m_nOffset + m_nValues); }
|
|
|
|
SConstIterator RBegin() const { return SConstIterator(m_vValues, m_nOffset + m_nValues - 1); }
|
|
SConstIterator REnd() const { return SConstIterator(m_vValues, m_nOffset - 1); }
|
|
|
|
void Erase(SIterator where)
|
|
{
|
|
assert(where.Offset() >= m_nOffset);
|
|
assert(where.Offset() < m_nOffset + m_nValues);
|
|
for (size_t offset = where.Offset(); offset < (size_t)(m_nOffset + m_nValues - 1); offset++)
|
|
{
|
|
m_vValues[offset % N] = m_vValues[(offset + 1) % N];
|
|
}
|
|
m_nValues--;
|
|
}
|
|
|
|
void Erase(SIterator first, SIterator last)
|
|
{
|
|
int num = last - first;
|
|
if (num == 0)
|
|
{
|
|
return;
|
|
}
|
|
assert(num > 0);
|
|
assert(num <= Size());
|
|
assert(first.Offset() >= m_nOffset);
|
|
assert(first.Offset() < m_nOffset + m_nValues);
|
|
assert(last.Offset() >= m_nOffset);
|
|
assert(last.Offset() <= m_nOffset + m_nValues);
|
|
for (int offset = (int)first.Offset(); offset < m_nOffset + m_nValues - 1; offset++)
|
|
{
|
|
m_vValues[offset % N] = m_vValues[(offset + num) % N];
|
|
}
|
|
m_nValues -= num;
|
|
}
|
|
|
|
private:
|
|
uint8 m_nValues;
|
|
uint8 m_nOffset;
|
|
T m_vValues[N];
|
|
};
|
|
|
|
#endif // CRYINCLUDE_CRYCOMMON_MINIQUEUE_H
|