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