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