https://git.reactos.org/?p=reactos.git;a=commitdiff;h=08d808cc444128dd652817425cf24767bac0ca0d

commit 08d808cc444128dd652817425cf24767bac0ca0d
Author:     Mark Jansen <[email protected]>
AuthorDate: Wed Apr 12 23:25:36 2023 +0200
Commit:     Mark Jansen <[email protected]>
CommitDate: Wed Apr 26 22:48:29 2023 +0200

    [ATL] Add CAtlList::SwapElements
---
 modules/rostests/apitests/atl/CAtlList.cpp | 75 ++++++++++++++++++++++++++++--
 sdk/lib/atl/atlcoll.h                      | 43 ++++++++++++++++-
 2 files changed, 112 insertions(+), 6 deletions(-)

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 <atlbase.h>
 #include <atlcoll.h>
+#include <atlstr.h>
 
-
-START_TEST(CAtlList)
+static void
+test_BasicCases()
 {
     CAtlList<int> 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<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();
+}
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<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
@@ -897,4 +938,4 @@ private:
 
 }
 
-#endif
\ No newline at end of file
+#endif

Reply via email to