Improve performance for loop and insertion
[scilab.git] / scilab / modules / ast / src / cpp / types / implicitlist.cpp
index ff8d547..a813a52 100644 (file)
@@ -45,28 +45,19 @@ ImplicitList::~ImplicitList()
         if (m_poStart)
         {
             m_poStart->DecreaseRef();
-            if (m_poStart->isDeletable())
-            {
-                delete m_poStart;
-            }
+            m_poStart->killMe();
         }
 
         if (m_poStep)
         {
             m_poStep->DecreaseRef();
-            if (m_poStep->isDeletable())
-            {
-                delete m_poStep;
-            }
+            m_poStep->killMe();
         }
 
         if (m_poEnd)
         {
             m_poEnd->DecreaseRef();
-            if (m_poEnd->isDeletable())
-            {
-                delete m_poEnd;
-            }
+            m_poEnd->killMe();
         }
     }
 #ifndef NDEBUG
@@ -138,11 +129,8 @@ void ImplicitList::setStart(InternalType *_poIT)
     {
         //clear previous value
         m_poStart->DecreaseRef();
-        if (m_poStart->isDeletable())
-        {
-            delete m_poStart;
-            m_poStart = NULL;
-        }
+        m_poStart->killMe();
+        m_poStart = NULL;
     }
 
     m_poStart = _poIT;
@@ -160,11 +148,8 @@ void ImplicitList::setStep(InternalType *_poIT)
     {
         //clear previous value
         m_poStep->DecreaseRef();
-        if (m_poStep->isDeletable())
-        {
-            delete m_poStep;
-            m_poStep = NULL;
-        }
+        m_poStep->killMe();
+        m_poStep = NULL;
     }
 
     m_poStep = _poIT;
@@ -182,11 +167,8 @@ void ImplicitList::setEnd(InternalType* _poIT)
     {
         //clear previous value
         m_poEnd->DecreaseRef();
-        if (m_poEnd->isDeletable())
-        {
-            delete m_poEnd;
-            m_poEnd = NULL;
-        }
+        m_poEnd->killMe();
+        m_poEnd = NULL;
     }
 
     m_poEnd = _poIT;
@@ -265,25 +247,6 @@ bool ImplicitList::compute()
             {
                 m_iSize++;
             }
-
-            //if(dblStep > 0)
-            //{
-            //    m_iSize = static_cast<int>(floor((dblEnd - dblStart) / dblStep)) + 1;
-            //}
-            //else if(dblStep < 0)
-            //{
-            //    m_iSize = static_cast<int>(floor((dblStart - dblEnd) / -dblStep)) + 1;
-            //}
-            //else
-            //{
-            //    m_iSize = 0;
-            //}
-
-            //if(m_iSize < 0)
-            //{
-            //    m_iSize = 0;
-            //}
-            //                m_iSize = static_cast<long long>(floor(fabs(dblEnd - dblStart) / fabs(dblStep))) + 1;
         }
         else //m_eOutType == ScilabInt
         {
@@ -369,8 +332,9 @@ bool ImplicitList::toString(std::wostringstream& ostr)
 {
     if (isComputable())
     {
-        bool ret = extractFullMatrix()->toString(ostr);
-        scilabWriteW(ostr.str().c_str());
+        types::InternalType* pIT = extractFullMatrix();
+        bool ret = pIT->toString(ostr);
+        delete pIT;
         return ret;
     }
     else
@@ -413,7 +377,6 @@ bool ImplicitList::toString(std::wostringstream& ostr)
             ostr << printInLinePoly(pMP->get(0), pMP->getVariableName());
         }
         ostr << std::endl;
-        scilabWriteW(ostr.str().c_str());
         return true;
     }
 }
@@ -423,72 +386,101 @@ InternalType::ScilabType ImplicitList::getOutputType()
     return m_eOutType;
 }
 
-double ImplicitList::extractValueInDouble(int _iOccur)
+void ImplicitList::extractValueAsDouble(int _iOccur, Double* d)
 {
-    double dblStart            = m_pDblStart->get(0);
-    double dblStep             = m_pDblStep->get(0);
-    return dblStart + _iOccur * dblStep;
+    double dblStart = m_pDblStart->get(0);
+    double dblStep = m_pDblStep->get(0);
+    d->get()[0] = dblStart + _iOccur * dblStep;
 }
 
