diff --git a/modules/rostests/apitests/atl/CAtlList.cpp b/modules/rostests/apitests/atl/CAtlList.cpp index 8f83703b996..f9c2933beef 100644 --- a/modules/rostests/apitests/atl/CAtlList.cpp +++ b/modules/rostests/apitests/atl/CAtlList.cpp @@ -14,9 +14,10 @@ #include #include +#include - -START_TEST(CAtlList) +static void +test_BasicCases() { CAtlList list1; @@ -29,18 +30,18 @@ START_TEST(CAtlList) ok_size_t(list1.GetCount(), 3); list1.InsertBefore(head, -123); - list1.InsertAfter(head, 34); // no longer head, but the POSITION should still be valid.. + list1.InsertAfter(head, 34); // no longer head, but the POSITION should still be valid.. list1.InsertBefore(tail, 78); list1.InsertAfter(tail, -44); - int expected[] = {-123, 12, 34, 56, 78, 90, -44 }; + int expected[] = {-123, 12, 34, 56, 78, 90, -44}; int expected_size = sizeof(expected) / sizeof(expected[0]); int index = 0; POSITION it = list1.GetHeadPosition(); while (it != NULL) { - ok(index < expected_size, "Too many items, expected %d, got %d!\n", expected_size, (index+1)); + ok(index < expected_size, "Too many items, expected %d, got %d!\n", expected_size, (index + 1)); int value = list1.GetNext(it); if (index < expected_size) { @@ -54,3 +55,67 @@ START_TEST(CAtlList) } ok(it == NULL, "it does still point to something!\n"); } + +static CStringW +to_str(const CAtlList& 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 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(); +} diff --git a/sdk/lib/atl/atlcoll.h b/sdk/lib/atl/atlcoll.h index f41fee71bdf..66a93a27b7f 100644 --- a/sdk/lib/atl/atlcoll.h +++ b/sdk/lib/atl/atlcoll.h @@ -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 +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 @@ -897,4 +938,4 @@ private: } -#endif \ No newline at end of file +#endif