elementary_functions module.
[scilab.git] / scilab / modules / elementary_functions / sci_gateway / cpp / sci_gsort.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - DIGITEO - Cedric DELAMARRE
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 "function.hxx"
15 #include "double.hxx"
16 #include "string.hxx"
17 #include "overload.hxx"
18 #include "execvisitor.hxx"
19 #include "gsort.hxx"
20
21
22 extern "C"
23 {
24 #include "Scierror.h"
25 #include "localization.h"
26 }
27
28 /*--------------------------------------------------------------------------*/
29 types::Function::ReturnValue sci_gsort(types::typed_list &in, int _iRetCount, types::typed_list &out)
30 {
31     types::Double* pDblInd = NULL;
32
33     std::wstring wstrWay     = L"d";
34     std::wstring wstrProcess = L"g";
35
36     if (in.size() < 1 || in.size() > 3)
37     {
38         ScierrorW(77, _W("%ls: Wrong number of input argument(s): %d to %d expected.\n"), L"gsort", 1, 3);
39         return types::Function::Error;
40     }
41
42     if (_iRetCount > 1 && in[0]->isSparse())
43     {
44         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d expected.\n"), L"gsort", 1, 1);
45         return types::Function::Error;
46     }
47     else if (_iRetCount > 2)
48     {
49         ScierrorW(78, _W("%ls: Wrong number of output argument(s): %d to %d expected.\n"), L"gsort", 1, 2);
50         return types::Function::Error;
51     }
52
53     /***** get data and perform operation *****/
54     if (in.size() == 3) // get Direction
55     {
56         if (in[2]->isString() == false)
57         {
58             ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A string expected.\n"), L"gsort", 3);
59             return types::Function::Error;
60         }
61
62         wstrWay = in[2]->getAs<types::String>()->get(0);
63
64         if (wstrWay != L"i" && wstrWay != L"d")
65         {
66             ScierrorW(999, _W("%ls: Wrong value for input argument #%d : It must be one of the following strings : i or d.\n"), L"gsort", 3);
67             return types::Function::Error;
68         }
69     }
70
71     if (in.size() >= 2) // get Option
72     {
73         if (in[1]->isString() == false)
74         {
75             ScierrorW(999, _W("%ls: Wrong type for input argument #%d : A string expected.\n"), L"gsort", 2);
76             return types::Function::Error;
77         }
78
79         wstrProcess = in[1]->getAs<types::String>()->get(0);
80
81         if ( wstrProcess != L"c"  &&
82                 wstrProcess != L"r"  &&
83                 wstrProcess != L"g"  &&
84                 wstrProcess != L"lc" &&
85                 wstrProcess != L"lr")
86         {
87             ScierrorW(999, _W("%ls: Wrong value for input argument #%d : It must be one of the following strings : r, c, g, lr or lc.\n"), L"gsort", 2);
88
89             return types::Function::Error;
90         }
91     }
92
93     // get data and perform operation for each types::
94     if (in[0]->isGenericType() == false)
95     {
96         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_gsort";
97         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
98     }
99
100     types::GenericType* pGTOut = in[0]->getAs<types::GenericType>();
101
102     if (pGTOut->getDims() > 2)
103     {
104         std::wstring wstFuncName = L"%hm_gsort";
105         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
106     }
107
108     if (_iRetCount == 2)
109     {
110         int iRowsInd = (wstrProcess == L"lc") ? 1 : pGTOut->getRows();
111         int iColsInd = (wstrProcess == L"lr") ? 1 : pGTOut->getCols();
112
113         pDblInd = new types::Double(iRowsInd, iColsInd);
114     }
115
116     if (in[0]->isDouble()) // double
117     {
118         types::Double* pDblIn = in[0]->getAs<types::Double>();
119         // doc says : "With complex numbers, gsort can be overloaded"
120         if (pDblIn->isComplex() && symbol::Context::getInstance()->get_fun(symbol::Symbol(L"%_gsort")))
121         {
122             if (_iRetCount == 2)
123             {
124                 delete pDblInd;
125             }
126
127             return Overload::call(L"%_gsort", in, _iRetCount, out, new ExecVisitor());
128         }
129
130         types::Double* pDblOut = gsort(pDblIn, pDblInd, wstrWay, wstrProcess);
131         out.push_back(pDblOut);
132     }
133     else if (in[0]->isSparse()) // sparse
134     {
135         if (_iRetCount == 2)
136         {
137             delete pDblInd;
138         }
139
140         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_gsort";
141         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
142     }
143     else if (in[0]->isString()) // string
144     {
145         types::String* pStringIn = in[0]->getAs<types::String>();
146         types::String* pStringOut = gsort(pStringIn, pDblInd, wstrWay, wstrProcess);
147         out.push_back(pStringOut);
148     }
149     else if (in[0]->isInt8()) // int
150     {
151         types::Int8* pIIn = in[0]->getAs<types::Int8>();
152         types::Int8* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
153         out.push_back(pIOut);
154     }
155     else if (in[0]->isInt16())
156     {
157         types::Int16* pIIn = in[0]->getAs<types::Int16>();
158         types::Int16* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
159         out.push_back(pIOut);
160     }
161     else if (in[0]->isInt32())
162     {
163         types::Int32* pIIn = in[0]->getAs<types::Int32>();
164         types::Int32* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
165         out.push_back(pIOut);
166     }
167     else if (in[0]->isInt64())
168     {
169         types::Int64* pIIn = in[0]->getAs<types::Int64>();
170         types::Int64* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
171         out.push_back(pIOut);
172     }
173     else if (in[0]->isUInt8()) // uint
174     {
175         types::UInt8* pIIn = in[0]->getAs<types::UInt8>();
176         types::UInt8* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
177         out.push_back(pIOut);
178     }
179     else if (in[0]->isUInt16())
180     {
181         types::UInt16* pIIn = in[0]->getAs<types::UInt16>();
182         types::UInt16* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
183         out.push_back(pIOut);
184     }
185     else if (in[0]->isUInt32())
186     {
187         types::UInt32* pIIn = in[0]->getAs<types::UInt32>();
188         types::UInt32* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
189         out.push_back(pIOut);
190     }
191     else if (in[0]->isUInt64())
192     {
193         types::UInt64* pIIn = in[0]->getAs<types::UInt64>();
194         types::UInt64* pIOut = gsort(pIIn, pDblInd, wstrWay, wstrProcess);
195         out.push_back(pIOut);
196     }
197     else
198     {
199         std::wstring wstFuncName = L"%"  + in[0]->getShortTypeStr() + L"_gsort";
200         return Overload::call(wstFuncName, in, _iRetCount, out, new ExecVisitor());
201     }
202
203     /***** set result *****/
204     if (_iRetCount == 2)
205     {
206         out.push_back(pDblInd);
207     }
208
209     return types::Function::OK;
210 }
211 /*--------------------------------------------------------------------------*/