-long long ImplicitList::extractValueInInteger(int _iOccur)
+template<typename T>
+void ImplicitList::extractValueAsInteger(int _iOccur, T* val)
+{
+
+    val->get()[0] = static_cast<typename T::type>(convert_input(m_poStart)) +
+                    _iOccur * static_cast<typename T::type>(convert_input(m_poStep));
+}
+
+template<typename T>
+void ImplicitList::extractValueAsUnsignedInteger(int _iOccur, T* val)
 {
-    return convert_input(m_poStart) + _iOccur * convert_input(m_poStep);
+    val->get()[0] = static_cast<typename T::type>(convert_unsigned_input(m_poStart)) +
+                    _iOccur * static_cast<typename T::type>(convert_unsigned_input(m_poStep));
 }
 
-unsigned long long ImplicitList::extractValueInUnsignedInteger(int _iOccur)
+InternalType* ImplicitList::getInitalType()
 {
-    return convert_unsigned_input(m_poStart) + _iOccur * convert_unsigned_input(m_poStep);
+    if (compute())
+    {
+        int iDims = 2;
+        int piDms[2] = {1, 1};
+        switch (m_eOutType)
+        {
+            case ScilabDouble:
+                return new Double(iDims, piDms);
+            case ScilabInt8:
+                return new Int8(iDims, piDms);
+            case ScilabInt16:
+                return new Int16(iDims, piDms);
+            case ScilabInt32:
+                return new Int32(iDims, piDms);
+            case ScilabInt64:
+                return new Int64(iDims, piDms);
+            case ScilabUInt8:
+                return new UInt8(iDims, piDms);
+            case ScilabUInt16:
+                return new UInt16(iDims, piDms);
+            case ScilabUInt32:
+                return new UInt32(iDims, piDms);
+            case ScilabUInt64:
+                return new UInt64(iDims, piDms);
+        }
+    }
+
+    return nullptr;
 }
 
 //extract single value in a InternalType
