a0fdbc98586dcaf1385c8dcd020f82e6b87b2cf3
[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     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);
190     inline InternalType::ScilabId   getId(void);
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         }
471
472         return true;
473     }
474
475     virtual T getNullValue()
476     {
477         return T(0);
478     }
479
480     virtual Int<T>* createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
481     {
482         return new Int<T>(_iDims, _piDims);
483     }
484
485     virtual T copyValue(T _data)
486     {
487         return _data;
488     }
489
490     virtual void deleteAll()
491     {
492         delete[] ArrayOf<T>::m_pRealData;
493         ArrayOf<T>::m_pRealData = NULL;
494         deleteImg();
495     }
496
497     virtual void deleteImg() { }
498
499     virtual T* allocData(int _iSize)
500     {
501         return new T[_iSize];
502     }
503
504     template<typename U, typename V> struct is_same_int
505     {
506         const static bool value = false;
507     };
508     template<typename U> struct is_same_int<U, U>
509     {
510         const static bool value = true;
511     };
512
513 public:
514     bool isInt8()
515     {
516         return is_same_int<T, char>::value;
517     }
518     bool isInt16()
519     {
520         return is_same_int<T, short>::value;
521     }
522     bool isInt32()
523     {
524         return is_same_int<T, int>::value;
525     }
526     bool isInt64()
527     {
528         return is_same_int<T, long long>::value;
529     }
530     bool isUInt8()
531     {
532         return is_same_int<T, unsigned char>::value;
533     }
534     bool isUInt16()
535     {
536         return is_same_int<T, unsigned short>::value;
537     }
538     bool isUInt32()
539     {
540         return is_same_int<T, unsigned int>::value;
541     }
542     bool isUInt64()
543     {
544         return is_same_int<T, unsigned long long>::value;
545     }
546
547     bool isUnsigned()
548     {
549         return !isSigned();
550     }
551
552     bool isSigned()
553     {
554         return std::numeric_limits<T>::is_signed;
555     }
556 };
557
558 template<> inline InternalType::ScilabType Int<char>::getType()
559 {
560     return ScilabInt8;
561 }
562 template<> inline InternalType::ScilabType Int<unsigned char>::getType()
563 {
564     return ScilabUInt8;
565 }
566 template<> inline InternalType::ScilabType Int<short>::getType()
567 {
568     return ScilabInt16;
569 }
570 template<> inline InternalType::ScilabType Int<unsigned short>::getType()
571 {
572     return ScilabUInt16;
573 }
574 template<> inline InternalType::ScilabType Int<int>::getType()
575 {
576     return ScilabInt32;
577 }
578 template<> inline InternalType::ScilabType Int<unsigned int>::getType()
579 {
580     return ScilabUInt32;
581 }
582 template<> inline InternalType::ScilabType Int<long long>::getType()
583 {
584     return ScilabInt64;
585 }
586 template<> inline InternalType::ScilabType Int<unsigned long long>::getType()
587 {
588     return ScilabUInt64;
589 }
590
591 template<> inline InternalType::ScilabId Int<char>::getId()
592 {
593     return GenericType::isScalar() ? IdScalarInt8 : IdInt8;
594 }
595 template<> inline InternalType::ScilabId Int<unsigned char>::getId()
596 {
597     return GenericType::isScalar() ? IdScalarUInt8 : IdUInt8;
598 }
599 template<> inline InternalType::ScilabId Int<short>::getId()
600 {
601     return GenericType::isScalar() ? IdScalarInt16 : IdInt16;
602 }
603 template<> inline InternalType::ScilabId Int<unsigned short>::getId()
604 {
605     return GenericType::isScalar() ? IdScalarUInt16 : IdUInt16;
606 }
607 template<> inline InternalType::ScilabId Int<int>::getId()
608 {
609     return GenericType::isScalar() ? IdScalarInt32 : IdInt32;
610 }
611 template<> inline InternalType::ScilabId Int<unsigned int>::getId()
612 {
613     return GenericType::isScalar() ? IdScalarUInt32 : IdUInt32;
614 }
615 template<> inline InternalType::ScilabId Int<long long>::getId()
616 {
617     return GenericType::isScalar() ? IdScalarInt64 : IdInt64;
618 }
619 template<> inline InternalType::ScilabId Int<unsigned long long>::getId()
620 {
621     return GenericType::isScalar() ? IdScalarUInt64 : IdUInt64;
622 }
623
624 // Specializations
625 template<> inline std::wstring Int<char>::getTypeStr() const
626 {
627     return L"int8";
628 }
629
630 template<> inline std::wstring Int<short>::getTypeStr() const
631 {
632     return L"int16";
633 }
634
635 template<> inline std::wstring Int<int>::getTypeStr() const
636 {
637     return L"int32";
638 }
639
640 template<> inline std::wstring Int<long long>::getTypeStr() const
641 {
642     return L"int64";
643 }
644
645 template<> inline std::wstring Int<unsigned char>::getTypeStr() const
646 {
647     return L"uint8";
648 }
649
650 template<> inline std::wstring Int<unsigned short>::getTypeStr() const
651 {
652     return L"uint16";
653 }
654
655 template<> inline std::wstring Int<unsigned int>::getTypeStr() const
656 {
657     return L"uint32";
658 }
659
660 template<> inline std::wstring Int<unsigned long long>::getTypeStr() const
661 {
662     return L"uint64";
663 }
664
665 template<> inline void Int<char>::whoAmI()
666 {
667     std::cout << "types::Int8";
668 }
669
670 template<> inline void Int<short>::whoAmI()
671 {
672     std::cout << "types::Int16";
673 }
674
675 template<> inline void Int<int>::whoAmI()
676 {
677     std::cout << "types::Int32";
678 }
679
680 template<> inline void Int<long long>::whoAmI()
681 {
682     std::cout << "types::Int64";
683 }
684
685 template<> inline void Int<unsigned char>::whoAmI()
686 {
687     std::cout << "types::UInt8";
688 }
689
690 template<> inline void Int<unsigned short>::whoAmI()
691 {
692     std::cout << "types::UInt16";
693 }
694
695 template<> inline void Int<unsigned int>::whoAmI()
696 {
697     std::cout << "types::UInt32";
698 }
699
700 template<> inline void Int<unsigned long long>::whoAmI()
701 {
702     std::cout << "types::UInt64";
703 }
704
705
706 typedef Int<char> Int8;
707 typedef Int<short> Int16;
708 typedef Int<int> Int32;
709 typedef Int<long long> Int64;
710
711 typedef Int<unsigned char> UInt8;
712 typedef Int<unsigned short> UInt16;
713 typedef Int<unsigned int> UInt32;
714 typedef Int<unsigned long long> UInt64;
715
716 #ifdef _MSC_VER
717 template class Int<char>;
718 template class Int<unsigned char>;
719 template class Int<short>;
720 template class Int<unsigned short>;
721 template class Int<int>;
722 template class Int<unsigned int>;
723 template class Int<long long>;
724 template class Int<unsigned long long>;
725 #endif
726 }
727
728
729 #endif /* !__INT_HXX__ */