STK++ 0.9.13
STK_List1D.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
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 * Purpose: Define the List1D class.
28 * Author: Serge Iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 *
30 **/
31
36#ifndef STK_LIST_H
37#define STK_LIST_H
38
39#include <STKernel.h>
46
47
48#include "STK_Cell.h"
49
50namespace STK
51{
52template< class Type> class List1D;
53template<class Derived> struct BiDirectionalIterator;
54template<class Derived> struct ConstBiDirectionalIterator;
55
56
57namespace hidden
58{
62template<class Type_>
63struct Traits< List1D<Type_> >
64{
71
72 typedef Type_ Type;
73 typedef typename RemoveConst<Type_>::Type const& TypeConst;
74
75 enum
76 {
77 structure_ = Arrays::point_,
78 orient_ = Arrays::by_row_,
79 size_ = UnknownSize,
80 sizeCols_ = UnknownSize,
81 sizeRows_ = 1,
82 storage_ = Arrays::dense_ // always dense
83 };
84
87
88
89 typedef int Index;
90
93
94 typedef std::reverse_iterator<Iterator> ReverseIterator;
95 typedef std::reverse_iterator<ConstIterator> ConstReverseIterator;
96};
97
98
99} // namespace hidden
100
101} // namespace STK
102
103namespace STK
104{
111template<class Type_>
112class List1D: public ITContainer1D< List1D<Type_> >, public IContainerRef
113{
114 public:
117
118 enum
119 {
125 };
126
131
136
137 // Compatibility naming scheme with STL
142
143 using Base::begin;
144 using Base::end;
145 using Base::size;
146 using Base::lastIdx;
147
159 List1D( Range const& I, Type const& v)
161 { initialize(I);
162 Cell* p1 = p_begin_;
163 for ( int j=begin(); j<end(); j++)
164 { (*p1) = v; // overwrite the value of the current cell
165 p1 = p1->getRight(); // Goto Right place
166 }
167 }
173 {
174 // initialize container
175 initialize(T.range());
176 // copy the container
177 Cell* p1 = p_begin_;
178 Cell* pt1 = T.p_begin_;
179 for (int j=T.begin(); j<T.end(); j++)
180 { (*p1) = pt1->data(); // write the value of the current cell
181 p1 = p1->getRight(); // Goto Right
182 pt1 = pt1->getRight(); // Goto Right
183 }
184 }
191 List1D( List1D<Type> const& T, Range const& J, bool ref = true)
193 {
194#ifdef STK_BOUNDS_CHECK
195 if ((J.begin()<T.begin()))
196 { STKOUT_OF_RANGE_1ARG(List1D::List1D,J,J.begin()<T.begin());}
197 if ((J.lastIdx()>T.lastIdx()))
198 { STKOUT_OF_RANGE_1ARG(List1D::List1D,J,J.lastIdx()>T.lastIdx());}
199#endif
200 if (!ref)
201 {
202 initialize(J);
203 (*this) = T;
204 }
205 else
206 {
207 T.moveCurrentPosition(J.begin());
208 p_begin_ = T.p_current_;
209 moveCurrentPosition(J.lastIdx());
210 p_last_ = T.p_current_;
213 }
214 }
216 inline RowRange const& rows() const { return this->range();}
218 inline int beginRows() const { return begin();}
220 inline int endRows() const { return end();}
222 inline int sizeRows() const { return size();}
223
225 inline ColRange cols() const { return ColRange(1);}
227 inline int beginCols() const { return baseIdx;}
229 inline int endCols() const { return baseIdx+1;}
231 inline int sizeCols() const { return 1;};
232
234 inline int lastIdxRows() const { return this->lastIdx();}
236 inline int lastIdxCols() const { return baseIdx;}
237
238 protected:
248 List1D( Cell* const & p_first, Cell* const & p_last, Range const& J)
251 , p_last_(p_last)
252 {
255 }
256 public:
258 ~List1D() { if (!this->isRef()) freeMem();}
260 Cell const* const p_begin() const { return p_begin_;}
262 Cell const* const p_lastIdx() const { return p_last_;}
267 inline Type& elt1Impl(int pos)
268 {
270 return (p_current_->data());
271 }
276 inline Type const& elt1Impl(int pos) const
277 {
279 return (p_current_->data());
280 }
285 inline List1D subImpl(Range const& J) const
286 {
287 if ((J.begin()<begin()))
289 if ((J.lastIdx()>this->lastIdx()))
291 moveCurrentPosition(J.begin());
293 moveCurrentPosition(J.lastIdx());
295 return List1D(p_first, p_last, J);
296 }
300 void shiftImpl(int const& beg)
301 {
302 if (begin() == beg) return;
303 // is this structure just a pointer?
304 if (this->isRef())
306 //compute increment
307 int inc = beg - begin();
308 this->incRange(inc); // update this->range_()
309 currentPosition_ += inc; // update current position
310 }
314 void clear()
315 {
316 if (this->isRef()) return; // Nothing to do for ref
317 freeMem(); // Free mem
318 this->setRange(); // Set to default the dimension
319 }
323 void pushBack(int const& n=1)
324 {
325 // if n==0 nothing to do
326 if (n <= 0) return;
327 // is this structure just a pointer?
328 if (this->isRef())
330 // If the container is empty : create it
331 if (this->empty())
332 { initialize(Range(begin(), n));}
333 else // else adjust the beginning and the sizes
334 {
335 Cell *p1, *p2; // Auxiliary cells;
336 try
337 { p1 = new Cell(p_last_);} // Create the end+1 cell
338 catch (std::bad_alloc & error)
340 // if no error is intercepted
341 p_last_->setRight(p1); // Set the right ending cell
342 for (int j=2; j<=n; j++) // main loop for the other cells
343 { try
344 { p2 = new Cell(p1);} // try to allocate memory
345 catch (std::bad_alloc & error) // if an alloc error occur
346 {
347 while ( p1 != p_last_) // for all cells allocated
348 { p2 = p1->getLeft(); // get the cell left
349 delete p1; // delete the curent cell
350 p1 = p2; // iterate
351 }
352 // set the original right side of cend
353 p_last_->setRight(p_begin_);
355 } // end catch
356 // if no error
357 p1->setRight(p2); // Set the right cell of the current cell
358 p1 = p2; // Set the current cell to the the next cell
359 }
360 p1->setRight(p_begin_); // the last cell point on the first cell
361 p_begin_->setLeft(p1); // the first cell point on the last cell
362 p_last_ = p1; // the last cell adress
363 this->incLast(n); // Update size of the container
364 }
365 }
370 void insert( Range const& I, Type const& v)
371 {
372 insertElt(I.begin(), I.size());
373 for (int i=I.begin(); i<=I.lastIdx(); i++)
374 this->elt(i) = v;
375 }
379 void merge( List1D const& other)
380 {
381 if (other.empty()) return;
382 // is this structure just a pointer?
383 if (this->isRef())
384 { STKRUNTIME_ERROR_NO_ARG(List1D::merge(other),*this is a reference.);}
385 // is T just a pointer?
386 if (other.isRef())
388 // break const reference
389 List1D& otherRef = const_cast<List1D&>(other);
390 // compute horizontal range of the container after insertion
391 Range range(this->range());
392
393 // merge
394 otherRef.p_begin_->setLeft(p_last_);
395 otherRef.p_last_->setRight(p_begin_);
396 p_last_->setRight(otherRef.p_begin_);
397 p_last_ = otherRef.p_last_;
398 p_begin_->setLeft(p_last_);
399
400 // compute first index of the first column added
401 const int first = range.lastIdx() + 1;
402 this->setRange(range.incLast(otherRef.size()));
403 otherRef.setRange(Range(first, other.size()));
404 otherRef.setRef(true);
405
406 // reset p_current_ to first position
407 otherRef.currentPosition_ = first;
408 otherRef.p_current_ = otherRef.p_begin_;
409 }
414 void insertElt( int pos, int const& n =1)
415 {
416 // if n<=0 nothing to do
417 if (n <= 0) return;
418 // is this structure just a pointer?
419 if (this->isRef())
421 if (begin() > pos)
423 if (this->lastIdx()+1 < pos)
425 // Move the current position to j
427 Cell *p0 = p_current_->getLeft(); // Get the j-1 cell
428 Cell *p1 = p0; // Auxiliary cell;
429 // main loop for the other cells
430 for (int j1=1; j1<=n; j1++)
431 {
432 Cell *p2; // Auxiliary cell;
433 try
434 { p2 = new Cell(p1);} // try to allocate memory
435 catch (std::bad_alloc & error) // if an alloc error occur
436 { while ( p1 != p0) // for all cells allocated
437 { p2 = p1; // get the cell left
438 delete p1; // delete the curent cell
439 p1 = p2->getLeft(); // iterate
440 }
441 p0->setRight(p_current_);
443 } // catch block
444 // if no error is intercepted
445 p1->setRight(p2); // Set the right cell of the current cell
446 p1 = p2; // iterate
447 }
448 p1->setRight(p_current_); // the last cell point on the first cell
449 p_current_->setLeft(p1); // the first cell point on the last cell
450 if ( pos==begin() ) // if the beginning was modified
451 { p_begin_ = p0->getRight();} // set new beginning
452 this->incLast(n); // Update the size of the container
453 currentPosition_ +=n; // Update the current position
454 }
458 void popBack(int const& n=1)
459 {
460 // if n<=0 nothing to do
461 if (n <= 0) return;
462 // is this structure just a pointer?
463 if (this->isRef())
465 // if there is elts to erase
466 if (size()<n)
468 // erase elts with pos = end -n +1
469 erase(this->lastIdx() - n +1, n);
470 }
475 void erase(int pos, int const& n=1)
476 {
477 // if n==0 nothing to do
478 if (n<=0) return;
479 // is this structure just a pointer?
480 if (this->isRef())
482 // check bounds
483 if (begin() > pos)
485 if (this->lastIdx() < pos)
486 { STKOUT_OF_RANGE_2ARG(List1D::erase,pos, n,lastIdx() < pos);}
487 if (this->lastIdx() < pos+n-1)
488 { STKOUT_OF_RANGE_2ARG(List1D::erase,pos, n,lastIdx() < pos+n-1);}
489 // Move the current position to pos
491 Cell* p2 = p_current_; // get pos-th cell
492 moveCurrentPositionLeft(); // set current to (pos-1)th position
493 // delete n cells
494 for (int l=1; l<=n; l++)
495 { Cell* p3 = p2->getRight(); // get right cell in p3
496 delete p2; // delete current cell
497 p2 = p3; // next
498 }
499 // If the last column have been erased update p_last_
500 if (pos+n-1 == this->lastIdx()) { p_last_ = p_current_;}
501 // Update the dimension of the container
502 this->decLast(n);
503 // If we have erased all cols
504 if (size() == 0)
505 { setDefault();}
506 else
507 { p2->setLeft(p_current_); // p2 is the j+n cell
508 p_current_->setRight(p2); // p_current_ is on j-1 cell
509 // If the first column has been erased
510 if (pos == begin())
511 { p_begin_ = p2; // Set the new beg cell
512 p_current_ = p2; // p_current_
513 currentPosition_++; // and current position
514 }
515 }
516 }
521 void swap(int const& j1, int const& j2)
522 {
523#ifdef STK_BOUNDS_CHECK
524 if (j1<begin())
526 if (j1>this->lastIdx())
528 if (j2<begin())
530 if (j2>this->lastIdx())
532#endif
533 // get j1th value in aux
535 Cell *p1 = p_current_;
536 Type aux = p1->data();
537 // set j2th value in j1th position
539 (*p1) = p_current_->data();
540 // set j2th value to aux
541 (*p_current_) = aux;
542 }
550 {
551 // We have to resize if this and T have not the same size
552 // but if they have the same size, we don't scale the index
553 if (size()!=T.size()) { this->resize(T.range());}
554
555 /* copy without ovelapping. */
556 if (begin() < T.begin())
557 { Cell *p1 = p_begin_, *pt1 = T.p_begin_;
558 for (int j=1; j<=size(); j++)
559 { (*p1) = pt1->data(); // overwrite the value
560 p1 = p1->getRight(); // Goto Right for this
561 pt1 = pt1->getRight(); // Goto Right for T
562 }
563 }
564 else
565 { Cell *p1 = p_last_, *pt1 = T.p_last_;
566 for (int j=size(); j>=1; j--)
567 { (*p1) = pt1->data(); // overwrite the value
568 p1 = p1->getLeft(); // Goto Left for this
569 pt1 = pt1->getLeft(); // Goto Left for T
570 }
571 }
572 return *this;
573 }
581 {
582 // check if there is something to do
583 if ( this->range() == I) return *this;
584 if (this->isRef())
586 // translate beg
587 shiftImpl(I.begin());
588 // compute number of elements to delete or add
589 const int inc = I.lastIdx() - this->lastIdx();
590 // adjust size of the container
591 if (inc > 0) this->pushBack(inc); // more elements
592 else this->popBack(-inc); // less elements
593 return *this;
594 }
599 {
600 Cell* p1 = p_begin_;
601 for (int j=1; j<=size(); j++)
602 { p1->setData(v); // overwrite the value of the current cell
603 p1 = p1->getRight(); // Goto Right
604 }
605 return *this;
606 }
607 protected:
611 void initialize(Range const& I)
612 {
613 // set new dimensions
614 this->setRange(I);
615 if (this->empty())
616 {
617 setDefault(); return;
618 }
619 // Allocate memory for the cells
620 Cell *p1, *p2; // Auxiliary pointer for cells
621
622 p1 = new Cell(); // pointer on the first cell
623 p_begin_ = p1; // set the first cell
624 // main loop for the other cells
625 for (int j=begin()+1; j<end(); j++)
626 { try
627 { p2 = new Cell(p1);} // try to allocate memory
628 catch (std::bad_alloc & error) // if an alloc error occur
629 { while (p1 != (Cell*)NULL) // for all cells allocated
630 { p2 = p1->getLeft(); // get the cell left
631 delete p1; // delete the cell
632 p1 = p2; // and iterate
633 }
634 // set default
635 setDefault();
636 this->setRange();
637 // and throw the Exception
639 }
640 // if no error is catched
641 p1->setRight(p2); // Set the right cell
642 p1 = p2; // and iterate
643 }
644 p_last_ = p1; // Set the last cell
645 p_last_->setRight(p_begin_); // the last cell point on the first cell
646 p_begin_->setLeft(p_last_); // the first cell point on the last cell
647 currentPosition_ = begin(); // current position is first position
648 p_current_ = p_begin_; // CurrentPositionent cell is first cell
649 }
651 void freeMem()
652 {
653 if (this->isRef()) return; // Nothing to do for ref
654 Cell *p2, *p1 =p_begin_; // Auxiliary pointers for cells
655 // for all cells
656 for (int j=begin(); j<end(); j++)
657 { p2 = p1->getRight(); // get the right cell
658 delete p1; // delete the curent cell
659 p1 = p2; // and iterate
660 }
661 setDefault();
662 }
663
664 private:
666 mutable int currentPosition_;
668 mutable Cell *p_current_;
669
672 { p_begin_ = 0;
673 p_last_ = 0;
674 p_current_ = 0;
676 }
677
679 inline void moveCurrentPositionLeft() const
680 {
681 p_current_ = p_current_->getLeft();
683 }
685 inline void moveCurrentPositionRight() const
686 {
687 p_current_ = p_current_->getRight();
689 }
693 void moveCurrentPosition(int pos) const
694 {
695 if (pos>currentPosition_)
696 {
697 if ((pos-currentPosition_) <= (this->lastIdx()-pos))
699 else // else start from the end
700 for( currentPosition_ = this->lastIdx(), p_current_ = p_last_; currentPosition_!=pos; )
702 }
703 else
704 {
705 if ((currentPosition_-pos) <= (pos-begin()))
707 else // else start from the beginning
710 }
711 }
712 };
713
714} // namespace STK
715
716#endif
717// STK_LIST_H
In this file we define the main traits class we use for the STK++ Containers.
In this file we define utilities functions and enum for the Array classes.
In this file we implement the BiDirectionalIterator class.
This file define the cell classes for the list classes.
In this file we define and implement the DenseRandomIterator and ConstDenseRandomIterator classes.
This is an internal header file, included by other Containers library headers.
in this file we define the interface class ITContainer1D.
#define STKOUT_OF_RANGE_1ARG(Where, Arg, Error)
Definition STK_Macros.h:93
#define STKRUNTIME_ERROR_1ARG(Where, Arg, Error)
Definition STK_Macros.h:129
#define STKOUT_OF_RANGE_2ARG(Where, Arg1, Arg2, Error)
Definition STK_Macros.h:102
#define STKRUNTIME_ERROR_NO_ARG(Where, Error)
Definition STK_Macros.h:138
#define STKRUNTIME_ERROR_2ARG(Where, Arg1, Arg2, Error)
Definition STK_Macros.h:120
This file include all the header files of the project STKernel.
virtual void setData(YArray_ const &y, XArray_ const &x)
set the data set.
Interface base class for homogeneous 1D containers.
bool empty() const
Is there some data ?
void incRange(int n=1)
increment the range of the container (can be negative).
List1D< Type_ > & resize(Range const &I=RowRange())
void setRange(RowRange const &I=RowRange())
Set range of the rows of the container.
void incLast(int n=1)
increment the end of the container (can be negative).
void decLast(int n=1)
decrement the end of the container.
template One dimensional Horizontal List.
Definition STK_List1D.h:113
ReverseIterator reverse_iterator
Definition STK_List1D.h:140
hidden::Traits< List1D< Type_ > >::ConstReverseIterator ConstReverseIterator
Definition STK_List1D.h:135
void pushBack(int const &n=1)
Add n Elts to the container.
Definition STK_List1D.h:323
List1D(List1D< Type > const &T, Range const &J, bool ref=true)
access to many elements.
Definition STK_List1D.h:191
List1D subImpl(Range const &J) const
access to many elements.
Definition STK_List1D.h:285
List1D(Range const &I, Type const &v)
Misc constructor, initialization with a constant.
Definition STK_List1D.h:159
int endRows() const
Definition STK_List1D.h:220
int end() const
int endCols() const
Definition STK_List1D.h:229
ColRange cols() const
Definition STK_List1D.h:225
List1D< Type > & operator=(Type const &v)
operator= : set the container to a constant value.
Definition STK_List1D.h:598
hidden::Traits< List1D< Type_ > >::ReverseIterator ReverseIterator
Definition STK_List1D.h:134
void erase(int pos, int const &n=1)
Delete n elts at the pos index to the container.
Definition STK_List1D.h:475
Cell * p_current_
Current position pointed in the List1D.
Definition STK_List1D.h:668
List1D(List1D< Type > const &T)
Copy constructor.
Definition STK_List1D.h:171
hidden::Traits< List1D< Type_ > >::RowRange RowRange
Definition STK_List1D.h:127
void setDefault()
set members values to default.
Definition STK_List1D.h:671
Type & elt1Impl(int pos)
access to one element.
Definition STK_List1D.h:267
void moveCurrentPosition(int pos) const
Move the current position to pos.
Definition STK_List1D.h:693
int lastIdxCols() const
Definition STK_List1D.h:236
hidden::Traits< List1D< Type_ > >::TypeConst TypeConst
Definition STK_List1D.h:116
void shiftImpl(int const &beg)
New first index for the object.
Definition STK_List1D.h:300
ConstReverseIterator const_reverse_iterator
Definition STK_List1D.h:141
Cell * p_last_
Last Element of the List.
Definition STK_List1D.h:609
~List1D()
destructor.
Definition STK_List1D.h:258
int size() const
void moveCurrentPositionRight() const
move CurrentPositionent position to right
Definition STK_List1D.h:685
hidden::Traits< List1D< Type_ > >::ConstIterator ConstIterator
Definition STK_List1D.h:133
void initialize(Range const &I)
Protected function for initialization.
Definition STK_List1D.h:611
void merge(List1D const &other)
merge this with other.
Definition STK_List1D.h:379
CellHo< Type > Cell
Definition STK_List1D.h:130
ConstIterator const_iterator
Definition STK_List1D.h:139
List1D & operator=(const List1D &T)
operator = : overwrite the List1D with T.
Definition STK_List1D.h:549
Cell * p_begin_
First Element of the List.
Definition STK_List1D.h:608
int lastIdxRows() const
Definition STK_List1D.h:234
int currentPosition_
Current position of pointer p_current_ in the List1D.
Definition STK_List1D.h:666
hidden::Traits< List1D< Type_ > >::Type Type
Definition STK_List1D.h:115
void insertElt(int pos, int const &n=1)
Insert n elts at the position pos of the container.
Definition STK_List1D.h:414
Type const & elt1Impl(int pos) const
access to one element const.
Definition STK_List1D.h:276
ITContainer1D< List1D< Type > > Base
Definition STK_List1D.h:129
hidden::Traits< List1D< Type_ > >::Iterator Iterator
Definition STK_List1D.h:132
List1D< Type > & resizeImpl(Range const &I)
Resize the container.
Definition STK_List1D.h:580
void insert(Range const &I, Type const &v)
Insert element v in the range I of the List1D.
Definition STK_List1D.h:370
List1D()
Default constructor : empty List.
Definition STK_List1D.h:149
int beginCols() const
Definition STK_List1D.h:227
void moveCurrentPositionLeft() const
Move CurrentPositionent position to left.
Definition STK_List1D.h:679
int beginRows() const
Definition STK_List1D.h:218
void popBack(int const &n=1)
Delete n last elements of the container.
Definition STK_List1D.h:458
int lastIdx() const
List1D(Range const &I)
constructor with specified Range.
Definition STK_List1D.h:153
Cell const *const p_lastIdx() const
Definition STK_List1D.h:262
void clear()
Clear the object.
Definition STK_List1D.h:314
int begin() const
void freeMem()
Protected function for deallocation.
Definition STK_List1D.h:651
RowRange const & rows() const
Definition STK_List1D.h:216
int sizeRows() const
Definition STK_List1D.h:222
List1D(Cell *const &p_first, Cell *const &p_last, Range const &J)
constructor by reference, ref_=1.
Definition STK_List1D.h:248
hidden::Traits< List1D< Type_ > >::ColRange ColRange
Definition STK_List1D.h:128
void swap(int const &j1, int const &j2)
Swapping the j1th column and the j2th column.
Definition STK_List1D.h:521
Iterator iterator
Definition STK_List1D.h:138
Cell const *const p_begin() const
Definition STK_List1D.h:260
int sizeCols() const
Definition STK_List1D.h:231
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
Index sub-vector region: Specialization when the size is unknown.
Definition STK_Range.h:265
TRange & incLast(int inc=1)
create the TRange [begin_, end_+inc)
Definition STK_Range.h:349
@ dense_
dense matrix/vector/array/expression
@ point_
row oriented vector/array/expression
@ by_row_
storage by row
const int UnknownSize
This value means that an integer is not known at compile-time, and that instead the value is stored i...
const int baseIdx
base index of the containers created in STK++.
The namespace STK is the main domain space of the Statistical ToolKit project.
TRange< UnknownSize > Range
Definition STK_Range.h:59
bool isRef() const
BiDirectionalIterator< List1D< Type_ > > Iterator
Definition STK_List1D.h:91
RemoveConst< Type_ >::Type const & TypeConst
Definition STK_List1D.h:73
std::reverse_iterator< ConstIterator > ConstReverseIterator
Definition STK_List1D.h:95
std::reverse_iterator< Iterator > ReverseIterator
Definition STK_List1D.h:94
ConstBiDirectionalIterator< List1D< Type_ > > ConstIterator
Definition STK_List1D.h:92