-InternalType* ImplicitList::extractValue(int _iOccur)
+void ImplicitList::extractValue(int _iOccur, InternalType* pIT)
 {
-    InternalType* pIT = NULL;
+    if (pIT == nullptr)
+    {
+        return;
+    }
+
     if (compute())
     {
-        long long llVal             = extractValueInInteger(_iOccur);
-        unsigned long long ullVal   = extractValueInUnsignedInteger(_iOccur);
-        if (m_eOutType == ScilabInt8)
-        {
-            pIT        = new Int8((char)llVal);
-        }
-        else if (m_eOutType == ScilabUInt8)
-        {
-            pIT        = new UInt8((unsigned char)ullVal);
-        }
-        else if (m_eOutType == ScilabInt16)
-        {
-            pIT        = new Int16((short)llVal);
-        }
-        else if (m_eOutType == ScilabUInt16)
-        {
-            pIT        = new UInt16((unsigned short)ullVal);
-        }
-        else if (m_eOutType == ScilabInt32)
-        {
-            pIT        = new Int32((int)llVal);
-        }
-        else if (m_eOutType == ScilabUInt32)
-        {
-            pIT        = new UInt32((unsigned int)ullVal);
-        }
-        else if (m_eOutType == ScilabInt64)
-        {
-            pIT        = new Int64((long long)llVal);
-        }
-        else if (m_eOutType == ScilabUInt64)
-        {
-            pIT        = new UInt64((unsigned long long)ullVal);
-        }
-        else //ScilabDouble
-        {
-            double dblStart = m_poStart->getAs<Double>()->getReal(0, 0);
-            double dblStep  = m_poStep->getAs<Double>()->getReal(0, 0);
-            Double* pD      = new Double(dblStart + _iOccur * dblStep);
-            pIT = pD;
+        switch (m_eOutType)
+        {
+            case ScilabInt8:
+                extractValueAsInteger(_iOccur, pIT->getAs<Int8>());
+                break;
+            case ScilabInt16:
+                extractValueAsInteger(_iOccur, pIT->getAs<Int16>());
+                break;
+            case ScilabInt32:
+                extractValueAsInteger(_iOccur, pIT->getAs<Int32>());
+                break;
+            case ScilabInt64:
+                extractValueAsInteger(_iOccur, pIT->getAs<Int64>());
+                break;
+            case ScilabUInt8:
+                extractValueAsUnsignedInteger(_iOccur, pIT->getAs<UInt8>());
+                break;
+            case ScilabUInt16:
+                extractValueAsUnsignedInteger(_iOccur, pIT->getAs<UInt16>());
+                break;
+            case ScilabUInt32:
+                extractValueAsUnsignedInteger(_iOccur, pIT->getAs<UInt32>());
+                break;
+            case ScilabUInt64:
+                extractValueAsUnsignedInteger(_iOccur, pIT->getAs<UInt64>());
+                break;
+            case ScilabDouble:
+                extractValueAsDouble(_iOccur, pIT->getAs<Double>());
+                break;
         }
     }
-    return pIT;
 }
 
 //extract matrix in a Internaltype
@@ -510,72 +502,74 @@ InternalType* ImplicitList::extractFullMatrix()
         else if (m_eOutType == ScilabDouble)
         {
             pIT = new Double(1, m_iSize);
-            extractFullMatrix(pIT->getAs<Double>()->get());
+            extractFullMatrix(pIT->getAs<Double>());
         }
         else if (m_eOutType == ScilabInt8)
         {
             pIT        = new Int8(1, m_iSize);
-            extractFullMatrix(pIT->getAs<Int8>()->get());
+            extractFullMatrix(pIT->getAs<Int8>());
         }
         else if (m_eOutType == ScilabUInt8)
         {
             pIT        = new UInt8(1, m_iSize);
-            extractFullMatrix(pIT->getAs<UInt8>()->get());
+            extractFullMatrix(pIT->getAs<UInt8>());
         }
         else if (m_eOutType == ScilabInt16)
         {
             pIT        = new Int16(1, m_iSize);
-            extractFullMatrix(pIT->getAs<Int16>()->get());
+            extractFullMatrix(pIT->getAs<Int16>());
         }
         else if (m_eOutType == ScilabUInt16)
         {
             pIT        = new UInt16(1, m_iSize);
-            extractFullMatrix(pIT->getAs<UInt16>()->get());
+            extractFullMatrix(pIT->getAs<UInt16>());
         }
         else if (m_eOutType == ScilabInt32)
         {
             pIT        = new Int32(1, m_iSize);
-            extractFullMatrix(pIT->getAs<Int32>()->get());
+            extractFullMatrix(pIT->getAs<Int32>());
         }
         else if (m_eOutType == ScilabUInt32)
         {
             pIT        = new UInt32(1, m_iSize);
-            extractFullMatrix(pIT->getAs<UInt32>()->get());
+            extractFullMatrix(pIT->getAs<UInt32>());
         }
         else if (m_eOutType == ScilabInt64)
         {
             pIT        = new Int64(1, m_iSize);
-            extractFullMatrix(pIT->getAs<Int64>()->get());
+            extractFullMatrix(pIT->getAs<Int64>());
         }
         else if (m_eOutType == ScilabUInt64)
         {
             pIT        = new UInt64(1, m_iSize);
-            extractFullMatrix(pIT->getAs<UInt64>()->get());
+            extractFullMatrix(pIT->getAs<UInt64>());
         }
     }
     return pIT;
 }
 
-void ImplicitList::extractFullMatrix(double *_pdbl)
+void ImplicitList::extractFullMatrix(Double *_p)
 {
     double dblStart = m_poStart->getAs<Double>()->get(0);
     double dblStep  = m_poStep->getAs<Double>()->get(0);
 
+    double* p = _p->get();
     for (int i = 0 ; i < m_iSize ; i++)
     {
-        _pdbl[i] = dblStart + i * dblStep;
+        p[i] = dblStart + i * dblStep;
     }
 }
 
 template<typename T>
 void ImplicitList::extractFullMatrix(T *_pT)
 {
-    T tStart = static_cast<T>(convert_input(m_poStart));
-    T tStep    = static_cast<T>(convert_input(m_poStep));
+    typename T::type tStart = static_cast<typename T::type>(convert_input(m_poStart));
+    typename T::type tStep = static_cast<typename T::type>(convert_input(m_poStep));
 
+    typename T::type* p = _pT->get();
     for (int i = 0 ; i < m_iSize ; i++)
     {
-        _pT[i] = tStart + i * tStep;
+        p[i] = tStart + i * tStep;
     }
 }
 
