[ATL] Add CAtlList::SwapElements

This commit is contained in:
Mark Jansen 2023-04-12 23:25:36 +02:00
parent 9d7d3314b3
commit 08d808cc44
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
2 changed files with 112 additions and 6 deletions

View file

@ -14,9 +14,10 @@
#include <atlbase.h>
#include <atlcoll.h>
#include <atlstr.h>
START_TEST(CAtlList)
static void
test_BasicCases()
{
CAtlList<int> list1;
@ -54,3 +55,67 @@ START_TEST(CAtlList)
}
ok(it == NULL, "it does still point to something!\n");
}
static CStringW
to_str(const CAtlList<int>& lst)
{
CStringW tmp;
POSITION it = lst.GetHeadPosition();
while (it != NULL)
{
int value = lst.GetNext(it);
tmp.AppendFormat(L"%d,", value);
}
return tmp;
}
#define ok_list(lst, expected) \
do \
{ \
CStringW _value = to_str(lst); \
ok(_value == (expected), "Wrong value for '%s', expected: " #expected " got: \"%S\"\n", #lst, \
_value.GetString()); \
} while (0)
static void
test_SwapElements()
{
CAtlList<int> list;
list.AddTail(1);
list.AddTail(2);
list.AddTail(3);
ok_list(list, "1,2,3,");
POSITION p1 = list.FindIndex(0);
POSITION p2 = list.FindIndex(2);
list.SwapElements(p1, p1);
ok_list(list, "1,2,3,");
list.SwapElements(p1, p2);
ok_list(list, "3,2,1,");
p1 = list.FindIndex(0);
p2 = list.FindIndex(1);
list.SwapElements(p1, p2);
ok_list(list, "2,3,1,");
p1 = list.FindIndex(1);
p2 = list.FindIndex(2);
list.SwapElements(p1, p2);
ok_list(list, "2,1,3,");
p1 = list.FindIndex(0);
p2 = list.FindIndex(2);
list.SwapElements(p2, p1);
ok_list(list, "3,1,2,");
}
START_TEST(CAtlList)
{
test_BasicCases();
test_SwapElements();
}

View file

@ -494,6 +494,8 @@ public:
_In_opt_ POSITION posStartAfter = NULL) const;
POSITION FindIndex(_In_ size_t iElement) const;
void SwapElements(POSITION pos1, POSITION pos2);
private:
CNode* CreateNode(
INARGTYPE element,
@ -809,6 +811,45 @@ POSITION CAtlList< E, ETraits >::FindIndex(_In_ size_t iElement) const
return (POSITION)Node;
}
template<typename E, class ETraits>
void CAtlList< E, ETraits >::SwapElements(POSITION pos1, POSITION pos2)
{
if (pos1 == pos2)
return;
CNode *node1 = (CNode *)pos1;
CNode *node2 = (CNode *)pos2;
CNode *tmp = node1->m_Prev;
node1->m_Prev = node2->m_Prev;
node2->m_Prev = tmp;
if (node1->m_Prev)
node1->m_Prev->m_Next = node1;
else
m_HeadNode = node1;
if (node2->m_Prev)
node2->m_Prev->m_Next = node2;
else
m_HeadNode = node2;
tmp = node1->m_Next;
node1->m_Next = node2->m_Next;
node2->m_Next = tmp;
if (node1->m_Next)
node1->m_Next->m_Prev = node1;
else
m_TailNode = node1;
if (node2->m_Next)
node2->m_Next->m_Prev = node2;
else
m_TailNode = node2;
}
//
// CAtlist private methods