# HG changeset patch
# User Petter Tomner <tomner@kth.se>
# Date 1641590062 -3600
#      Fri Jan 07 22:14:22 2022 +0100
# Node ID 807013100d28b585daf392bd4441d761368c333a
# Parent  93c11c38d77b1dd59683af220286e8e0b503f58b
WIP: Tiny vector - funktioner for att få ner fotavtrycket. Verkar funka OK
     men dubbelkolla att inte OCTAVE_LIKELY är anledningen till att det blir
     snabbare

diff -r 93c11c38d77b -r 807013100d28 liboctave/util/tiny_vector.h
--- a/liboctave/util/tiny_vector.h	Fri Jan 07 14:18:35 2022 +0100
+++ b/liboctave/util/tiny_vector.h	Fri Jan 07 22:14:22 2022 +0100
@@ -26,6 +26,8 @@
 #if ! defined (tiny_vector_h)
 #define tiny_vector_h 1
 
+#include "octave-config.h"
+
 #include <vector>
 #include <cstddef>
 #include <initializer_list>
@@ -100,7 +102,7 @@
 
     tiny_vector (const tiny_vector &tovv)
     {
-      if (tovv.m_tag >= 0)
+      if (OCTAVE_LIKELY (tovv.m_tag >= 0))
         {
           for (int i = 0; i < tovv.m_tag; i++)
             new (&m_data.m_arr[i]) T(tovv.m_data.m_arr[i]);
@@ -125,22 +127,25 @@
       m_tag = -1;
     }
 
+    void __attribute__ ((noinline,noclone)) dtor_internal ()
+    {
+      m_data.m_vec.~vector ();
+    }
+
     ~tiny_vector ()
     {
-      if (m_tag < 0)
-        {
-          m_data.m_vec.~vector ();
-        }
-      else
+      if (OCTAVE_LIKELY (m_tag >= 0))
         {
           for (int i = 0; i < m_tag; i++)
             m_data.m_arr [i].~T ();
         }
+      else
+        dtor_internal ();
     }
 
     bool empty () const
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return m_tag == 0;
       else
         return m_data.m_vec.empty ();
@@ -148,15 +153,20 @@
 
     size_t size () const
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return m_tag;
       else
         return m_data.m_vec.size ();
     }
 
+    void __attribute__ ((noinline,noclone)) clear_internal ()
+    {
+      m_data.m_vec.clear ();
+    }
+
     void clear ()
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         {
           // Destroy old elements
           for (int i = 0; i < m_tag; i++)
@@ -165,12 +175,12 @@
           m_tag = 0;
         }
       else
-        return m_data.m_vec.clear ();
+        clear_internal ();
     }
 
     const T* begin () const
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return &m_data.m_arr[0];
       else
         return m_data.m_vec.data ();
@@ -178,7 +188,7 @@
 
     T* begin ()
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return &m_data.m_arr[0];
       else
         return m_data.m_vec.data ();
@@ -186,7 +196,7 @@
 
     const T* end () const
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return &m_data.m_arr[m_tag];
       else
         return m_data.m_vec.data () + m_data.m_vec.size ();
@@ -194,15 +204,43 @@
 
     T* end ()
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return &m_data.m_arr[m_tag];
       else
         return m_data.m_vec.data () + m_data.m_vec.size ();
     }
 
+    void __attribute__ ((noinline))
+    operator_eq_internal (tiny_vector &&tovv)
+    {
+      if (m_tag < 0 && tovv.m_tag < 0)
+        {
+          m_data.m_vec = tovv.m_data.m_vec;
+          m_tag = -1;
+        }
+      else if (m_tag >= 0 && tovv.m_tag < 0)
+        {
+          // Destroy elements
+          for (int i = 0; i < m_tag; i++)
+            m_data.m_arr[i].~T ();
+
+          // Construct the vector in the union
+          new (&m_data.m_vec) std::vector<T> (tovv.m_data.m_vec);
+
+          //Mark for vector usage
+          m_tag = -1;
+        }
+      else // (m_tag < 0 && tovv.m_tag >= 0)
+        {
+          m_data.m_vec.resize (tovv.m_tag);
+          for (int i = 0; i < tovv.m_tag; i++)
+            m_data.m_vec[i] = tovv.m_data.m_arr[i];
+        }
+    }
+
     tiny_vector& operator=(tiny_vector &&tovv)
     {
-      if (m_tag >= 0 && tovv.m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0 && tovv.m_tag >= 0))
         {
           // Destroy old elements
           for (int i = 0; i < m_tag; i++)
@@ -216,11 +254,19 @@
 
           return *this;
         }
