2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
4 * Copyright (C) 2019 - Stéphane MOTTELET
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
19 #include "doubleexp.hxx"
20 #include "tostring_common.hxx"
21 #include "configvariable.hxx"
22 #include "type_traits.hxx"
23 #include "types_tools.hxx"
28 #include "elem_common.h"
29 #include "localization.h"
30 #include "charEncoding.h"
31 #include "os_string.h"
36 Double* Double::Empty()
38 return new Double(0, 0);
41 Double* Double::Identity(int _iRows, int _iCols)
44 Double* pI = new Double(_iRows, _iCols, &pdbl);
46 for (int i = 0 ; i < std::min(_iRows, _iCols) ; i++)
51 if (_iRows == -1 && _iCols == -1)
58 Double* Double::Identity(int _iDims, const int* _piDims)
60 Double* pI = new Double(_iDims, _piDims);
62 int iMinDim = _piDims[0];
63 for (int i = 1 ; i < _iDims ; i++)
65 if (_piDims[i] < iMinDim)
71 int* piIndex = new int[_iDims];
72 for (int i = 0; i < iMinDim; i++)
74 for (int j = 0 ; j < _iDims ; j++)
79 int index = getIndexWithDims(piIndex, _piDims, _iDims);
87 Double* Double::Identity(int _iDims, const int* _piDims, double _dblReal)
89 Double* pI = new Double(_iDims, _piDims);
91 int iMinDim = _piDims[0];
92 for (int i = 1; i < _iDims; i++)
94 if (_piDims[i] < iMinDim)
100 int* piIndex = new int[_iDims];
101 for (int i = 0; i < iMinDim; i++)
103 for (int j = 0; j < _iDims; j++)
108 int index = getIndexWithDims(piIndex, _piDims, _iDims);
109 pI->set(index, _dblReal);
116 Double* Double::Identity(int _iDims, const int* _piDims, double _dblReal, double _dblImg)
118 Double* pI = new Double(_iDims, _piDims, true);
120 int iMinDim = _piDims[0];
121 for (int i = 1; i < _iDims; i++)
123 if (_piDims[i] < iMinDim)
125 iMinDim = _piDims[i];
129 for (int i = 0; i < iMinDim; i++)
131 int* piIndex = new int[_iDims];
132 for (int j = 0; j < _iDims; j++)
137 int index = getIndexWithDims(piIndex, _piDims, _iDims);
138 pI->set(index, _dblReal);
139 pI->setImg(index, _dblImg);
145 bool Double::isEmpty()
147 if (getDims() == 2 && getRows() == 0 && getCols() == 0)
156 if (isDeletable() == true)
161 Inspector::removeItem(this);
165 Double::Double(int _iRows, int _iCols, bool _bComplex, bool _bZComplex)
167 int piDims[2] = {_iRows, _iCols};
168 double *pReal = NULL;
170 setViewAsZComplex(_bZComplex);
171 if (_bComplex == false || _bZComplex)
173 create(piDims, 2, &pReal, NULL);
177 create(piDims, 2, &pReal, &pImg);
180 setViewAsInteger(false);
182 Inspector::addItem(this);
186 Double::Double(double _dblReal)
194 m_iSizeMax = m_iSize;
195 m_pRealData = new double[1];
196 setViewAsInteger(false);
197 setViewAsZComplex(false);
198 m_pRealData[0] = _dblReal;
200 // int piDims[2] = {1, 1};
202 //create(piDims, 2, &pdblVal, NULL);
203 //pdblVal[0] = _dblReal;
205 Inspector::addItem(this);
209 Double::Double(double _dblReal, double _dblImg)
211 int piDims[2] = {1, 1};
214 setViewAsInteger(false);
215 setViewAsZComplex(false);
216 create(piDims, 2, &pdblR, &pdblI);
221 Inspector::addItem(this);
225 Double::Double(int _iRows, int _iCols, double **_pdblReal)
227 int piDims[2] = {_iRows, _iCols};
228 setViewAsInteger(false);
229 setViewAsZComplex(false);
230 create(piDims, 2, _pdblReal, NULL);
233 Inspector::addItem(this);
237 Double::Double(int _iRows, int _iCols, double **_pdblReal, double **_pdblImg)
239 int piDims[2] = {_iRows, _iCols};
240 setViewAsInteger(false);
241 setViewAsZComplex(false);
242 create(piDims, 2, _pdblReal, _pdblImg);
245 Inspector::addItem(this);
249 Double::Double(int _iDims, const int* _piDims, bool _bComplex, bool _bZComplex)
251 double *pReal = NULL;
253 setViewAsZComplex(_bZComplex);
254 setViewAsInteger(false);
256 if (_bComplex == false || _bZComplex)
258 create(_piDims, _iDims, &pReal, NULL);
262 create(_piDims, _iDims, &pReal, &pImg);
266 Inspector::addItem(this);
270 double* Double::getReal() const
275 double Double::getReal(int _iRows, int _iCols)
277 return get(_iRows, _iCols);
280 bool Double::setInt(int* _piReal)
283 for (int i = 0 ; i < m_iSize ; i++)
285 ret = set(i, static_cast<double>(_piReal[i]));
294 void Double::whoAmI()
296 std::cout << "types::Double";
299 bool Double::setZeros()
301 if (m_pRealData != NULL)
303 memset(m_pRealData, 0x00, m_iSize * sizeof(double));
310 if (isComplex() == true)
312 if (m_pImgData != NULL)
314 memset(m_pImgData, 0x00, m_iSize * sizeof(double));
324 bool Double::setOnes()
326 if (m_pRealData != NULL)
328 std::fill(m_pRealData, m_pRealData + m_iSize, 1);
335 if (isComplex() == true)
337 if (m_pImgData != NULL)
339 std::fill(m_pImgData, m_pImgData + m_iSize, 1);
349 bool Double::subMatrixToString(std::wostringstream& ostr, int* _piDims, int /*_iDims*/)
351 int iCurrentLine = 0;
352 int iLineLen = ConfigVariable::getConsoleWidth();
353 int iMaxLines = ConfigVariable::getConsoleLines();
357 ostr << L"eye *" << std::endl << std::endl;
358 if (isComplex() == false)
360 printDoubleValue(ostr, m_pRealData[0]);
366 printComplexValue(ostr, m_pRealData[0], m_pImgData[0]);
373 printEmptyString(ostr);
381 int iPos = getIndex(_piDims);
383 if (isComplex() == false)
385 printDoubleValue(ostr, m_pRealData[iPos]);
391 printComplexValue(ostr, m_pRealData[iPos], m_pImgData[iPos]);
395 else if (getCols() == 1 && isComplex() == false)
397 // real column vector
399 // compute the number of ligne to print in function of max line
400 int iLinesToPrint = getRows() - m_iRows1PrintState;
401 if ((iMaxLines == 0 && iLinesToPrint >= MAX_LINES) || (iMaxLines != 0 && iLinesToPrint >= iMaxLines))
403 // Number of lines to print exceeds the max lines allowed
404 iLinesToPrint = iMaxLines ? iMaxLines : MAX_LINES;
408 for (int i = 0; i < iLinesToPrint; i++)
410 printDoubleValue(ostr, m_pRealData[m_iRows1PrintState + i]);
414 // Record what line we were at
415 m_iRows1PrintState += iLinesToPrint;
416 if(m_iRows1PrintState != getRows())
418 // ask before continue to print
424 std::wostringstream ostemp;
425 int iLen = SIZE_BETWEEN_TWO_VALUES;
426 int iLastCol = m_iCols1PrintState;
427 // some unchanging field is to be retrieved for later used
429 int iBlankSize = df.bPrintBlank ? BLANK_SIZE : 0;
431 //Array with the max printed size of each col
432 std::vector<int> piSize(getCols());
433 std::vector<int> piRSize(getCols());
434 std::vector<int> piISize(getCols());
436 if (isComplex() == false)
438 //compute the row size for padding for the full matrix
439 for (int iCols1 = 0 ; iCols1 < getCols() ; iCols1++)
441 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
445 int iPos = getIndex(_piDims);
448 getDoubleFormat(m_pRealData[iPos], &df);
449 piSize[iCols1] = std::max(piSize[iCols1], df.iWidth);
453 for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
455 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
457 //find the limit, print this part
458 for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
461 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
462 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
463 (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
465 if (m_iRows2PrintState == 0 && iRows2 != 0)
468 addColumnString(ostr, iLastCol + 1, iCols1);
470 ostr << ostemp.str();
471 m_iRows2PrintState = iRows2;
472 m_iCols1PrintState = iLastCol;
476 for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
480 int iPos = getIndex(_piDims);
483 getDoubleFormat(m_pRealData[iPos], &df);
485 ostemp << SPACE_BETWEEN_TWO_VALUES;
487 df.iWidth = piSize[iCols2];
488 addDoubleValue(&ostemp, m_pRealData[iPos], &df);
493 iLen = SIZE_BETWEEN_TWO_VALUES;
496 if (m_iRows2PrintState == 0)
499 addColumnString(ostr, iLastCol + 1, iCols1);
501 ostr << ostemp.str();
504 m_iRows2PrintState = 0;
505 m_iCols1PrintState = 0;
508 iLen += piSize[iCols1] + SIZE_BETWEEN_TWO_VALUES + iBlankSize;
511 for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
514 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
516 if (m_iRows2PrintState == 0 && iLastCol != 0)
519 addColumnString(ostr, iLastCol + 1, getCols());
522 ostr << ostemp.str();
523 m_iRows2PrintState = iRows2;
524 m_iCols1PrintState = iLastCol;
528 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
532 int iPos = getIndex(_piDims);
535 getDoubleFormat(m_pRealData[iPos], &df);
537 ostemp << SPACE_BETWEEN_TWO_VALUES;
538 df.iWidth = piSize[iCols2];
539 addDoubleValue(&ostemp, m_pRealData[iPos], &df);
544 if (m_iRows2PrintState == 0 && iLastCol != 0)
546 addColumnString(ostr, iLastCol + 1, getCols());
548 ostr << ostemp.str();
552 //compute the row size for padding for the full matrix.
553 for (int iCols1 = 0; iCols1 < getCols() ; iCols1++)
555 DoubleFormat dfR, dfI;
556 for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
561 int iPos = getIndex(_piDims);
563 getComplexFormat(m_pRealData[iPos], m_pImgData[iPos], &iTotalWidth, &dfR, &dfI);
564 // keep track of real and imaginary part width for further alignment
565 piISize[iCols1] = std::max(piISize[iCols1], dfI.iWidth);
566 piRSize[iCols1] = std::max(piRSize[iCols1], dfR.iWidth);
568 piSize[iCols1] = piISize[iCols1] + piRSize[iCols1] + 2 * (dfR.bPrintBlank ? BLANK_SIZE : 0) + BLANK_SIZE + SIZE_SYMBOL_I;
571 for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
573 if (iLen + piSize[iCols1] > iLineLen && iCols1 != iLastCol)
575 //find the limit, print this part
576 for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
579 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
580 ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
581 (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
583 if (m_iRows2PrintState == 0 && iRows2 != 0)
586 addColumnString(ostr, iLastCol + 1, iCols1);
588 ostr << ostemp.str();
589 m_iRows2PrintState = iRows2;
590 m_iCols1PrintState = iLastCol;
594 for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
599 int iPos = getIndex(_piDims);
601 DoubleFormat dfR, dfI;
602 getComplexFormat(m_pRealData[iPos], m_pImgData[iPos], &iTotalWidth, &dfR, &dfI);
604 // override with precomputed real part width for alignment of imaginary part sign
605 dfR.iWidth = piRSize[iCols2];
606 dfI.iWidth = piISize[iCols2];
607 ostemp << SPACE_BETWEEN_TWO_VALUES;
608 addDoubleComplexValue(&ostemp, m_pRealData[iPos], m_pImgData[iPos], piSize[iCols2], &dfR, &dfI);
613 iLen = SIZE_BETWEEN_TWO_VALUES;
616 if (m_iRows2PrintState == 0)
619 addColumnString(ostr, iLastCol + 1, iCols1);
621 ostr << ostemp.str();
624 m_iRows2PrintState = 0;
625 m_iCols1PrintState = 0;
628 iLen += piSize[iCols1] + SIZE_BETWEEN_TWO_VALUES;
631 for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
634 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
636 if (m_iRows2PrintState == 0 && iLastCol != 0)
639 addColumnString(ostr, iLastCol + 1, getCols());
642 ostr << ostemp.str();
643 m_iRows2PrintState = iRows2;
644 m_iCols1PrintState = iLastCol;
648 for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
653 int iPos = getIndex(_piDims);
655 DoubleFormat dfR, dfI;
656 getComplexFormat(m_pRealData[iPos], m_pImgData[iPos], &iTotalWidth, &dfR, &dfI);
658 // override with precomputed real part width for aligment of imaginary part sign
659 dfR.iWidth = piRSize[iCols2];
660 dfI.iWidth = piISize[iCols2];
661 ostemp << SPACE_BETWEEN_TWO_VALUES;
662 addDoubleComplexValue(&ostemp, m_pRealData[iPos], m_pImgData[iPos], piSize[iCols2], &dfR, &dfI);
667 if (m_iRows2PrintState == 0 && iLastCol != 0)
669 addColumnString(ostr, iLastCol + 1, getCols());
671 ostr << ostemp.str();
678 Double* Double::clone()
681 Double *pReturn = new Double(m_iDims, m_piDims, isComplex());
682 //memcpy(pReturn->getReal(), m_pRealData, m_iSize * sizeof(double));
683 dcopy_(&m_iSize, m_pRealData, &iOne, pReturn->getReal(), &iOne);
687 pReturn->setComplex(true);
688 //memcpy(pReturn->getImg(), m_pImgData, m_iSize * sizeof(double));
689 dcopy_(&m_iSize, m_pImgData, &iOne, pReturn->getImg(), &iOne);
694 bool Double::fillFromCol(int _iCols, Double *_poSource)
697 int iDestOffset = _iCols * m_iRows;
698 int iSize = _poSource->getSize();
699 double* pdblDest = m_pRealData + iDestOffset;
701 dcopy_(&iSize, _poSource->getReal(), &iOne, pdblDest, &iOne);
705 pdblDest = m_pImgData + iDestOffset;
706 dcopy_(&iSize, _poSource->getImg(), &iOne, pdblDest, &iOne);
711 bool Double::fillFromRow(int _iRows, Double *_poSource)
713 int iCols = _poSource->getCols();
720 for (int i = 0 ; i < iCols ; i++)
722 int iDestOffset = i * m_iRows + _iRows;
723 int iOrigOffset = i * _poSource->getRows();
724 int iSize = _poSource->getRows();
725 double* pdblDest = m_pRealData + iDestOffset;
726 double* pdblSource = _poSource->getReal() + iOrigOffset;
729 dcopy_(&iSize, pdblSource, &iOne, pdblDest, &iOne);
735 bool Double::operator==(const InternalType& it)
737 if (const_cast<InternalType &>(it).isDouble() == false)
742 Double* pdbl = const_cast<InternalType &>(it).getAs<Double>();
744 if (pdbl->getDims() != getDims())
749 for (int i = 0 ; i < getDims() ; i++)
751 if (pdbl->getDimsArray()[i] != getDimsArray()[i])
757 double *pdblReal = pdbl->getReal();
758 for (int i = 0 ; i < getSize() ; i++)
760 if (m_pRealData[i] != pdblReal[i])
767 if (isComplex() && pdbl->isComplex())
769 double *pdblImg = pdbl->getImg();
770 for (int i = 0 ; i < m_iSize ; i++)
772 if (m_pImgData[i] != pdblImg[i])
778 //pdbl complex check all img values == 0
779 else if (pdbl->isComplex())
781 double *pdblImg = pdbl->getImg();
782 for (int i = 0 ; i < m_iSize ; i++)
790 //complex check all img values == 0
791 else if (isComplex())
793 for (int i = 0 ; i < m_iSize ; i++)
805 bool Double::operator!=(const InternalType& it)
807 return !(*this == it);
810 double Double::getNullValue()
815 Double* Double::createEmpty(int _iDims, int* _piDims, bool _bComplex)
817 return new Double(_iDims, _piDims, _bComplex);
820 double Double::copyValue(double _dblData)
825 void Double::deleteAll()
827 if (isViewAsZComplex())
829 vFreeDoubleComplexFromPointer((doublecomplex*)m_pRealData);
833 delete[] m_pRealData;
840 void Double::deleteImg()
842 if (isComplex() && m_pImgData)
849 double* Double::allocData(int _iSize)
851 if (isViewAsZComplex())
853 return (double*)new doublecomplex[_iSize];
857 return new double[_iSize];
861 Double* Double::append(int _iRows, int _iCols, InternalType* _poSource)
863 Double* pIT = checkRef(this, &Double::append, _iRows, _iCols, _poSource);
869 Double* pD = _poSource->getAs<Double>();
870 int iRows = pD->getRows();
871 int iCols = pD->getCols();
872 int iSize = iRows * iCols;
874 //insert without resize
875 if (iRows + _iRows > m_iRows || iCols + _iCols > m_iCols)
880 //Update complexity if necessary
881 setComplex(isComplex() || pD->isComplex());
888 // - real append in x,y
890 if (_iRows == 0 && _iCols == 0)
893 //std::cout << "append 0,0" << std::endl;
894 if (iRows == 1 || iRows == getRows())
896 //std::cout << "full Rows or one row" << std::endl;
900 //std::cout << "iInc : " << iInc << std::endl;
905 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
908 C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg(), &iInc);
912 memset(getImg(), 0x00, iSize * sizeof(double));
917 C2F(dcopy)(&iSize, pD->get(), &iOne, get(), &iInc);
922 //std::cout << "part of row" << std::endl;
925 for (int i = 0 ; i < iCols ; i++)
927 int iOffset = i * getRows();
928 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
931 C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
935 memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
941 for (int i = 0 ; i < iCols ; i++)
943 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + i * getRows(), &iOne);
948 else if (_iRows == 0 || (_iCols == 0 && (iCols == 1 || iRows == 1)))
951 //std::cout << "real append in x,y" << std::endl;
955 //std::cout << "iInc : " << iInc << std::endl;
958 int iOffset = _iCols * getRows() + _iRows;
959 C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
963 int iOffset = _iCols * getRows() + _iRows;
964 C2F(dcopy)(&iSize, pD->get(), &iOne, get() + iOffset, &iInc);
967 C2F(dcopy)(&iSize, pD->getImg(), &iOne, getImg() + iOffset, &iInc);
973 C2F(dcopy)(&iSize, &dblZero, &iZero, getImg() + iOffset, &iInc);
979 //std::cout << "no optimisation" << std::endl;
982 for (int i = 0 ; i < iCols ; i++)
984 int iOffset = (_iCols + i) * getRows() + _iRows;
985 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + iOffset, &iOne);
988 C2F(dcopy)(&iRows, pD->getImg() + i * iRows, &iOne, getImg() + iOffset, &iOne);
992 memset(getImg() + iOffset, 0x00, iRows * sizeof(double));
998 for (int i = 0 ; i < iCols ; i++)
1000 C2F(dcopy)(&iRows, pD->get() + i * iRows, &iOne, get() + (_iCols + i) * getRows() + _iRows, &iOne);
1007 void Double::convertToInteger()
1009 if (isViewAsInteger())
1014 //convert in place double to integer
1015 int* piR = (int*)get();
1016 double *pdblR = get();
1020 int* piI = (int*)getImg();
1021 double *pdblI = getImg();
1023 //normal way to prevent overlap
1024 for (int i = 0 ; i < getSize() ; i++)
1026 piR[i] = (int)pdblR[i];
1027 piI[i] = (int)pdblI[i];
1032 //normal way to prevent overlap
1033 for (int i = 0 ; i < getSize() ; i++)
1035 piR[i] = (int)pdblR[i];
1039 setViewAsInteger(true);
1042 void Double::convertFromInteger()
1044 if (isViewAsInteger() == false)
1050 int* piR = (int*)get();
1051 double *pdblR = get();
1052 //convert in place integer to double
1056 int* piI = (int*)getImg();
1057 double *pdblI = getImg();
1059 //reverse way to prevent overlap
1060 for (int i = getSize() - 1 ; i >= 0 ; i--)
1062 pdblR[i] = (double)piR[i];
1063 pdblI[i] = (double)piI[i];
1068 //reverse way to prevent overlap
1069 for (int i = getSize() - 1 ; i >= 0 ; i--)
1071 pdblR[i] = (double)piR[i];
1075 setViewAsInteger(false);
1078 void Double::convertFromZComplex()
1080 if (isViewAsZComplex() == false)
1086 doublecomplex* pdblZ = (doublecomplex*)get();
1087 m_pRealData = new double[getSize()];
1091 delete[] m_pImgData;
1094 m_pImgData = new double[getSize()];
1096 vGetPointerFromDoubleComplex(pdblZ, getSize(), m_pRealData, m_pImgData);
1097 vFreeDoubleComplexFromPointer(pdblZ);
1098 setViewAsZComplex(false);
1101 void Double::convertToZComplex()
1103 if (isViewAsZComplex())
1109 doublecomplex* pdblZ = NULL;
1113 pdblZ = oGetDoubleComplexFromPointer(getReal(), getImg(), getSize());
1114 delete[] m_pImgData;
1119 pdblZ = oGetDoubleComplexFromPointer(getReal(), NULL, getSize());
1122 delete[] m_pRealData;
1123 m_pRealData = (double*)pdblZ;
1124 setViewAsZComplex(true);
1127 ast::Exp* Double::getExp(const Location& loc)
1129 return new ast::DoubleExp(loc, this);
1132 bool Double::isTrue()
1134 if (isEmpty() || isComplex())
1139 return type_traits::isTrue<double>(m_iSize, m_pRealData);