fix llabs()/_abs64() on unsigned warnings
[scilab.git] / scilab / modules / ast / includes / types / int.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4  *  Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 //#ifndef __ARRAYOF_HXX__
18 //    #error This file must only be include by arrayof.hxx
19 //#endif
20
21 #ifndef __INT_HXX__
22 #define __INT_HXX__
23
24 #include "arrayof.hxx"
25 #include "bool.hxx"
26 #include "internal.hxx"
27 #include "types_transposition.hxx"
28 #include "configvariable.hxx"
29 #include "type_traits.hxx"
30
31 #include <sstream>
32 #include <string>
33 #include <limits>       // std::numeric_limits
34 #include "tostring_common.hxx"
35
36 namespace types
37 {
38 template<typename T>
39 class EXTERN_AST Int : public ArrayOf<T>
40 {
41 public :
42
43     Int(int _iRows, int _iCols)
44     {
45         int piDims[2] = {_iRows, _iCols};
46         T * pInt = NULL;
47         this->create(piDims, 2, &pInt, NULL);
48 #ifndef NDEBUG
49         //Inspector::addItem(this);
50 #endif
51     }
52
53     Int(T _val)
54     {
55         int piDims[2]   = {1, 1};
56         T * pInt = NULL;
57         this->create(piDims, 2, &pInt, NULL);
58         pInt[0] = _val;
59 #ifndef NDEBUG
60         //Inspector::addItem(this);
61 #endif
62     }
63
64     Int(int _iRows, int _iCols, T** _pData)
65     {
66         const int piDims[2] = {_iRows, _iCols};
67         this->create(piDims, 2, _pData, NULL);
68 #ifndef NDEBUG
69         //Inspector::addItem(this);
70 #endif
71     }
72
73     Int(int _iDims, const int* _piDims)
74     {
75         T * pInt = NULL;
76         this->create(_piDims, _iDims, &pInt, NULL);
77 #ifndef NDEBUG
78         //Inspector::addItem(this);
79 #endif
80     }
81
82     ~Int()
83     {
84         if (InternalType::isDeletable() == true)
85         {
86             deleteAll();
87         }
88 #ifndef NDEBUG
89         //Inspector::removeItem(this);
90 #endif
91     }
92
93     Int<T>* clone() override
94     {
95         Int<T> *pbClone = new Int<T>(GenericType::getDims(), GenericType::getDimsArray());
96         pbClone->set(ArrayOf<T>::get());
97         return pbClone;
98     }
99
100     /*Config management*/
101     void whoAmI() override;
102
103     bool isInt() override
104     {
105         return true;
106     }
107
108     bool neg(InternalType *& out) override
109     {
110         out = new Int<T>(this->getDims(), this->getDimsArray());
111         type_traits::bin_neg<T, T>(this->m_iSize, this->m_pRealData, static_cast<Int<T> *>(out)->get());
112
113         return true;
114     }
115
116     virtual bool transpose(InternalType *& out) override
117     {
118         return type_traits::transpose(*this, out);
119     }
120
121     bool operator==(const InternalType& it) override
122     {
123         if (const_cast<InternalType &>(it).getType() != getType())
124         {
125             return false;
126         }
127
128         Int<T>* pb = const_cast<InternalType &>(it).getAs<typename types::Int<T> >();
129
130         if (pb->getDims() != GenericType::getDims())
131         {
132             return false;
133         }
134
135         for (int i = 0 ; i < GenericType::getDims() ; i++)
136         {
137             if (pb->getDimsArray()[i] != GenericType::getDimsArray()[i])
138             {
139                 return false;
140             }
141         }
142
143         if (memcmp(ArrayOf<T>::get(), pb->get(), GenericType::getSize() * sizeof(T)) != 0)
144         {
145             return false;
146         }
147         return true;
148     }
149
150     bool operator!=(const InternalType& it) override
151     {
152         return !(*this == it);
153     }
154
155     /* return type as string ( double, int, cell, list, ... )*/
156     virtual std::wstring        getTypeStr() const override;
157
158     /* return type as short string ( s, i, ce, l, ... )*/
159     virtual std::wstring        getShortTypeStr() const override
160     {
161         return L"i";
162     }
163
164     virtual bool isNativeType() override
165     {
166         return true;
167     }
168
169     virtual void fillDefaultValues() override
170     {
171         int size = GenericType::getSize();
172         memset(this->m_pRealData, 0x00, sizeof(T) * size);
173     }
174
175     Int<T>* sign()
176     {
177         Int<T> *pOut = new Int<T>(GenericType::getDims(), GenericType::getDimsArray());
178         T* p = pOut->get();
179         int size = GenericType::getSize();
180         for (int i = 0; i < size; ++i)
181         {
182             p[i] = (this->m_pRealData[i] > T(0)) - (this->m_pRealData[i] < T(0));
183         }
184
185         return pOut;
186     }
187
188 protected :
189     inline InternalType::ScilabType getType(void) override;
190     inline InternalType::ScilabId   getId(void) override;
191
192 private :
193     virtual bool subMatrixToString(std::wostringstream& ostr, int* _piDims, int /*_iDims*/) override
194     {
195         int iCurrentLine = 0;
196         int iLineLen = ConfigVariable::getConsoleWidth();
197         int iMaxLines = ConfigVariable::getConsoleLines();
198
199         if (GenericType::isIdentity())
200         {
201             ostr << L"eye *" << std::endl << std::endl;
202             int iWidth = 0;
203             getIntFormat(ArrayOf<T>::get(0), &iWidth);
204             addIntValue(&ostr, ArrayOf<T>::get(0), iWidth);
205             ostr << std::endl;
206         }
207         else if (GenericType::isScalar())
208         {
209             //scalar
210             int iWidth  = 0;
211             _piDims[0]  = 0;
212             _piDims[1]  = 0;
213             int iPos    = ArrayOf<T>::getIndex(_piDims);
214
215             getIntFormat(ArrayOf<T>::get(iPos), &iWidth);
216             addIntValue(&ostr, ArrayOf<T>::get(iPos), iWidth);
217
218             ostr << std::endl;
219         }
220         else if (GenericType::getCols() == 1)
221         {
222             //column vector
223             int iWidthMax = 0;
224
225             //Array with the max printed size of each col
226             for (int i = 0 ; i < GenericType::getRows() ; i++)
227             {
228                 _piDims[1] = 0;
229                 _piDims[0] = i;
230                 int iWidth = 0;
231                 int iPos = ArrayOf<T>::getIndex(_piDims);
232                 getIntFormat(ArrayOf<T>::get(iPos), &iWidth);
233                 iWidthMax = (std::max)(iWidthMax, iWidth);
234             }
235
236             for (int i = this->m_iRows1PrintState ; i < this->getRows() ; i++)
237             {
238                 iCurrentLine++;
239                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
240                 {
241                     this->m_iRows1PrintState = i;
242                     return false;
243                 }
244
245                 _piDims[1]  = 0;
246                 _piDims[0]  = i;
247                 int iPos    = ArrayOf<T>::getIndex(_piDims);
248
249                 addIntValue(&ostr, ArrayOf<T>::get(iPos), iWidthMax);
250                 ostr << std::endl;
251             }
252         }
253         else if (GenericType::getRows() == 1)
254         {
255             //row vector
256             std::wostringstream ostemp;
257             int iLastVal = this->m_iCols1PrintState;
258
259             for (int i = this->m_iCols1PrintState ; i < this->getCols() ; i++)
260             {
261                 int iWidth  = 0;
262                 int iLen    = 0;
263                 _piDims[0]  = 0;
264                 _piDims[1]  = i;
265                 int iPos    = ArrayOf<T>::getIndex(_piDims);
266
267                 getIntFormat(ArrayOf<T>::get(iPos), &iWidth);
268
269                 iLen = iWidth + static_cast<int>(ostemp.str().size());
270                 if (iLen > iLineLen && iLastVal != i)
271                 {
272                     //Max length, new line
273                     iCurrentLine += 4; //"column x to Y" + empty line + value + empty line
274                     if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
275                     {
276                         this->m_iCols1PrintState = iLastVal;
277                         return false;
278                     }
279
280                     addColumnString(ostr, iLastVal + 1, i);
281                     ostr << ostemp.str() << std::endl;
282                     ostemp.str(L"");
283                     iLastVal = i;
284                 }
285
286                 addIntValue(&ostemp, ArrayOf<T>::get(iPos), iWidth);
287             }
288
289             if (iLastVal != 0)
290             {
291                 addColumnString(ostr, iLastVal + 1, GenericType::getCols());
292             }
293
294             ostemp << std::endl;
295             ostr << ostemp.str();
296         }
297         else // matrix
298         {
299             std::wostringstream ostemp;
300             int iLen = 0;
301             int iLastCol = this->m_iCols1PrintState;
302
303             //Array with the max printed size of each col
304             int *piSize = new int[GenericType::getCols()];
305             memset(piSize, 0x00, GenericType::getCols() * sizeof(int));
306
307             //compute the row size for padding for each printed bloc.
308             for (int iCols1 = this->m_iCols1PrintState ; iCols1 < this->getCols() ; iCols1++)
309             {
310                 for (int iRows1 = 0 ; iRows1 < this->getRows() ; iRows1++)
311                 {
312                     int iWidth  = 0;
313                     _piDims[0]  = iRows1;
314                     _piDims[1]  = iCols1;
315                     int iPos    = ArrayOf<T>::getIndex(_piDims);
316
317                     getIntFormat(ArrayOf<T>::get(iPos), &iWidth);
318                     piSize[iCols1] = (std::max)(piSize[iCols1], iWidth);
319                 }
320
321                 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
322                 {
323                     //find the limit, print this part
324                     for (int iRows2 = this->m_iRows2PrintState ; iRows2 < this->getRows() ; iRows2++)
325                     {
326                         iCurrentLine++;
327                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
328                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == this->m_iRows2PrintState) ||
329                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != this->m_iRows2PrintState)))
330                         {
331                             if (this->m_iRows2PrintState == 0 && iRows2 != 0)
332                             {
333                                 //add header
334                                 addColumnString(ostr, iLastCol + 1, iCols1);
335                             }
336
337                             ostr << ostemp.str();
338                             this->m_iRows2PrintState = iRows2;
339                             this->m_iCols1PrintState = iLastCol;
340                             return false;
341                         }
342
343                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
344                         {
345                             _piDims[0]  = iRows2;
346                             _piDims[1]  = iCols2;
347                             int iPos    = ArrayOf<T>::getIndex(_piDims);
348
349                             addIntValue(&ostemp, ArrayOf<T>::get(iPos), piSize[iCols2]);
350                         }
351                         ostemp << std::endl;
352                     }
353                     iLen = 0;
354
355                     iCurrentLine++;
356                     if (this->m_iRows2PrintState == 0)
357                     {
358                         iCurrentLine += 3;
359                         addColumnString(ostr, iLastCol + 1, iCols1);
360                     }
361
362                     ostr << ostemp.str();
363                     ostemp.str(L"");
364                     iLastCol = iCols1;
365                     this->m_iRows2PrintState = 0;
366                     this->m_iCols1PrintState = 0;
367                 }
368
369                 iLen += piSize[iCols1] + SIGN_LENGTH + SIZE_BETWEEN_TWO_VALUES;
370             }
371
372             for (int iRows2 = this->m_iRows2PrintState ; iRows2 < this->getRows() ; iRows2++)
373             {
374                 iCurrentLine++;
375                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
376                 {
377                     if (this->m_iRows2PrintState == 0 && iLastCol != 0)
378                     {
379                         //add header
380                         addColumnString(ostr, iLastCol + 1, GenericType::getCols());
381                     }
382
383                     ostr << ostemp.str();
384                     this->m_iRows2PrintState = iRows2;
385                     this->m_iCols1PrintState = iLastCol;
386                     return false;
387                 }
388
389                 for (int iCols2 = iLastCol ; iCols2 < GenericType::getCols() ; iCols2++)
390                 {
391                     _piDims[0]  = iRows2;
392                     _piDims[1]  = iCols2;
393                     int iPos    = ArrayOf<T>::getIndex(_piDims);
394
395                     addIntValue(&ostemp, ArrayOf<T>::get(iPos), piSize[iCols2]);
396                 }
397                 ostemp << std::endl;
398             }
399
400             if (this->m_iRows2PrintState == 0 && iLastCol != 0)
401             {
402                 addColumnString(ostr, iLastCol + 1, GenericType::getCols());
403             }
404
405             ostr << ostemp.str();
406             delete[] piSize;
407         }
408
409         return true;
410     }
411
412     virtual T getNullValue() override
413     {
414         return T(0);
415     }
416
417     virtual Int<T>* createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/) override
418     {
419         return new Int<T>(_iDims, _piDims);
420     }
421
422     virtual T copyValue(T _data) override
423     {
424         return _data;
425     }
426
427     virtual void deleteAll() override
428     {
429         delete[] ArrayOf<T>::m_pRealData;
430         ArrayOf<T>::m_pRealData = NULL;
431         deleteImg();
432     }
433
434     virtual void deleteImg() override { }
435
436     virtual T* allocData(int _iSize) override
437     {
438         return new T[_iSize];
439     }
440
441     template<typename U, typename V> struct is_same_int
442     {
443         const static bool value = false;
444     };
445     template<typename U> struct is_same_int<U, U>
446     {
447         const static bool value = true;
448     };
449
450 public:
451     bool isInt8() override
452     {
453         return is_same_int<T, char>::value;
454     }
455     bool isInt16() override
456     {
457         return is_same_int<T, short>::value;
458     }
459     bool isInt32() override
460     {
461         return is_same_int<T, int>::value;
462     }
463     bool isInt64() override
464     {
465         return is_same_int<T, long long>::value;
466     }
467     bool isUInt8() override
468     {
469         return is_same_int<T, unsigned char>::value;
470     }
471     bool isUInt16() override
472     {
473         return is_same_int<T, unsigned short>::value;
474     }
475     bool isUInt32() override
476     {
477         return is_same_int<T, unsigned int>::value;
478     }
479     bool isUInt64() override
480     {
481         return is_same_int<T, unsigned long long>::value;
482     }
483
484     bool isUnsigned()
485     {
486         return !isSigned();
487     }
488
489     bool isSigned()
490     {
491         return std::numeric_limits<T>::is_signed;
492     }
493 };
494
495 template<> inline InternalType::ScilabType Int<char>::getType()
496 {
497     return ScilabInt8;
498 }
499 template<> inline InternalType::ScilabType Int<unsigned char>::getType()
500 {
501     return ScilabUInt8;
502 }
503 template<> inline InternalType::ScilabType Int<short>::getType()
504 {
505     return ScilabInt16;
506 }
507 template<> inline InternalType::ScilabType Int<unsigned short>::getType()
508 {
509     return ScilabUInt16;
510 }
511 template<> inline InternalType::ScilabType Int<int>::getType()
512 {
513     return ScilabInt32;
514 }
515 template<> inline InternalType::ScilabType Int<unsigned int>::getType()
516 {
517     return ScilabUInt32;
518 }
519 template<> inline InternalType::ScilabType Int<long long>::getType()
520 {
521     return ScilabInt64;
522 }
523 template<> inline InternalType::ScilabType Int<unsigned long long>::getType()
524 {
525     return ScilabUInt64;
526 }
527
528 template<> inline InternalType::ScilabId Int<char>::getId()
529 {
530     return GenericType::isScalar() ? IdScalarInt8 : IdInt8;
531 }
532 template<> inline InternalType::ScilabId Int<unsigned char>::getId()
533 {
534     return GenericType::isScalar() ? IdScalarUInt8 : IdUInt8;
535 }
536 template<> inline InternalType::ScilabId Int<short>::getId()
537 {
538     return GenericType::isScalar() ? IdScalarInt16 : IdInt16;
539 }
540 template<> inline InternalType::ScilabId Int<unsigned short>::getId()
541 {
542     return GenericType::isScalar() ? IdScalarUInt16 : IdUInt16;
543 }
544 template<> inline InternalType::ScilabId Int<int>::getId()
545 {
546     return GenericType::isScalar() ? IdScalarInt32 : IdInt32;
547 }
548 template<> inline InternalType::ScilabId Int<unsigned int>::getId()
549 {
550     return GenericType::isScalar() ? IdScalarUInt32 : IdUInt32;
551 }
552 template<> inline InternalType::ScilabId Int<long long>::getId()
553 {
554     return GenericType::isScalar() ? IdScalarInt64 : IdInt64;
555 }
556 template<> inline InternalType::ScilabId Int<unsigned long long>::getId()
557 {
558     return GenericType::isScalar() ? IdScalarUInt64 : IdUInt64;
559 }
560
561 // Specializations
562 template<> inline std::wstring Int<char>::getTypeStr() const
563 {
564     return L"int8";
565 }
566
567 template<> inline std::wstring Int<short>::getTypeStr() const
568 {
569     return L"int16";
570 }
571
572 template<> inline std::wstring Int<int>::getTypeStr() const
573 {
574     return L"int32";
575 }
576
577 template<> inline std::wstring Int<long long>::getTypeStr() const
578 {
579     return L"int64";
580 }
581
582 template<> inline std::wstring Int<unsigned char>::getTypeStr() const
583 {
584     return L"uint8";
585 }
586
587 template<> inline std::wstring Int<unsigned short>::getTypeStr() const
588 {
589     return L"uint16";
590 }
591
592 template<> inline std::wstring Int<unsigned int>::getTypeStr() const
593 {
594     return L"uint32";
595 }
596
597 template<> inline std::wstring Int<unsigned long long>::getTypeStr() const
598 {
599     return L"uint64";
600 }
601
602 template<> inline void Int<char>::whoAmI()
603 {
604     std::cout << "types::Int8";
605 }
606
607 template<> inline void Int<short>::whoAmI()
608 {
609     std::cout << "types::Int16";
610 }
611
612 template<> inline void Int<int>::whoAmI()
613 {
614     std::cout << "types::Int32";
615 }
616
617 template<> inline void Int<long long>::whoAmI()
618 {
619     std::cout << "types::Int64";
620 }
621
622 template<> inline void Int<unsigned char>::whoAmI()
623 {
624     std::cout << "types::UInt8";
625 }
626
627 template<> inline void Int<unsigned short>::whoAmI()
628 {
629     std::cout << "types::UInt16";
630 }
631
632 template<> inline void Int<unsigned int>::whoAmI()
633 {
634     std::cout << "types::UInt32";
635 }
636
637 template<> inline void Int<unsigned long long>::whoAmI()
638 {
639     std::cout << "types::UInt64";
640 }
641
642
643 typedef Int<char> Int8;
644 typedef Int<short> Int16;
645 typedef Int<int> Int32;
646 typedef Int<long long> Int64;
647
648 typedef Int<unsigned char> UInt8;
649 typedef Int<unsigned short> UInt16;
650 typedef Int<unsigned int> UInt32;
651 typedef Int<unsigned long long> UInt64;
652
653 #ifdef _MSC_VER
654 template class Int<char>;
655 template class Int<unsigned char>;
656 template class Int<short>;
657 template class Int<unsigned short>;
658 template class Int<int>;
659 template class Int<unsigned int>;
660 template class Int<long long>;
661 template class Int<unsigned long long>;
662 #endif
663 }
664
665
666 #endif /* !__INT_HXX__ */