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