@@ -585,7 +579,7 @@ bool ImplicitList::transpose(InternalType *& out)
     {
         Double * pIT = new Double(m_iSize, 1);
         out = pIT;
-        extractFullMatrix(pIT->get());
+        extractFullMatrix(pIT);
 
         return true;
     }
@@ -606,7 +600,7 @@ bool ImplicitList::neg(InternalType *& out)
     return false;
 }
 
-bool ImplicitList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, ast::ConstVisitor & /*execFunc*/, const ast::CallExp & e)
+bool ImplicitList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, ast::ConstVisitor & /*execFunc*/, const ast::Exp & e)
 {
     if (in.size() == 0)
     {
@@ -619,7 +613,7 @@ bool ImplicitList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetC
         {
             std::wostringstream os;
             os << _W("Invalid index.\n");
-            throw ast::ScilabError(os.str(), 999, (*e.getArgs().begin())->getLocation());
+            throw ast::ScilabError(os.str(), 999, e.getLocation());
         }
         out.push_back(_out);
     }
@@ -641,6 +635,8 @@ InternalType* ImplicitList::extract(typed_list* _pArgs)
     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
     if (iSeqCount == 0)
     {
+        //free pArg content
+        cleanIndexesArguments(_pArgs, &pArg);
         return createEmptyDouble();
     }
 
@@ -695,13 +691,7 @@ InternalType* ImplicitList::extract(typed_list* _pArgs)
     }
 
     //free pArg content
-    for (int iArg = 0 ; iArg < (int)pArg.size() ; iArg++)
-    {
-        if (pArg[iArg] != (*_pArgs)[iArg] && pArg[iArg]->isDeletable())
-        {
-            delete pArg[iArg];
-        }
-    }
+    cleanIndexesArguments(_pArgs, &pArg);
 
     delete[] piMaxDim;
     delete[] piCountDim;
@@ -724,6 +714,9 @@ std::wstring printInLinePoly(types::SinglePoly* _pPoly, std::wstring _stVar)
             df.bPrintPlusSign = true;
             df.bPrintOne = i == 0;
             df.bPaddSign = false;
