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