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