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