removed useless copy of input arguments when allocating output matrix of double
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_size.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - DIGITEO - Antoine ELIAS
4  * Copyright (C) 2015 - Scilab Enterprises - Anais AUBERT
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13 /*--------------------------------------------------------------------------*/
14 #include "elem_func_gw.hxx"
15 #include "types.hxx"
16 #include "string.hxx"
17 #include "container.hxx"
18 #include "getmode.hxx"
19 #include "overload.hxx"
20 #include "execvisitor.hxx"
21 #include "context.hxx"
22
23 extern "C"
24 {
25 #include "Scierror.h"
26 #include "localization.h"
27 #include "os_string.h"
28 }
29
30 using namespace types;
31 /*--------------------------------------------------------------------------*/
32 Function::ReturnValue sci_size(types::typed_list &in, int _iRetCount, types::typed_list &out)
33 {
34     if (in.size() < 1)
35     {
36         Scierror(999, _("%s: Wrong number of input arguments: At least %d expected.\n"), "size", 1);
37         return Function::Error;
38     }
39
40     switch (in[0]->getType())
41     {
42         // Dedicated case for lists.
43         case InternalType::ScilabMList:
44         {
45             ast::ExecVisitor exec;
46             std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_size";
47             Overload::call(wstFuncName, in, _iRetCount, out, &exec);
48             break;
49         }
50         case InternalType::ScilabTList:
51         {
52             // calls the overload if it exists.
53             std::wstring wstFuncName = L"%"  + in[0]->getTypeStr() + L"_size";
54             types::InternalType *pIT = symbol::Context::getInstance()->get(symbol::Symbol(wstFuncName));
55             if (pIT)
56             {
57                 ast::ExecVisitor exec;
58                 return Overload::call(wstFuncName, in, _iRetCount, out, &exec);
59             }
60         }
61         case InternalType::ScilabList:
62         {
63             if (in.size() > 1)
64             {
65                 Scierror(999, _("%s: Wrong number of input argument(s): %d expected.\n"), "size", 1);
66                 return Function::Error;
67             }
68
69             Double* pD = new Double(in[0]->getAs<Container>()->getSize());
70             out.push_back(pD);
71             break;
72         }
73         default :
74             // All types inherits of GenericType, so have this algorithm as default.
75         {
76             if (in[0]->isGenericType() == false)
77             {
78                 ast::ExecVisitor exec;
79                 std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_size";
80                 return Overload::call(wstFuncName, in, _iRetCount, out, &exec);
81             }
82             int iMode = -1;
83
84             if (in.size() > 2)
85             {
86                 Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "size", 1, 2);
87                 return Function::Error;
88             }
89
90             if (in.size() == 2)
91             {
92                 iMode = getMode(in, 1, 0);
93                 if (iMode == -2)
94                 {
95                     return Function::Error;
96                 }
97
98             }
99
100             int iDims   = in[0]->getAs<GenericType>()->getDims();
101             int* piDims = in[0]->getAs<GenericType>()->getDimsArray();
102
103             if (_iRetCount == 1)
104             {
105                 int iRowsOut = 1;
106                 int iColsOut = 0;
107                 double* pdblReal = NULL;
108
109                 switch (iMode)
110                 {
111                     case -1 : //lhs == 1
112                         iColsOut = iDims;
113                         break;
114                     default : //"*"
115                         iColsOut = 1;
116                         break;
117                 }
118
119                 Double* pD = new Double(iRowsOut, iColsOut);
120
121                 double* pdbl = pD->getReal();
122
123                 switch (iMode)
124                 {
125                     case -1 : //lhs == 1
126                         for (int i = 0 ; i < iDims ; i++)
127                         {
128                             pdbl[i] = piDims[i];
129                         }
130                         break;
131                     case 0 : //"*"
132                         pdbl[0] = in[0]->getAs<GenericType>()->getSize();
133                         break;
134                     default : //"r"
135                         if (iMode > iDims)
136                         {
137                             pdbl[0] = 1;
138                             out.push_back(pD);
139                             return Function::OK;
140                         }
141
142                         iColsOut = 1;
143                         pdbl[0] = piDims[iMode - 1];
144                         break;
145                 }
146                 out.push_back(pD);
147             }
148             else
149             {
150                 for (int i = 0 ; i < std::min(_iRetCount, iDims) ; i++)
151                 {
152                     Double* pD = new Double(piDims[i]);
153                     out.push_back(pD);
154                 }
155
156                 /* Multiple returns:
157                  * example: [a b c]=size(M) */
158                 if (_iRetCount > iDims)
159                 {
160                     for (int i = iDims ; i < _iRetCount ; i++)
161                     {
162                         Double* pD = new Double(1);
163                         out.push_back(pD);
164                     }
165                 }
166             }
167             break;
168         }
169     }
170     return Function::OK;
171 }
172 /*--------------------------------------------------------------------------*/