Index: trunk/include/iprt/cpp/list.h
===================================================================
--- trunk/include/iprt/cpp/list.h	(revision 37829)
+++ trunk/include/iprt/cpp/list.h	(revision 37861)
@@ -219,5 +219,6 @@
       , m_cCapacity(0)
     {
-        realloc_grow(cCapacity);
+        if (cCapacity > 0)
+            realloc_grow(cCapacity);
     }
 
@@ -236,5 +237,5 @@
       , m_cCapacity(0)
     {
-        realloc_grow(other.m_cSize);
+        realloc_no_elements_clean(other.m_cSize);
         RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
         m_cSize = other.m_cSize;
@@ -372,8 +373,11 @@
     {
         m_guard.enterWrite();
-        if (m_cCapacity - m_cSize < other.m_cSize)
-            realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize)));
-        RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, m_cSize, other.m_cSize);
-        m_cSize += other.m_cSize;
+        if (RT_LIKELY(other.m_cSize > 0))
+        {
+            if (m_cCapacity - m_cSize < other.m_cSize)
+                realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize)));
+            RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, m_cSize, other.m_cSize);
+            m_cSize += other.m_cSize;
+        }
         m_guard.leaveWrite();
 
@@ -391,15 +395,15 @@
     {
         /* Prevent self assignment */
-        if (this == &other)
+        if (RT_UNLIKELY(this == &other))
             return *this;
 
         m_guard.enterWrite();
-        /* Values cleanup */
+        /* Delete all items. */
         RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
-
-        /* Copy */
+        /* Need we to realloc memory. */
         if (other.m_cSize != m_cCapacity)
-            realloc_grow(other.m_cSize);
+            realloc_no_elements_clean(other.m_cSize);
         m_cSize = other.m_cSize;
+        /* Copy new items. */
         RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
         m_guard.leaveWrite();
@@ -431,108 +435,108 @@
      * Return the first item as constant object.
      *
+     * @note No boundary checks are done. Make sure there is at least one
+     * element.
+     *
+     * @return   The first item.
+     */
+    GET_CRTYPE first() const
+    {
+        m_guard.enterRead();
+        GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
+        m_guard.leaveRead();
+        return res;
+    }
+
+    /**
+     * Return the first item.
+     *
+     * @note No boundary checks are done. Make sure there is at least one
+     * element.
+     *
+     * @return   The first item.
+     */
+    GET_RTYPE first()
+    {
+        m_guard.enterRead();
+        GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
+        m_guard.leaveRead();
+        return res;
+    }
+
+    /**
+     * Return the last item as constant object.
+     *
+     * @note No boundary checks are done. Make sure there is at least one
+     * element.
+     *
+     * @return   The last item.
+     */
+    GET_CRTYPE last() const
+    {
+        m_guard.enterRead();
+        GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
+        m_guard.leaveRead();
+        return res;
+    }
+
+    /**
+     * Return the last item.
+     *
+     * @note No boundary checks are done. Make sure there is at least one
+     * element.
+     *
+     * @return   The last item.
+     */
+    GET_RTYPE last()
+    {
+        m_guard.enterRead();
+        GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
+        m_guard.leaveRead();
+        return res;
+    }
+
+    /**
+     * Return the item at position @a i as constant object.
+     *
      * @note No boundary checks are done. Make sure @a i is equal or greater zero
      *       and smaller than RTCList::size.
      *
-     * @return   The first item.
-     */
-    GET_CRTYPE first() const
-    {
-        m_guard.enterRead();
-        GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
-        m_guard.leaveRead();
-        return res;
-    }
-
-    /**
-     * Return the first item.
+     * @param   i     The position of the item to return.
+     * @return  The item at position @a i.
+     */
+    GET_CRTYPE at(size_t i) const
+    {
+        m_guard.enterRead();
+        GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
+        m_guard.leaveRead();
+        return res;
+    }
+
+    /**
+     * Return the item at position @a i.
      *
      * @note No boundary checks are done. Make sure @a i is equal or greater zero
      *       and smaller than RTCList::size.
      *
-     * @return   The first item.
-     */
-    GET_RTYPE first()
-    {
-        m_guard.enterRead();
-        GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
-        m_guard.leaveRead();
-        return res;
-    }
-
-    /**
-     * Return the last item as constant object.
+     * @param   i     The position of the item to return.
+     * @return   The item at position @a i.
+     */
+    GET_RTYPE at(size_t i)
+    {
+        m_guard.enterRead();
+        GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
+        m_guard.leaveRead();
+        return res;
+    }
+
+    /**
+     * Return the item at position @a i as mutable reference.
      *
      * @note No boundary checks are done. Make sure @a i is equal or greater zero
      *       and smaller than RTCList::size.
      *
-     * @return   The last item.
-     */
-    GET_CRTYPE last() const
-    {
-        m_guard.enterRead();
-        GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
-        m_guard.leaveRead();
-        return res;
-    }
-
-    /**
-     * Return the last item.
-     *
-     * @note No boundary checks are done. Make sure @a i is equal or greater zero
-     *       and smaller than RTCList::size.
-     *
-     * @return   The last item.
-     */
-    GET_RTYPE last()
-    {
-        m_guard.enterRead();
-        GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
-        m_guard.leaveRead();
-        return res;
-    }
-
-    /**
-     * Return the item at position @a i as constant object.
-     *
-     * @note No boundary checks are done. Make sure @a i is equal or greater zero
-     *       and smaller than RTCList::size.
-     *
-     * @param   i     The position of the item to return.
-     * @return  The item at position @a i.
-     */
-    GET_CRTYPE at(size_t i) const
-    {
-        m_guard.enterRead();
-        GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
-        m_guard.leaveRead();
-        return res;
-    }
-
-    /**
-     * Return the item at position @a i.
-     *
-     * @note No boundary checks are done. Make sure @a i is equal or greater zero
-     *       and smaller than RTCList::size.
-     *
      * @param   i     The position of the item to return.
      * @return   The item at position @a i.
      */
-    GET_RTYPE at(size_t i)
-    {
-        m_guard.enterRead();
-        GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
-        m_guard.leaveRead();
-        return res;
-    }
-
-    /**
-     * Return the item at position @a i as mutable reference.
-     *
-     * @note No boundary checks are done. Make sure @a i is equal or greater zero
-     *       and smaller than RTCList::size.
-     *
-     * @param   i     The position of the item to return.
-     * @return   The item at position @a i.
-     */
     T &operator[](size_t i)
     {
@@ -553,5 +557,5 @@
     {
         m_guard.enterRead();
-        if (i >= m_cSize)
+        if (RT_UNLIKELY(i >= m_cSize))
         {
             m_guard.leaveRead();
@@ -574,5 +578,5 @@
     {
         m_guard.enterRead();
-        if (i >= m_cSize)
+        if (RT_UNLIKELY(i >= m_cSize))
         {
             m_guard.leaveRead();
@@ -601,6 +605,6 @@
      * Remove the first item.
      *
-     * @note No boundary checks are done. Make sure @a i is equal or greater zero
-     *       and smaller than RTCList::size.
+     * @note No boundary checks are done. Make sure there is at least one
+     * element.
      */
     void removeFirst()
@@ -612,6 +616,6 @@
      * Remove the last item.
      *
-     * @note No boundary checks are done. Make sure @a i is equal or greater zero
-     *       and smaller than RTCList::size.
+     * @note No boundary checks are done. Make sure there is at least one
+     * element.
      */
     void removeLast()
@@ -669,5 +673,5 @@
         RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
         if (m_cSize != DefaultCapacity)
-            realloc_grow(DefaultCapacity);
+            realloc_no_elements_clean(DefaultCapacity);
         m_cSize = 0;
         m_guard.leaveWrite();
@@ -691,4 +695,9 @@
         m_guard.leaveRead();
         return res;
+    }
+
+    RTCListBase<T, ITYPE, MT> &operator<<(const T &val)
+    {
+        return append(val);
     }
 
@@ -716,8 +725,19 @@
         if (   cNewSize < m_cSize
             && m_pArray)
-        {
             RTCListHelper<T, ITYPE>::eraseRange(m_pArray, cNewSize, m_cSize - cNewSize);
+        realloc_no_elements_clean(cNewSize);
+    }
+
+    void realloc_no_elements_clean(size_t cNewSize)
+    {
+        /* Same size? */
+        if (cNewSize == m_cCapacity)
+            return;
+
+        /* If we get smaller we have to delete some of the objects at the end
+           of the list. */
+        if (   cNewSize < m_cSize
+            && m_pArray)
             m_cSize -= m_cSize - cNewSize;
-        }
 
         /* If we get zero we delete the array it self. */
@@ -803,4 +823,7 @@
      : BASE(cCapacity) {}
 
+    RTCList(const BASE &other)
+     : BASE(other) {}
+
     /* Define our own new and delete. */
     RTMEMEF_NEW_AND_DELETE_OPERATORS();