-      else if (m_tag < 0 && tovv.m_tag < 0)
+      else
+        {
+          operator_eq_internal (std::move (tovv));
+          return *this;
+        }
+    }
+
+    void __attribute__ ((noinline,noclone))
+    operator_eq_ref_internal (const tiny_vector &tovv)
+    {
+      if (m_tag < 0 && tovv.m_tag < 0)
         {
           m_data.m_vec = tovv.m_data.m_vec;
-          m_tag = -1;
-          return *this;
         }
       else if (m_tag >= 0 && tovv.m_tag < 0)
         {
@@ -228,27 +274,23 @@
           for (int i = 0; i < m_tag; i++)
             m_data.m_arr[i].~T ();
 
-          // Construct the vector in the union
-          new (&m_data.m_vec) std::vector<T> (tovv.m_data.m_vec);
-
           //Mark for vector usage
           m_tag = -1;
 
-          return *this;
+          // Construct the vector in the union
+          new (&m_data.m_vec) std::vector<T> (tovv.m_data.m_vec);
         }
       else // (m_tag < 0 && tovv.m_tag >= 0)
         {
           m_data.m_vec.resize (tovv.m_tag);
           for (int i = 0; i < tovv.m_tag; i++)
             m_data.m_vec[i] = tovv.m_data.m_arr[i];
-
-          return *this;
         }
     }
 
     tiny_vector& operator=(const tiny_vector &tovv)
     {
-      if (m_tag >= 0 && tovv.m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0 && tovv.m_tag >= 0))
         {
           // Destroy old elements
           for (int i = 0; i < m_tag; i++)
@@ -262,38 +304,16 @@
 
           return *this;
         }
-      else if (m_tag < 0 && tovv.m_tag < 0)
-        {
-          m_data.m_vec = tovv.m_data.m_vec;
-          return *this;
-        }
-      else if (m_tag >= 0 && tovv.m_tag < 0)
+      else
         {
-          // Destroy elements
-          for (int i = 0; i < m_tag; i++)
-            m_data.m_arr[i].~T ();
-
-          //Mark for vector usage
-          m_tag = -1;
-
-          // Construct the vector in the union
-          new (&m_data.m_vec) std::vector<T> (tovv.m_data.m_vec);
-
-          return *this;
-        }
-      else // (m_tag < 0 && tovv.m_tag >= 0)
-        {
-          m_data.m_vec.resize (tovv.m_tag);
-          for (int i = 0; i < tovv.m_tag; i++)
-            m_data.m_vec[i] = tovv.m_data.m_arr[i];
-
+          operator_eq_ref_internal(tovv);
           return *this;
         }
     }
 
     T& operator[](std::size_t idx)
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         {
       // Poor compiler can't figure out that m_tag is supposed to be
       // -1 when idx is bigger than the array.
@@ -308,7 +328,7 @@
 
     const T& operator[](std::size_t idx) const
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         {
       // Poor compiler can't figure out that m_tag is supposed to be
       // -1 when idx is bigger than the array.
@@ -325,7 +345,7 @@
 
     T& front ()
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return m_data.m_arr[0];
       else
         return m_data.m_vec.front ();
@@ -333,7 +353,7 @@
 
     const T& front () const
     {
-      if (m_tag >= 0)
+      if (OCTAVE_LIKELY (m_tag >= 0))
         return m_data.m_arr[0];
       else
         return m_data.m_vec.front ();
@@ -341,7 +361,7 @@
 
     void push_back (const T &v)
     {
-      if (m_tag >= 0 && m_tag < static_cast<int> (n_tiny))
+      if (OCTAVE_LIKELY (m_tag >= 0 && m_tag < static_cast<int> (n_tiny)))
         {
           new (&m_data.m_arr[m_tag++]) T (v);
           return;
