STK++ 0.9.13
STK_CAllocator.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23 */
24
25/*
26 * Project: stkpp::Arrays
27 * created on: 10 août 2012
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
35#ifndef STK_CALLOCATOR_H
36#define STK_CALLOCATOR_H
37
38namespace STK
39{
40
46template<typename Type, int SizeRows_, int SizeCols_, bool Orient_>
47class CAllocator;
48
49namespace hidden
50{
54template< typename Type_, int SizeRows_, int SizeCols_, bool Orient_>
56{
57 typedef Type_ Type;
58 typedef typename RemoveConst<Type_>::Type const& TypeConst;
59
60 enum
61 {
62 structure_ = (SizeRows_==1) ? (SizeCols_== 1) ? Arrays::number_ : Arrays::point_
65 Arrays::square_ : Arrays::array2D_,
66 orient_ = Orient_,
67 sizeRows_ = SizeRows_,
68 sizeCols_ = SizeCols_,
70 storage_ = Arrays::dense_ // always dense
71 };
72
75
78};
79
80} // namespace hidden
81
82// forward declaration
83template<class Derived> class CAllocatorBase;
84template<class Derived, bool Orient_> class OrientedCAllocator;
85template<class Derived, int SizeRows_, int SizeCols_> class StructuredCAllocator;
86
88template<class Derived>
89class CAllocatorBase: public ITContainer2D<Derived>
90{
91 public:
96
97 enum
98 {
105 };
108
115
116 protected:
120 CAllocatorBase( RowRange const& I, ColRange const& J): Base(I, J) {}
123
124 public:
125
127 RowRange const& rangeRowsInCol(int) const { return this->rows();}
129 ColRange const& rangeColsInRow(int) const { return this->cols();}
130
135 inline Row row(int i) const
136 {
137#ifdef STK_BOUNDS_CHECK
138 if (this->beginRows() > i) { STKOUT_OF_RANGE_1ARG(CAllocatorBase::row, i, beginRows() > i);}
139 if (this->endRows() <= i) { STKOUT_OF_RANGE_1ARG(CAllocatorBase::row, i, endRows() <= i);}
140#endif
141 return Row(this->asDerived(), TRange<1>(i,1), this->cols());
142 }
147 template<int Size_>
149 {
150#ifdef STK_BOUNDS_CHECK
151 if (this->beginRows() > i) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::row, i, J, beginRows() > i);}
152 if (this->endRows() <= i) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::row, i, J, endRows() <= i);}
153 if (this->beginCols() > J.begin()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::row, i, J, beginCols() > J.begin());}
154 if (this->endCols() < J.end()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::row, i, J, endCols() < J.end());}
155#endif
156 return CAllocator<Type, 1, Size_, orient_>(this->asDerived(), TRange<1>(i,1), J);
157 }
158
163 inline Col col(int j) const
164 {
165#ifdef STK_BOUNDS_CHECK
166 if (this->beginCols() > j) { STKOUT_OF_RANGE_1ARG(CAllocatorBase::col, j, beginCols() > j);}
167 if (this->endCols() <= j) { STKOUT_OF_RANGE_1ARG(CAllocatorBase::col, j, endCols() <= j);}
168#endif
169 return Col(this->asDerived(), this->rows(), TRange<1>(j,1));
170 }
175 template<int Size_>
177 {
178#ifdef STK_BOUNDS_CHECK
179 if (this->beginCols() > j) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::col, I, j, beginCols() > j);}
180 if (this->endCols() <= j) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::col, I, j, endCols() <= j);}
181 if (this->beginRows() > I.begin()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::col, I, j, beginRows() > I.begin());}
182 if (this->endRows() < I.end()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::col, I, j, endRows() < I.end());}
183#endif
184 return CAllocator<Type, Size_, 1, orient_>(this->asDerived(), I, TRange<1>(j,1));
185 }
186
191 template<int OtherRows_, int OtherCols_>
194 {
195#ifdef STK_BOUNDS_CHECK
196 if (this->beginRows() > I.begin()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::sub, I, J, beginRows() > I.begin());}
197 if (this->endRows() < I.end()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::sub, I, J, endRows() < I.end());}
198 if (this->beginCols() > J.begin()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::sub, I, J, beginCols() > j);}
199 if (this->endCols() < J.end()) { STKOUT_OF_RANGE_2ARG(CAllocatorBase::sub, I, J, endCols() <= j);}
200#endif
201 return CAllocator<Type, OtherRows_, OtherCols_, orient_>(this->asDerived(), I, J);
202 }
203
204
206 void swapCols(int pos1, int pos2)
207 {
208#ifdef STK_BOUNDS_CHECK
209 if (this->beginCols() > pos1)
210 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapCols,pos1, pos2,beginCols() > pos1);}
211 if (this->endCols() <= pos1)
212 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapCols,pos1, pos2,endCols() <= pos1);}
213 if (this->beginCols() > pos2)
214 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapCols,pos1, pos2,beginCols() > pos2);}
215 if (this->endCols() <= pos2)
216 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapCols,pos1, pos2,endCols()<= pos2);}
217#endif
218 for (int i=this->beginRows(); i< this->endRows(); ++i)
219 { std::swap(this->asDerived().elt2Impl(i, pos1),this->asDerived().elt2Impl(i, pos2));}
220 }
222 void swapRows(int pos1, int pos2)
223 {
224#ifdef STK_BOUNDS_CHECK
225 if (this->beginRows() > pos1)
226 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapRows,pos1, pos2,beginRows() > pos1);}
227 if (this->endRows() <= pos1)
228 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapRows,pos1, pos2,endRows() <= pos1);}
229 if (this->beginRows() > pos2)
230 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapRows,pos1, pos2,beginRows() > pos2);}
231 if (this->endRows() <= pos2)
232 { STKOUT_OF_RANGE_2ARG(CAllocatorBase::swapRows,pos1, pos2,endRows() <= pos2);}
233#endif
234 for (int j=this->beginCols(); j< this->endCols(); ++j)
235 { std::swap(this->asDerived().elt2Impl(pos1, j),this->asDerived().elt2Impl(pos2, j));}
236 }
237};
238
239
243template<class Derived>
244class OrientedCAllocator<Derived, Arrays::by_col_>: public CAllocatorBase<Derived>
245{
246 public:
251
252 enum
253 {
260 };
263
270
271 using Base::rows;
272 using Base::cols;
273
274 protected:
277 : Base(I, J), ldx_(I.size()), allocator_(prod(I, J))
278 {}
281 : Base(A), ldx_(A.ldx()), allocator_(A.allocator_, ref)
282 { if (!ref) allocator_.assign(A.allocator_);}
284 template<class OtherDerived>
286 , RowRange const& I, ColRange const& J)
287 : Base(I, J), ldx_(A.ldx()), allocator_(A.allocator(), true) {}
289 OrientedCAllocator( Type* const& q, int nbRow, int nbCol)
290 : Base(Range(0,nbRow), Range(0,nbCol)), ldx_(nbRow)
291 , allocator_(q, nbRow * nbCol, true)
292 {}
295
296 public:
298 inline AllocatorRange range() const { return allocator_.range();}
300 inline int begin() const { return allocator_.begin();}
302 inline int end() const { return allocator_.end();}
304 inline int size() const { return allocator_.size();}
305
307 inline bool isRef() const { return allocator_.isRef();}
309 inline Type* const& p_data() const { return allocator_.p_data();}
311 inline Allocator const& allocator() const { return allocator_;}
313 inline int ldx() const { return ldx_;}
314
318 inline TypeConst elt2Impl(int i, int j) const { return allocator_[j*ldx_ + i];}
322 inline Type& elt2Impl(int i, int j) { return allocator_[j*ldx_ + i];}
326 inline void setValue(TypeConst v)
327 { allocator_.assign(range(), v);}
329 Derived& move(OrientedCAllocator const& T)
330 {
331 if (this->asPtrDerived() != T.asPtrDerived())
332 {
333 allocator_.move(T.allocator_);
334 this->asDerived().moveImpl(T.asDerived()); // move any other data fields
335 this->setRanges(T.rows(), T.cols());
336 ldx_ = T.ldx_;
337 }
338 return this->asDerived();
339 }
340
341 protected:
343 int ldx_;
347 void moveImpl(OrientedCAllocator const& T) {}
352 {
353 allocator_.exchange(T.allocator_);
354 Base::exchange(T);
355 std::swap(ldx_, T.ldx_);
356 }
363 static Range prod(Range const& I, Range const& J)
364 { return Range(I.size()*J.begin()+I.begin(), I.size()*J.size()); }
367 int shiftInc(int beginRows, int beginCols)
368 { return ldx_*beginCols+beginRows; }
370 void setSizedIdx() {ldx_ = this->sizeRows();}
371};
372
375template<class Derived>
376class OrientedCAllocator<Derived, Arrays::by_row_>: public CAllocatorBase<Derived>
377{
378 public:
383
384 enum
385 {
392 };
395
402
403 using Base::rows;
404 using Base::cols;
405
406 protected:
409 : Base(I, J), ldx_(J.size()), allocator_(prod(I, J))
410 {}
413 : Base(A), ldx_(A.ldx_), allocator_(A.allocator_, ref)
414 { if (!ref) allocator_.assign(A.allocator_);}
416 template<class OtherDerived>
418 , RowRange const& I, ColRange const& J)
419 : Base(I, J), ldx_(A.ldx()), allocator_(A.allocator(), true)
420 {}
422 OrientedCAllocator( Type* const& q, int nbRow, int nbCol)
423 : Base(Range(0,nbRow), Range(0,nbCol)), ldx_(nbCol)
424 , allocator_(q, nbRow * nbCol, true)
425 {}
428
429 public:
431 inline AllocatorRange range() const { return allocator_.range();}
433 inline int begin() const { return allocator_.begin();}
435 inline int end() const { return allocator_.end();}
437 inline int size() const { return allocator_.size();}
438
440 inline bool isRef() const { return allocator_.isRef();}
442 inline Type* const& p_data() const { return allocator_.p_data();}
444 inline Allocator const& allocator() const { return allocator_;}
446 inline int ldx() const { return ldx_;}
450 inline TypeConst elt2Impl(int i, int j) const { return allocator_[i*ldx_ + j];}
454 inline Type& elt2Impl(int i, int j) { return allocator_[i*ldx_ + j];}
458 inline void setValue(TypeConst v) { allocator_.assign(range(), v);}
460 Derived& move(OrientedCAllocator const& T)
461 {
462 if (this->asPtrDerived() != T.asPtrDerived())
463 {
464 allocator_.move(T.allocator_);
465 this->asDerived().moveImpl(T.asDerived()); // move any other data fields
466 this->setRanges(T.rows(), T.cols());
467 ldx_ = T.ldx_;
468 }
469 return this->asDerived();
470 }
471
472 protected:
474 int ldx_;
481 {
482 allocator_.exchange(T.allocator_);
483 Base::exchange(T);
484 std::swap(ldx_, T.ldx_);
485 }
492 static Range prod(Range const& I, Range const& J)
493 { return Range(J.size()*I.begin()+J.begin(), I.size()*J.size());}
495 int shiftInc(int beginRows, int beginCols)
496 { return ldx_*beginRows+beginCols; }
498 void setSizedIdx() { ldx_ = this->sizeCols();}
499};
500
504template<class Derived, int SizeRows_, int SizeCols_>
505class StructuredCAllocator: public OrientedCAllocator<Derived, hidden::Traits<Derived>::orient_>
506{
507 public:
512
513 enum
514 {
521 };
525
532
533 protected:
537 StructuredCAllocator( StructuredCAllocator const& A, bool ref): Base(A, ref) {}
539 template<class OtherDerived, int OtherRows_, int OtherCols_>
545 StructuredCAllocator( Type* const& q, int nbRow, int nbCol): Base(q, nbRow, nbCol) {}
546
547 public:
551 void exchange(StructuredCAllocator &T) { Base::exchange(T);}
555 inline TypeConst elt1Impl(int i) const { return Base::allocator_[i];}
559 inline Type& elt1Impl(int i) { return Base::allocator_[i];}
563 void shift2Impl(int beginRows, int beginCols)
564 {
565 if ((beginRows == this->beginRows())&&(beginCols == this->beginCols())) return;
566 LowBase::shift(beginRows, beginCols);
567 this->allocator_.shift(this->shiftInc(beginRows, beginCols));
568 }
572 void shift1Impl(int begin) { shift2Impl(begin, begin);}
576 Derived& resize1Impl(int size)
577 { return this->asDerived().resize2Impl(size, size);}
578};
579
580
584template<class Derived, int SizeCols_>
586 : public OrientedCAllocator<Derived, hidden::Traits<Derived>::orient_>
587{
588 public:
593
594 enum
595 {
602 };
606
613
614 protected:
616 StructuredCAllocator( RowRange const& I, ColRange const& J): Base(I, J), row_(I.begin()) {}
618 StructuredCAllocator( StructuredCAllocator const& A, bool ref): Base(A, ref), row_(A.row_) {}
620 template<class OtherDerived, int OtherRows_, int OtherCols_>
622 , RowRange const& I, ColRange const& J)
623 : Base(A, I, J), row_(I.begin())
624 {}
626 StructuredCAllocator( Type* const& q, int , int nbCol): Base(q, 1, nbCol), row_(0) {}
627 public:
632 { Base::exchange(T);
633 std::swap(row_, T.row_);
634 }
635
639 inline TypeConst elt1Impl( int j) const { return this->elt2Impl(row_,j);}
643 inline Type& elt1Impl( int j) { return this->elt2Impl(row_,j);}
647 void shift2Impl(int beginRows, int beginCols)
648 {
649 if ((beginRows == this->beginRows())&&(beginCols == this->beginCols())) return;
650 LowBase::shift(beginRows, beginCols);
651 this->allocator_.shift(this->shiftInc(beginRows, beginCols));
652 row_ = beginRows;
653 }
656 void shift1Impl(int beginCols)
657 { shift2Impl(beginCols, beginCols);
658 row_ = beginCols;
659 }
663 Derived& resize1Impl(int sizeCols)
664 { this->asDerived().resize2Impl(1, sizeCols);
665 row_ = this->beginRows();
666 return this->asDerived();
667 }
671 template< int Size_>
673 { return Base::template row<Size_>(row_, J);}
678 { row_ = T.row_;}
679
680 private:
682 int row_;
683};
684
688template<class Derived, int SizeRows_>
690 : public OrientedCAllocator<Derived, hidden::Traits<Derived>::orient_>
691{
692 public:
697
698 enum
699 {
706 };
710
715
716 protected:
719 StructuredCAllocator( RowRange const& I, ColRange const& J): Base(I, J), col_(J.begin()) {}
721 StructuredCAllocator( StructuredCAllocator const& A, bool ref): Base(A, ref), col_(A.col_) {}
723 template<class OtherDerived, int OtherRows_, int OtherCols_>
725 , RowRange const& I, ColRange const& J)
726 : Base(A, I, J)
727 , col_(J.begin())
728 {}
730 StructuredCAllocator( Type* const& q, int nbRow, int): Base(q, nbRow, 1), col_(0) {}
731 public:
736 { Base::exchange(T);
737 std::swap(col_, T.col_);
738 }
742 inline TypeConst elt1Impl( int i) const { return this->elt2Impl(i, col_);}
746 inline Type& elt1Impl( int i) { return this->elt2Impl(i, col_);}
750 void shift2Impl(int beginRows, int beginCols)
751 {
752 if ((beginRows == this->beginRows())&&(beginCols == this->beginCols())) return;
753 LowBase::shift(beginRows, beginCols);
754 this->allocator_.shift(this->shiftInc(beginRows, beginCols));
755 col_ = beginCols;
756 }
760 void shift1Impl(int beginRows)
761 { shift2Impl(beginRows, beginRows);
762 col_ = beginRows;
763 }
767 Derived& resize1Impl(int sizeRow)
768 {
769 this->asDerived().resize2Impl(sizeRow, 1);
770 col_ = this->beginCols();
771 return this->asDerived();
772 }
776 template<int Size_>
778 { return Base::template col<Size_>(I, col_);}
783 { col_ = T.col_;}
784
785 private:
786 int col_;
787};
788
789
793template<class Derived>
794class StructuredCAllocator<Derived, 1, 1>
795 : public OrientedCAllocator<Derived, hidden::Traits<Derived>::orient_>
796{
797 public:
802
803 enum
804 {
811 };
815
820
821 protected:
824 : Base(I, J), row_(I.begin()), col_(J.begin())
825 {}
828 : Base(A, ref), row_(A.row_), col_(A.col_)
829 {}
831 template<class OtherDerived, int OtherRows_, int OtherCols_>
833 , RowRange const& I, ColRange const& J)
834 : Base(A, I, J)
835 , row_(I.begin()), col_(J.begin())
836 {}
838 StructuredCAllocator( Type* const& q, int , int): Base(q, 1, 1), row_(0), col_(0) {}
845 { row_ = T.row_; col_ = T.col_; return *this;}
846
847 public:
852 { Base::exchange(T);
853 std::swap(row_, T.row_);
854 std::swap(col_, T.col_);
855 }
857 inline int size() const { return 1;}
858
860 inline TypeConst elt0Impl() const { return this->elt2Impl(row_, col_);}
862 inline Type& elt0Impl() { return this->elt2Impl(row_, col_);}
864 inline TypeConst elt1Impl(int) const { return this->elt2Impl(row_, col_);}
866 inline Type& elt1Impl(int) { return this->elt2Impl(row_, col_);}
867
871 void shift2Impl(int beginRows, int beginCols)
872 {
873 if ((beginRows == this->beginRows())&&(beginCols == this->beginCols())) return;
874 LowBase::shift(beginRows, beginCols);
875 this->allocator_.shift(this->shiftInc(beginRows, beginCols));
876 row_ = beginRows;
877 col_ = beginCols;
878 }
882 void shift1Impl(int begin)
883 {
884 this->shift2Impl(begin, begin);
885 row_ = begin; col_ = begin;
886 }
888 Derived& resize1Impl(int) { return this->asDerived().resize2Impl(1, 1);}
892 void moveImpl(StructuredCAllocator const& T) { row_ = T.row_; col_ = T.col_;}
893
894 private:
895 int row_;
896 int col_;
897};
898
903template<typename Type_, int SizeRows_, int SizeCols_, bool Orient_>
904class CAllocator: public StructuredCAllocator<CAllocator<Type_, SizeRows_, SizeCols_, Orient_>, SizeRows_, SizeCols_>
905{
906 public:
911
912 enum
913 {
920 };
924
929
930 using Base::allocator_;
934 CAllocator( int, int, Type const& v): Base(SizeRows_, SizeCols_) {Base::Base::setValue(v);}
935 CAllocator( CAllocator const& A, bool ref = true): Base(A, ref)
936 { if (!ref) { allocator_.assign(A.allocator_);} }
937
938 template< int OtherRows_, int OtherCols_>
940 , RowRange const& I, ColRange const& J)
941 : Base(A, I, J)
942 {}
944 CAllocator( Type* const& q, int , int ): Base(q, SizeRows_, SizeCols_) {}
948 void clear() {}
949
951 CAllocator& resize2Impl( int, int) { return *this;}
952 void realloc(int, int) {}
953};
954
959template<typename Type_, bool Orient_>
961 : public StructuredCAllocator<CAllocator<Type_, UnknownSize, UnknownSize, Orient_>, UnknownSize, UnknownSize>
962{
963 public:
968
969 enum
970 {
977 };
980
985
986 using Base::allocator_;
987
989 CAllocator(): Base(0, 0) {}
993 CAllocator( int sizeRows, int sizeCols): Base(sizeRows, sizeCols) {}
998 CAllocator( int sizeRows, int sizeCols, Type const& v): Base(sizeRows, sizeCols)
999 { Base::Base::setValue(v);}
1004 CAllocator( CAllocator const& A, bool ref = true): Base(A, ref)
1005 { if (!ref) { allocator_.assign(A.allocator_);}}
1010 template< int OtherRows_, int OtherCols_>
1012 , RowRange const& I, ColRange const& J)
1013 : Base(A, I, J)
1014 {}
1016 CAllocator( Type* const& q, int nbRow, int nbCol): Base(q, nbRow, nbCol) {}
1020 void clear() { allocator_.free(); this->setRanges();}
1022 CAllocator& resize2Impl( int sizeRows, int sizeCols)
1023 {
1024 if (this->sizeRows() == sizeRows && this->sizeCols() == sizeCols) return *this;
1025 // check size
1026 if ((sizeRows <= 0)||(sizeCols<=0))
1027 {
1028 // free any allocated memory if this is not a reference
1029 allocator_.free();
1030 this->setRanges(sizeRows, sizeCols);
1031 this->setSizedIdx();
1032 return *this;
1033 }
1034 // allocate
1035 allocator_.malloc(this->prod(sizeRows, sizeCols));
1036 this->setRanges(sizeRows, sizeCols);
1037 this->setSizedIdx();
1038 return *this;
1039 }
1045 void realloc(int sizeRows, int sizeCols)
1046 {
1047 if ((sizeRows == this->sizeRows())&&(sizeCols == this->sizeCols())) return;
1048 // create a copy the original data set
1049 CAllocator copy;
1050 this->exchange(copy);
1051 try
1052 {
1053 // create new container
1054 resize2Impl(sizeRows, sizeCols);
1055 this->shift2Impl(copy.beginRows(), copy.beginCols());
1056 // copy data
1057 const int endRow = std::min(copy.endRows(), this->endRows());
1058 const int endCol = std::min(copy.endCols(), this->endCols());
1059 for (int j= this->beginCols(); j < endCol; ++j)
1060 for (int i = this->beginRows(); i< endRow; ++i)
1061 { this->elt(i, j) = copy.elt(i, j);}
1062 }
1063 catch (std::bad_alloc & error) // if an alloc error occur
1064 {
1065 this->exchange(copy); // restore the original container
1066 STKRUNTIME_ERROR_2ARG(Allocator::realloc, sizeRows, sizeCols, memory allocation failed);
1067 }
1068 }
1069};
1070
1074template<typename Type_, int SizeRows_, bool Orient_>
1076 : public StructuredCAllocator<CAllocator<Type_, SizeRows_, UnknownSize, Orient_>, SizeRows_, UnknownSize>
1077{
1078 public:
1083
1084 enum
1085 {
1095
1100
1101 using Base::allocator_;
1102
1103
1104 CAllocator(): Base(sizeRows_, 0) {}
1105 CAllocator( int, int sizeCols): Base(sizeRows_, sizeCols) {}
1106 CAllocator( int, int sizeCols, Type const& v): Base(sizeRows_, sizeCols) { Base::Base::setValue(v);}
1107 CAllocator( CAllocator const& A, bool ref = true): Base(A, ref) { if (!ref) { allocator_.assign(A.allocator_);}}
1108
1109 template< int OtherRows_, int OtherCols_>
1111 , RowRange const& I, ColRange const& J)
1112 : Base(A, I, J)
1113 {}
1115 CAllocator( Type* const& q, int , int nbCol): Base(q, sizeRows_, nbCol) {}
1119 void clear() { allocator_.free(); this->setCols();}
1121 CAllocator& resize2Impl( int, int sizeCols)
1122 {
1123 if (this->sizeCols() == sizeCols) return *this;
1124 // check size
1125 if (sizeCols<=0)
1126 {
1127 // free any allocated memory if it is not a reference
1128 allocator_.free();
1129 this->setRanges(SizeRows_, sizeCols);
1130 this->setSizedIdx();
1131 return *this;
1132 }
1133 // allocate
1134 allocator_.malloc(this->prod(SizeRows_, sizeCols));
1135 this->setRanges(SizeRows_, sizeCols);
1136 this->setSizedIdx();
1137 return *this;
1138 }
1139 void realloc(int, int sizeCols)
1140 {
1141 CAllocator copy;// create a copy the original data set
1142 this->exchange(copy);
1143 try
1144 {
1145 // create new container
1146 resize2Impl(SizeRows_, sizeCols);
1147 this->shift2Impl(copy.beginRows(), copy.beginCols());
1148 // copy data
1149 const int endCol = std::min(copy.endCols(), this->endCols());
1150 for (int j= this->beginCols(); j < endCol; ++j)
1151 for (int i = this->beginRows(); i < this->endRows(); ++i)
1152 { this->elt(i, j) = copy.elt(i, j);}
1153
1154 }
1155 catch (std::bad_alloc const& error) // if an alloc error occur
1156 {
1157 this->exchange(copy); // restore the original container
1158 STKRUNTIME_ERROR_2ARG(Allocator::realloc, sizeRows_, sizeCols, memory allocation failed);
1159 }
1160 }
1161};
1162
1166template<typename Type_, bool Orient_, int SizeCols_>
1168 : public StructuredCAllocator<CAllocator<Type_, UnknownSize, SizeCols_, Orient_>, UnknownSize, SizeCols_>
1169{
1170 public:
1175
1176 enum
1177 {
1185
1194
1195 using Base::allocator_;
1196
1198 CAllocator( int sizeRows, int): Base(sizeRows, SizeCols_) {}
1199
1200 CAllocator( int sizeRows, int, Type const& v): Base(sizeRows, SizeCols_){ this->asDerived().setValue(v);}
1201 CAllocator( CAllocator const& A, bool ref = true): Base(A, ref)
1202 { if (!ref) { allocator_.assign(A.allocator_);} }
1203
1205 template< int OtherRows_, int OtherCols_>
1207 , RowRange const& I, ColRange const& J)
1208 : Base(A, I, J)
1209 {}
1211 CAllocator( Type* const& q, int nbRow, int ): Base(q, nbRow, SizeCols_) {}
1214
1216 void clear() { allocator_.free(); this->setRows();}
1218 CAllocator& resize2Impl( int sizeRows, int)
1219 {
1220 if (this->sizeRows() == sizeRows) return *this;
1221 if (sizeRows <= 0)// check if
1222 {
1223 // free any allocated memory if it is not a reference
1224 allocator_.free();
1225 this->setRanges(sizeRows, SizeCols_);
1226 this->setSizedIdx();
1227 return *this;
1228 }
1229 // allocate
1230 allocator_.malloc(this->prod(sizeRows, SizeCols_));
1231 this->setRanges(sizeRows, SizeCols_);
1232 this->setSizedIdx();
1233 return *this;
1234 }
1235 void realloc(int sizeRows, int)
1236 {
1237 // create a copy the original data set
1238 CAllocator copy;
1239 this->exchange(copy);
1240 try
1241 {
1242 // create new container
1243 resize2Impl(sizeRows, SizeCols_);
1244 this->shift2Impl(copy.beginRows(), copy.beginCols());
1245 // copy data
1246 const int endRow = std::min(copy.endRows(), this->endRows());
1247 for (int j= this->beginCols(); j < this->endCols(); ++j)
1248 for (int i = this->beginRows(); i< endRow; ++i)
1249 { this->elt(i, j) = copy.elt(i, j);}
1250 }
1251 catch (std::bad_alloc & error) // if an alloc error occur
1252 {
1253 this->exchange(copy); // restore the original container
1254 STKRUNTIME_ERROR_2ARG(Allocator::realloc, sizeRows, SizeCols_, memory allocation failed);
1255 }
1256 }
1257};
1258
1259} // namespace STK
1260
1261#endif /* STK_CALLOCATOR_H */
#define STKOUT_OF_RANGE_1ARG(Where, Arg, Error)
Definition STK_Macros.h:93
#define STKOUT_OF_RANGE_2ARG(Where, Arg1, Arg2, Error)
Definition STK_Macros.h:102
#define STKRUNTIME_ERROR_2ARG(Where, Arg1, Arg2, Error)
Definition STK_Macros.h:120
Base class for CAllocators.
ColRange const & rangeColsInRow(int) const
CAllocator< Type, OtherRows_, OtherCols_, orient_ > sub(TRange< OtherRows_ > const &I, TRange< OtherCols_ > const &J) const
Access to the sub-part (I,J) of the Allocator.
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
ITContainer2D< Derived > Base
RowRange const & rangeRowsInCol(int) const
hidden::Traits< Derived >::Col Col
CAllocatorBase()
default constructor
hidden::Traits< Derived >::TypeConst TypeConst
hidden::Traits< Derived >::Row Row
CAllocator< Type, Size_, 1, orient_ > col(TRange< Size_ > const &I, int j) const
Access to the column (I,j) of the Allocator.
TRange< sizeProd_ > AllocatorRange
Type of the Range for the allocator.
Row row(int i) const
Access to the ith row of the Allocator.
Col col(int j) const
Access to the jth column of the Allocator.
CAllocator< Type, 1, Size_, orient_ > row(int i, TRange< Size_ > const &J) const
Access to the row (i,J) of the Allocator.
hidden::Traits< Derived >::Type Type
CAllocatorBase(CAllocatorBase const &A)
copy constructor
hidden::Traits< Derived >::Allocator Allocator
void swapRows(int pos1, int pos2)
CAllocatorBase(RowRange const &I, ColRange const &J)
constructor
void swapCols(int pos1, int pos2)
CAllocator(Type *const &q, int, int nbCol)
wrapper constructor for 0 based C-Array
CAllocator(CAllocator< Type, OtherRows_, OtherCols_, Orient_ > const &A, RowRange const &I, ColRange const &J)
hidden::Traits< CAllocator >::TypeConst TypeConst
StructuredCAllocator< CAllocator, SizeRows_, UnknownSize > Base
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
CAllocator & resize2Impl(int, int sizeCols)
resize allocator
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
CAllocator(Type *const &q, int nbRow, int)
wrapper constructor for 0 based C-Array
hidden::Traits< CAllocator >::TypeConst TypeConst
TRange< sizeProd_ > AllocatorRange
Type of the Range for the columns.
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
CAllocator(CAllocator< Type, OtherRows_, OtherCols_, Orient_ > const &A, RowRange const &I, ColRange const &J)
wrap other allocator
StructuredCAllocator< CAllocator, UnknownSize, SizeCols_ > Base
CAllocator & resize2Impl(int sizeRows, int)
resize the rows
CAllocator(CAllocator const &A, bool ref=true)
Copy or wrapper constructor.
hidden::Traits< CAllocator >::TypeConst TypeConst
void realloc(int sizeRows, int sizeCols)
function for memory reallocation.
CAllocator(CAllocator< Type, OtherRows_, OtherCols_, Orient_ > const &A, RowRange const &I, ColRange const &J)
Wrapper constructor.
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
CAllocator(Type *const &q, int nbRow, int nbCol)
wrapper constructor for 0 based C-Array
CAllocator & resize2Impl(int sizeRows, int sizeCols)
resize CAllocator
CAllocator(int sizeRows, int sizeCols)
Constructor with specified size.
StructuredCAllocator< CAllocator, UnknownSize, UnknownSize > Base
CAllocator(int sizeRows, int sizeCols, Type const &v)
Constructor with specified size and specified value.
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
Allocator for dense Array classes.
CAllocator(CAllocator const &A, bool ref=true)
hidden::Traits< CAllocator >::Type Type
MemAllocator< Type, SizeRows_ *SizeCols_ > Allocator
IContainer2D< SizeRows_, SizeCols_ > LowBase
void clear()
clear allocated memories
hidden::Traits< CAllocator >::TypeConst TypeConst
CAllocator(int, int, Type const &v)
void realloc(int, int)
CAllocator & resize2Impl(int, int)
resize this
hidden::Traits< CAllocator >::Row Row
CAllocator()
default constructor
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
CAllocator(Type *const &q, int, int)
wrapper constructor for 0 based C-Array
~CAllocator()
destructor
CAllocator(CAllocator< Type, OtherRows_, OtherCols_, Orient_ > const &A, RowRange const &I, ColRange const &J)
hidden::Traits< CAllocator >::Col Col
StructuredCAllocator< CAllocator, SizeRows_, SizeCols_ > Base
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
Interface base class for homogeneous 2D containers like allocators.
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
void setSizedIdx()
set the index corresponding to the actual size of the allocator.
int shiftInc(int beginRows, int beginCols)
return the increment to apply to a zero based pointer corresponding to the actual first row and first...
OrientedCAllocator(Type *const &q, int nbRow, int nbCol)
wrapper constructor for 0 based C-Array
OrientedCAllocator(OrientedCAllocator const &A, bool ref)
copy constructor
OrientedCAllocator(RowRange const &I, ColRange const &J)
default constructor
static Range prod(Range const &I, Range const &J)
Compute the range of the 1D Allocator when we want to allocate a 2D array with range I for the rows a...
hidden::Traits< Derived >::Allocator Allocator
Derived & move(OrientedCAllocator const &T)
move T to this without copying data
void exchange(OrientedCAllocator &T)
exchange T with this.
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
int ldx_
leading dimension of the data set
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
OrientedCAllocator(OrientedCAllocator< OtherDerived, Arrays::by_col_ > const &A, RowRange const &I, ColRange const &J)
Reference constructor.
TRange< sizeProd_ > AllocatorRange
Type of the Range for the allocator.
void moveImpl(OrientedCAllocator const &T)
do nothing by default
hidden::Traits< Derived >::TypeConst TypeConst
void setValue(TypeConst v)
set a value to this allocator.
OrientedCAllocator(OrientedCAllocator const &A, bool ref)
copy constructor
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
OrientedCAllocator(Type *const &q, int nbRow, int nbCol)
wrapper constructor for 0 based C-Array
TRange< sizeProd_ > AllocatorRange
Type of the Range for the allocator.
int shiftInc(int beginRows, int beginCols)
return the increment corresponding to the actual first row an column.
static Range prod(Range const &I, Range const &J)
Compute the range of the 1D Allocator when we want to allocate a 2D array with I indexes in the first...
void setValue(TypeConst v)
set a value to this container.
OrientedCAllocator(OrientedCAllocator< OtherDerived, Arrays::by_row_ > const &A, RowRange const &I, ColRange const &J)
Reference constructor.
hidden::Traits< Derived >::TypeConst TypeConst
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
hidden::Traits< Derived >::Allocator Allocator
OrientedCAllocator(RowRange const &I, ColRange const &J)
constructor with specified ranges
void setSizedIdx()
set the index corresponding to the actual size of the allocator.
void exchange(OrientedCAllocator &T)
exchange T with this.
Derived & move(OrientedCAllocator const &T)
move T to this without copying data
int ldx_
leading dimension of the data set
hidden::Traits< Derived >::Row Row
hidden::Traits< Derived >::Col Col
hidden::Traits< Derived >::Type Type
StructuredCAllocator(Type *const &q, int, int)
wrapper constructor for 0 based C-Array
void shift1Impl(int begin)
shift the first indexes of the allocator.
StructuredCAllocator(StructuredCAllocator const &A, bool ref)
copy constructor
void moveImpl(StructuredCAllocator const &T)
move T to this.
void shift2Impl(int beginRows, int beginCols)
shift the first indexes of the allocator
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
StructuredCAllocator(RowRange const &I, ColRange const &J)
Default constructor.
hidden::Traits< Derived >::Allocator Allocator
IContainer2D< sizeRows_, sizeCols_ > LowBase
Derived & resize1Impl(int)
resize the allocator (for square and diagonal matrices).
StructuredCAllocator & move(StructuredCAllocator const &T)
move T to this.
void exchange(StructuredCAllocator &T)
exchange T with this.
hidden::Traits< Derived >::TypeConst TypeConst
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
OrientedCAllocator< Derived, orient_ > Base
StructuredCAllocator(StructuredCAllocator< OtherDerived, OtherRows_, OtherCols_ > const &A, RowRange const &I, ColRange const &J)
Reference constructor.
void shift2Impl(int beginRows, int beginCols)
shift the first indexes of the allocator
void exchange(StructuredCAllocator &T)
exchange T with this.
Derived & resize1Impl(int sizeCols)
resize the allocator.
StructuredCAllocator(RowRange const &I, ColRange const &J)
Default constructor.
OrientedCAllocator< Derived, orient_ > Base
CAllocator< Type, 1, Size_, orient_ > subVector(TRange< Size_ > const &J) const
TRange< sizeProd_ > AllocatorRange
Type of the Range for the allocator.
StructuredCAllocator(StructuredCAllocator const &A, bool ref)
copy constructor
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
StructuredCAllocator(Type *const &q, int, int nbCol)
wrapper constructor for 0 based C-Array
IContainer2D< sizeRows_, sizeCols_ > LowBase
hidden::Traits< Derived >::Allocator Allocator
hidden::Traits< Derived >::TypeConst TypeConst
void moveImpl(StructuredCAllocator const &T)
move T to this.
int row_
row of the point (needed when this is a reference)
void shift1Impl(int beginCols)
shift the first column index of the allocator.
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
StructuredCAllocator(StructuredCAllocator< OtherDerived, OtherRows_, OtherCols_ > const &A, RowRange const &I, ColRange const &J)
Reference constructor.
void shift2Impl(int beginRows, int beginCols)
shift the first indexes of the allocator
StructuredCAllocator(RowRange const &I, ColRange const &J)
Default constructor.
CAllocator< Type, Size_, 1, orient_ > subVector(TRange< Size_ > const &I) const
StructuredCAllocator(Type *const &q, int nbRow, int)
wrapper constructor for 0 based C-Array
void shift1Impl(int beginRows)
shift the first row index of the allocator.
hidden::Traits< Derived >::Allocator Allocator
StructuredCAllocator(StructuredCAllocator< OtherDerived, OtherRows_, OtherCols_ > const &A, RowRange const &I, ColRange const &J)
Reference constructor.
StructuredCAllocator(StructuredCAllocator const &A, bool ref)
copy constructor
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
IContainer2D< sizeRows_, sizeCols_ > LowBase
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
Derived & resize1Impl(int sizeRow)
resize the allocator.
void moveImpl(StructuredCAllocator const &T)
move T to this.
hidden::Traits< Derived >::TypeConst TypeConst
OrientedCAllocator< Derived, orient_ > Base
void exchange(StructuredCAllocator &T)
exchange T with this.
Base class for the general by_col_ structured case.
void shift2Impl(int beginRows, int beginCols)
shift the first indexes of the allocator
Derived & resize1Impl(int size)
resize the allocator (for square and diagonal matrices).
TRange< sizeCols_ > ColRange
Type of the Range for the columns.
hidden::Traits< Derived >::Allocator Allocator
StructuredCAllocator(StructuredCAllocator< OtherDerived, OtherRows_, OtherCols_ > const &A, RowRange const &I, ColRange const &J)
Reference constructor.
hidden::Traits< Derived >::TypeConst TypeConst
OrientedCAllocator< Derived, orient_ > Base
StructuredCAllocator(RowRange const &I, ColRange const &J)
Default constructor.
StructuredCAllocator(StructuredCAllocator const &A, bool ref)
copy constructor
hidden::Traits< Derived >::Row Row
TRange< sizeRows_ > RowRange
Type of the Range for the rows.
TypeConst elt1Impl(int i) const
IContainer2D< sizeRows_, sizeCols_ > LowBase
void exchange(StructuredCAllocator &T)
exchange T with this.
void shift1Impl(int begin)
shift the first indexes of the allocator (for square and diagonal matrices).
hidden::Traits< Derived >::Type Type
hidden::Traits< Derived >::Col Col
StructuredCAllocator(Type *const &q, int nbRow, int nbCol)
wrapper constructor for 0 based C-Array
TRange< sizeProd_ > AllocatorRange
Type of the Range for the allocator.
Index sub-vector region: Specialization when the size is unknown.
Definition STK_Range.h:265
@ number_
(1,1) matrix/vector/array/expression (like a number)
@ point_
row oriented vector/array/expression
@ vector_
column oriented vector/array/expression
@ square_
square matrix/array/expression
const int UnknownSize
This value means that an integer is not known at compile-time, and that instead the value is stored i...
The namespace STK is the main domain space of the Statistical ToolKit project.
Convenient structure for computing the product of two template integer parameters without overflow.
MemAllocator< Type_, sizeProd_ > Allocator
Type of the base allocator allocating data.