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