665155dd5bd049d81bdaf87f6f86f85ba8da26dd
[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)
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                     ostr << std::endl << L"       column " << iLastVal + 1 << L" to " << i << std::endl << std::endl;
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                 ostr << std::endl << L"       column " << iLastVal + 1 << L" to " << GenericType::getCols() << std::endl << std::endl;
307             }
308             ostemp << std::endl;
309             ostr << ostemp.str();
310         }
311         else // matrix
312         {
313             std::wostringstream ostemp;
314             int iLen = 0;
315             int iLastCol = this->m_iCols1PrintState;
316
317             //Array with the max printed size of each col
318             int *piSize = new int[GenericType::getCols()];
319             memset(piSize, 0x00, GenericType::getCols() * sizeof(int));
320
321             //compute the row size for padding for each printed bloc.
322             for (int iCols1 = this->m_iCols1PrintState ; iCols1 < this->getCols() ; iCols1++)
323             {
324                 for (int iRows1 = 0 ; iRows1 < this->getRows() ; iRows1++)
325                 {
326                     int iWidth  = 0;
327                     _piDims[0]  = iRows1;
328                     _piDims[1]  = iCols1;
329                     int iPos    = ArrayOf<T>::getIndex(_piDims);
330
331                     if (isSigned())
332                     {
333                         getSignedIntFormat(ArrayOf<T>::get(iPos), &iWidth);
334                     }
335                     else
336                     {
337                         getUnsignedIntFormat(ArrayOf<T>::get(iPos), &iWidth);
338                     }
339                     piSize[iCols1] = std::max(piSize[iCols1], iWidth);
340                 }
341
342                 if (iLen + piSize[iCols1] > iLineLen)
343                 {
344                     //find the limit, print this part
345                     for (int iRows2 = this->m_iRows2PrintState ; iRows2 < this->getRows() ; iRows2++)
346                     {
347                         iCurrentLine++;
348                         if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
349                                 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == this->m_iRows2PrintState) ||
350                                   (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != this->m_iRows2PrintState)))
351                         {
352                             if (this->m_iRows2PrintState == 0 && iRows2 != 0)
353                             {
354                                 //add header
355                                 ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << iCols1 << std::endl << std::endl;
356                             }
357                             ostr << ostemp.str();
358                             this->m_iRows2PrintState = iRows2;
359                             this->m_iCols1PrintState = iLastCol;
360                             return false;
361                         }
362
363                         for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
364                         {
365                             _piDims[0]  = iRows2;
366                             _piDims[1]  = iCols2;
367                             int iPos    = ArrayOf<T>::getIndex(_piDims);
368
369                             if (isSigned())
370                             {
371                                 addSignedIntValue(&ostemp, ArrayOf<T>::get(iPos), piSize[iCols2]);
372                             }
373                             else
374                             {
375                                 addUnsignedIntValue(&ostemp, ArrayOf<T>::get(iPos), piSize[iCols2]);
376                             }
377                         }
378                         ostemp << std::endl;
379                     }
380                     iLen = 0;
381
382                     iCurrentLine++;
383                     if (this->m_iRows2PrintState == 0)
384                     {
385                         iCurrentLine += 3;
386                         ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << iCols1 << std::endl << std::endl;
387                     }
388
389                     ostr << ostemp.str();
390                     ostemp.str(L"");
391                     iLastCol = iCols1;
392                     this->m_iRows2PrintState = 0;
393                     this->m_iCols1PrintState = 0;
394                 }
395
396                 iLen += piSize[iCols1] + SIGN_LENGTH + SIZE_BETWEEN_TWO_VALUES;
397             }
398
399             for (int iRows2 = this->m_iRows2PrintState ; iRows2 < this->getRows() ; iRows2++)
400             {
401                 iCurrentLine++;
402                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
403                 {
404                     if (this->m_iRows2PrintState == 0 && iLastCol != 0)
405                     {
406                         //add header
407                         ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << GenericType::getCols() << std::endl << std::endl;
408                     }
409
410                     ostr << ostemp.str();
411                     this->m_iRows2PrintState = iRows2;
412                     this->m_iCols1PrintState = iLastCol;
413                     return false;
414                 }
415
416                 for (int iCols2 = iLastCol ; iCols2 < GenericType::getCols() ; iCols2++)
417                 {
418                     _piDims[0]  = iRows2;
419                     _piDims[1]  = iCols2;
420                     int iPos    = ArrayOf<T>::getIndex(_piDims);
421
422                     if (isSigned())
423                     {
424                         addSignedIntValue(&ostemp, ArrayOf<T>::get(iPos), piSize[iCols2]);
425                     }
426                     else
427                     {
428                         addUnsignedIntValue(&ostemp, ArrayOf<T>::get(iPos), piSize[iCols2]);
429                     }
430                 }
431                 ostemp << std::endl;
432             }
433
434             if (this->m_iRows2PrintState == 0 && iLastCol != 0)
435             {
436                 ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << GenericType::getCols() << std::endl << std::endl;
437             }
438             ostr << ostemp.str();
439         }
440
441         return true;
442     }
443
444     virtual T getNullValue()
445     {
446         return T(0);
447     }
448
449     virtual Int<T>* createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
450     {
451         return new Int<T>(_iDims, _piDims);
452     }
453
454     virtual T copyValue(T _data)
455     {
456         return _data;
457     }
458
459     virtual void deleteAll()
460     {
461         delete[] ArrayOf<T>::m_pRealData;
462         ArrayOf<T>::m_pRealData = NULL;
463         deleteImg();
464     }
465
466     virtual void deleteImg() { }
467
468     virtual T* allocData(int _iSize)
469     {
470         return new T[_iSize];
471     }
472
473     template<typename U, typename V> struct is_same_int
474     {
475         const static bool value = false;
476     };
477     template<typename U> struct is_same_int<U, U>
478     {
479         const static bool value = true;
480     };
481
482     bool isInt8()
483     {
484         return is_same_int<T, char>::value;
485     }
486     bool isInt16()
487     {
488         return is_same_int<T, short>::value;
489     }
490     bool isInt32()
491     {
492         return is_same_int<T, int>::value;
493     }
494     bool isInt64()
495     {
496         return is_same_int<T, long long>::value;
497     }
498     bool isUInt8()
499     {
500         return is_same_int<T, unsigned char>::value;
501     }
502     bool isUInt16()
503     {
504         return is_same_int<T, unsigned short>::value;
505     }
506     bool isUInt32()
507     {
508         return is_same_int<T, unsigned int>::value;
509     }
510     bool isUInt64()
511     {
512         return is_same_int<T, unsigned long long>::value;
513     }
514
515     bool isUnsigned()
516     {
517         return !isSigned();
518     }
519
520     bool isSigned()
521     {
522         return std::numeric_limits<T>::is_signed;
523     }
524 };
525
526 template<> inline InternalType::ScilabType Int<char>::getType()
527 {
528     return ScilabInt8;
529 }
530 template<> inline InternalType::ScilabType Int<unsigned char>::getType()
531 {
532     return ScilabUInt8;
533 }
534 template<> inline InternalType::ScilabType Int<short>::getType()
535 {
536     return ScilabInt16;
537 }
538 template<> inline InternalType::ScilabType Int<unsigned short>::getType()
539 {
540     return ScilabUInt16;
541 }
542 template<> inline InternalType::ScilabType Int<int>::getType()
543 {
544     return ScilabInt32;
545 }
546 template<> inline InternalType::ScilabType Int<unsigned int>::getType()
547 {
548     return ScilabUInt32;
549 }
550 template<> inline InternalType::ScilabType Int<long long>::getType()
551 {
552     return ScilabInt64;
553 }
554 template<> inline InternalType::ScilabType Int<unsigned long long>::getType()
555 {
556     return ScilabUInt64;
557 }
558
559 template<> inline InternalType::ScilabId Int<char>::getId()
560 {
561     return isScalar() ? IdScalarInt8 : IdInt8;
562 }
563 template<> inline InternalType::ScilabId Int<unsigned char>::getId()
564 {
565     return isScalar() ? IdScalarUInt8 : IdUInt8;
566 }
567 template<> inline InternalType::ScilabId Int<short>::getId()
568 {
569     return isScalar() ? IdScalarInt16 : IdInt16;
570 }
571 template<> inline InternalType::ScilabId Int<unsigned short>::getId()
572 {
573     return isScalar() ? IdScalarUInt16 : IdUInt16;
574 }
575 template<> inline InternalType::ScilabId Int<int>::getId()
576 {
577     return isScalar() ? IdScalarInt32 : IdInt32;
578 }
579 template<> inline InternalType::ScilabId Int<unsigned int>::getId()
580 {
581     return isScalar() ? IdScalarUInt32 : IdUInt32;
582 }
583 template<> inline InternalType::ScilabId Int<long long>::getId()
584 {
585     return isScalar() ? IdScalarInt64 : IdInt64;
586 }
587 template<> inline InternalType::ScilabId Int<unsigned long long>::getId()
588 {
589     return isScalar() ? IdScalarUInt64 : IdUInt64;
590 }
591
592 // Specializations
593 template<> inline std::wstring Int<char>::getTypeStr()
594 {
595     return L"int8";
596 }
597
598 template<> inline std::wstring Int<short>::getTypeStr()
599 {
600     return L"int16";
601 }
602
603 template<> inline std::wstring Int<int>::getTypeStr()
604 {
605     return L"int32";
606 }
607
608 template<> inline std::wstring Int<long long>::getTypeStr()
609 {
610     return L"int64";
611 }
612
613 template<> inline std::wstring Int<unsigned char>::getTypeStr()
614 {
615     return L"uint8";
616 }
617
618 template<> inline std::wstring Int<unsigned short>::getTypeStr()
619 {
620     return L"uint16";
621 }
622
623 template<> inline std::wstring Int<unsigned int>::getTypeStr()
624 {
625     return L"uint32";
626 }
627
628 template<> inline std::wstring Int<unsigned long long>::getTypeStr()
629 {
630     return L"uint64";
631 }
632
633 template<> inline void Int<char>::whoAmI()
634 {
635     std::cout << "types::Int8";
636 }
637
638 template<> inline void Int<short>::whoAmI()
639 {
640     std::cout << "types::Int16";
641 }
642
643 template<> inline void Int<int>::whoAmI()
644 {
645     std::cout << "types::Int32";
646 }
647
648 template<> inline void Int<long long>::whoAmI()
649 {
650     std::cout << "types::Int64";
651 }
652
653 template<> inline void Int<unsigned char>::whoAmI()
654 {
655     std::cout << "types::UInt8";
656 }
657
658 template<> inline void Int<unsigned short>::whoAmI()
659 {
660     std::cout << "types::UInt16";
661 }
662
663 template<> inline void Int<unsigned int>::whoAmI()
664 {
665     std::cout << "types::UInt32";
666 }
667
668 template<> inline void Int<unsigned long long>::whoAmI()
669 {
670     std::cout << "types::UInt64";
671 }
672
673
674 typedef Int<char> Int8;
675 typedef Int<short> Int16;
676 typedef Int<int> Int32;
677 typedef Int<long long> Int64;
678
679 typedef Int<unsigned char> UInt8;
680 typedef Int<unsigned short> UInt16;
681 typedef Int<unsigned int> UInt32;
682 typedef Int<unsigned long long> UInt64;
683
684 #ifdef _MSC_VER
685 template class Int<char>;
686 template class Int<unsigned char>;
687 template class Int<short>;
688 template class Int<unsigned short>;
689 template class Int<int>;
690 template class Int<unsigned int>;
691 template class Int<long long>;
692 template class Int<unsigned long long>;
693 #endif
694 }
695
696
697 #endif /* !__INT_HXX__ */