Сначала я сделал небольшой класс-обёртку для этих функций...
Код: Выделить всё
class CSList
{
public:
CSList()
{
::InitializeSListHead(&m_head);
}
USHORT Depth()
{
return ::QueryDepthSList(&m_head);
}
PSLIST_ENTRY Flush()
{
return ::InterlockedFlushSList(&m_head);
}
PSLIST_ENTRY First()
{
return ::RtlFirstEntrySList(&m_head);
}
PSLIST_ENTRY Push(PSLIST_ENTRY ListEntry)
{
return ::InterlockedPushEntrySList(&m_head, ListEntry);
}
PSLIST_ENTRY Pop()
{
return ::InterlockedPopEntrySList(&m_head);
}
private:
SLIST_HEADER m_head;
};
// Documentation...
// https://msdn.microsoft.com/en-us/library/ms684121 - Interlocked Singly Linked Lists
Далее на основе этого класса я сделал простой шаблон стека.
Там же приведён пример его использования...
Код: Выделить всё
#include <iostream>
using namespace std;
template <typename T>
class TSimpleStack
{
public:
typedef struct DATA_ENTRY : SINGLE_LIST_ENTRY
{
T Data;
DATA_ENTRY(const T& val) : Data(val)
{
}
} *LPDATA_ENTRY;
~TSimpleStack()
{
// удаление элементов стека
while (m_list.Depth() > 0)
{
delete static_cast<LPDATA_ENTRY>(m_list.Pop());
}
}
USHORT Count()
{
return m_list.Depth();
}
LPDATA_ENTRY Push(const T& data)
{
LPDATA_ENTRY lpEntry = new DATA_ENTRY(data);
// Возвращает указатель на предыдущий элемент списка
return static_cast<LPDATA_ENTRY>(m_list.Push(lpEntry));
}
BOOL Pop(T& outVal)
{
BOOL bOut = FALSE;
if (m_list.Depth() > 0)
{
LPDATA_ENTRY lpEntry = static_cast<LPDATA_ENTRY>(m_list.Pop());
if (lpEntry != NULL)
{
outVal = lpEntry->Data;
delete lpEntry;
bOut = TRUE;
}
}
return bOut;
}
private:
CSList m_list;
};
int _tmain(int argc, _TCHAR* argv[])
{
TSimpleStack<long> sl;
sl.Push(10);
sl.Push(20);
sl.Push(50);
sl.Push(100);
sl.Push(500);
// вывод данных
long data (0);
while (sl.Pop(data))
{
cout << data << ' ';
}
_gettch();
return 0;
}
С уважением, ваш WinMain