+            df.bPrintBlank = false;
+            df.bPrintPlusSign = false;
+
             addDoubleValue(&ostr, pdblIn[i], &df);
             if (i != 0)
             {
@@ -743,86 +736,66 @@ std::wstring printDouble(types::Double* _pD)
     std::wostringstream ostr;
     DoubleFormat df;
     getDoubleFormat(_pD->get(0), &df);
+    df.bPrintPoint = false;
     df.bPaddSign = true;
+    df.bPaddSign = false;
+    df.bPrintBlank = false;
     addDoubleValue(&ostr, _pD->get(0), &df);
     return ostr.str();
 }
 
 long long convert_input(types::InternalType* _poIT)
 {
-    long long llValue = 0;
     switch (_poIT->getType())
     {
-        case types::GenericType::ScilabDouble :
-            llValue = static_cast<long long>(_poIT->getAs<types::Double>()->get(0));
-            break;
-        case types::GenericType::ScilabInt8 :
-            llValue = static_cast<long long>(_poIT->getAs<types::Int8>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt8 :
-            llValue = static_cast<long long>(_poIT->getAs<types::UInt8>()->get(0));
-            break;
-        case types::GenericType::ScilabInt16 :
-            llValue = static_cast<long long>(_poIT->getAs<types::Int16>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt16 :
-            llValue = static_cast<long long>(_poIT->getAs<types::UInt16>()->get(0));
-            break;
-        case types::GenericType::ScilabInt32 :
-            llValue = static_cast<long long>(_poIT->getAs<types::Int32>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt32 :
-            llValue = static_cast<long long>(_poIT->getAs<types::UInt32>()->get(0));
-            break;
-        case types::GenericType::ScilabInt64 :
-            llValue = static_cast<long long>(_poIT->getAs<types::Int64>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt64 :
-            llValue = static_cast<long long>(_poIT->getAs<types::UInt64>()->get(0));
-            break;
+        case types::InternalType::ScilabDouble:
+            return static_cast<long long>(_poIT->getAs<types::Double>()->get(0));
+        case types::InternalType::ScilabInt8:
+            return static_cast<long long>(_poIT->getAs<types::Int8>()->get(0));
+        case types::InternalType::ScilabUInt8:
+            return static_cast<long long>(_poIT->getAs<types::UInt8>()->get(0));
+        case types::InternalType::ScilabInt16:
+            return static_cast<long long>(_poIT->getAs<types::Int16>()->get(0));
+        case types::InternalType::ScilabUInt16:
+            return static_cast<long long>(_poIT->getAs<types::UInt16>()->get(0));
+        case types::InternalType::ScilabInt32:
+            return static_cast<long long>(_poIT->getAs<types::Int32>()->get(0));
+        case types::InternalType::ScilabUInt32:
+            return static_cast<long long>(_poIT->getAs<types::UInt32>()->get(0));
+        case types::InternalType::ScilabInt64:
+            return static_cast<long long>(_poIT->getAs<types::Int64>()->get(0));
+        case types::InternalType::ScilabUInt64:
+            return static_cast<long long>(_poIT->getAs<types::UInt64>()->get(0));
         default:
-            // FIXME : Trigger an error ??
-            break;
+            return 0;
     }
-    return llValue;
+    return 0;
 }
 
 unsigned long long convert_unsigned_input(types::InternalType* _poIT)
 {
-    unsigned long long ullValue = 0;
     switch (_poIT->getType())
     {
-        case types::GenericType::ScilabDouble :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::Double>()->get(0));
-            break;
-        case types::GenericType::ScilabInt8 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::Int8>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt8 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::UInt8>()->get(0));
-            break;
-        case types::GenericType::ScilabInt16 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::Int16>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt16 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::UInt16>()->get(0));
-            break;
-        case types::GenericType::ScilabInt32 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::Int32>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt32 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::UInt32>()->get(0));
-            break;
-        case types::GenericType::ScilabInt64 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::Int64>()->get(0));
-            break;
-        case types::GenericType::ScilabUInt64 :
-            ullValue = static_cast<unsigned long long>(_poIT->getAs<types::UInt64>()->get(0));
-            break;
+        case types::InternalType::ScilabDouble:
+            return static_cast<unsigned long long>(_poIT->getAs<types::Double>()->get(0));
+        case types::InternalType::ScilabInt8:
+            return static_cast<unsigned long long>(_poIT->getAs<types::Int8>()->get(0));
+        case types::InternalType::ScilabUInt8:
+            return static_cast<unsigned long long>(_poIT->getAs<types::UInt8>()->get(0));
+        case types::InternalType::ScilabInt16:
+            return static_cast<unsigned long long>(_poIT->getAs<types::Int16>()->get(0));
+        case types::InternalType::ScilabUInt16:
+            return static_cast<unsigned long long>(_poIT->getAs<types::UInt16>()->get(0));
+        case types::InternalType::ScilabInt32:
+            return static_cast<unsigned long long>(_poIT->getAs<types::Int32>()->get(0));
+        case types::InternalType::ScilabUInt32:
+            return static_cast<unsigned long long>(_poIT->getAs<types::UInt32>()->get(0));
+        case types::InternalType::ScilabInt64:
+            return static_cast<unsigned long long>(_poIT->getAs<types::Int64>()->get(0));
+        case types::InternalType::ScilabUInt64:
+            return static_cast<unsigned long long>(_poIT->getAs<types::UInt64>()->get(0));
         default:
-            // FIXME : Trigger an error ??
-            break;
+            return 0;
     }
-    return ullValue;
-
+    return 0;
 }