SheafSystem  0.0.0.0
ragged_array.impl.h
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Implementation for class template ragged_array.
19 
20 #ifndef RAGGED_ARRAY_IMPL_H
21 #define RAGGED_ARRAY_IMPL_H
22 
23 #ifndef SHEAF_DLL_SPEC_H
24 #include "SheafSystem/sheaf_dll_spec.h"
25 #endif
26 
27 #ifndef RAGGED_ARRAY_H
28 #include "SheafSystem/ragged_array.h"
29 #endif
30 
31 #ifndef ASSERT_CONTRACT_H
32 #include "SheafSystem/assert_contract.h"
33 #endif
34 
35 namespace sheaf
36 {
37 
38 // =============================================================================
39 // RAGGED_ARRAY FACET
40 // =============================================================================
41 
42 // PUBLIC MEMBER FUNCTIONS
43 
44 template <typename T>
46 ragged_array(size_t xct)
47 {
48  // Preconditions:
49 
50  // Body:
51 
52  // Create one row with col count 0.
53 
54  _col_cts.reserve(1);
55  _col_cts.push_back(0);
56 
57  _row_ptrs.reserve(1);
58  _row_ptrs.push_back(0);
59 
60  // Reserve space for xct values.
61 
62  _values.reserve(xct);
63  _values.set_ct(0);
64 
65  // Postconditions:
66 
67  ensure(row_ct() == 1);
68  ensure(col_ct(0) == 0);
69  ensure(value_ct() == 0);
70 
71  // Exit:
72 
73  return;
74 };
75 
76 template <typename T>
78 ragged_array(const ragged_array& xother)
79 {
80  // Preconditions:
81 
82  // Body:
83 
84  (*this) = xother;
85 
86  // Postconditions:
87 
88  ensure(invariant());
89  ensure((*this) == xother);
90 
91  // Exit
92 };
93 
94 template <typename T>
96 ragged_array(const index_type* xcol_cts,
97  index_type xcol_cts_ub)
98 {
99  // Preconditions:
100 
101  require(xcol_cts != 0);
102 
103  // Body:
104 
105  initialize(xcol_cts, xcol_cts_ub);
106 
107  // Postconditions:
108 
109  ensure(invariant());
110  ensure(row_ct() == xcol_cts_ub);
111  ensure_for_all(i, 0, row_ct(), col_ct(i) == xcol_cts[i]);
112 
113  // Exit
114 
115  return;
116 };
117 
118 template <typename T>
120 ragged_array(index_type xrow_ct, index_type xvalue_ct)
121 {
122  // Preconditions:
123 
124  require(xrow_ct > 0);
125  require(xvalue_ct > 0);
126 
127  // Body:
128 
129  _col_cts.reserve(xrow_ct);
130  _col_cts.set_ct(xrow_ct);
131 
132  _row_ptrs.reserve(xrow_ct);
133  _row_ptrs.set_ct(xrow_ct);
134 
135  _values.reserve(xvalue_ct);
136  _values.set_ct(xvalue_ct);
137 
138  // Default column counts are uniform,
139  // except possibly for last one.
140 
141  index_type lcol_ct = xvalue_ct/xrow_ct;
142  _col_cts.assign(lcol_ct);
143  _col_cts.back() = lcol_ct + (xvalue_ct % xrow_ct);
144 
145  for(index_type i=0; i<xrow_ct; i++)
146  {
147  _row_ptrs[i] = i*lcol_ct;
148  }
149 
150  // Postconditions:
151 
152  ensure(invariant());
153  ensure(row_ct() == xrow_ct);
154  ensure(value_ct() == xvalue_ct);
155  ensure_for_all(i, 0, row_ct()-1, col_ct(i) == (value_ct()/row_ct()));
156  ensure(col_ct(row_ct()-1) == ((value_ct()/row_ct()) + (value_ct() % row_ct())));
157 
158  // Exit
159 
160  return;
161 }
162 
163 template <typename T>
166 {
167  // Preconditions:
168 
169  // Body:
170 
171  // Nothing to do.
172 
173  // Postconditions:
174 
175  // Exit
176 
177  return;
178 };
179 
180 template <typename T>
183 operator=(const ragged_array& xother)
184 {
185  // Preconditions:
186 
187  // Body:
188 
189  initialize(xother._col_cts.base(), xother._col_cts.ct());
190 
191  for(index_type i=0; i<value_ct(); i++)
192  {
193  _values[i] = xother._values[i];
194  }
195 
196  // Postconditions:
197 
198  ensure(invariant());
199  ensure(row_ct() == xother.row_ct());
200  ensure_for_all(i, 0, row_ct(), col_ct(i) == xother.col_ct(i));
201  ensure_for_all(i, 0, value_ct(), values()[i] == xother.values()[i]);
202 
203  // Exit:
204 
205  return *this;
206 };
207 
208 template <typename T>
209 bool
211 operator==(const ragged_array& xother) const
212 {
213  // Preconditions:
214 
215  // Body:
216 
217  bool result = (row_ct() == xother.row_ct());
218 
219  for(index_type i=0; result && i<row_ct(); i++)
220  {
221  result = (col_ct(i) == xother.col_ct(i));
222  }
223 
224  for(index_type i=0; result && i<value_ct(); i++)
225  {
226  result = (_values[i] == xother._values[i]);
227  }
228 
229  // Postconditions:
230 
231  // Exit:
232 
233  return result;
234 };
235 
236 template <typename T>
239 row_ct() const
240 {
241  index_type result;
242 
243  // Preconditions:
244 
245  // Body:
246 
247  result = _col_cts.ct();
248 
249  // Postconditions:
250 
251  // Exit
252 
253  return result;
254 };
255 
256 template <typename T>
259 col_ct(const index_type xrow_index) const
260 {
261  index_type result;
262 
263  // Preconditions:
264 
265  require(xrow_index < row_ct());
266 
267  // Body:
268 
269  result = _col_cts[xrow_index];
270 
271  // Postconditions:
272 
273  // Exit
274 
275  return result;
276 }
277 
278 template <typename T>
281 col_cts() const
282 {
283  index_type* result;
284 
285  // Preconditions:
286 
287  // Body:
288 
289  result = _col_cts.base();
290 
291  // Postconditions:
292 
293  ensure(result != 0);
294  ensure(unexecutable(result contains at least row_ct() entries));
295 
296  // Exit
297 
298  return result;
299 };
300 
301 template <typename T>
302 T*
304 values() const
305 {
306  T* result;
307 
308  // Preconditions:
309 
310  // Body:
311 
312  result = _values.base();
313 
314  // Postconditions:
315 
316  //$$ISSUE: result is ==0 when using the default constructor!!!
317  //ensure(result != 0);
318  ensure(unexecutable(result contains value_ct() entries));
319 
320  // Exit
321 
322  return result;
323 };
324 
325 template <typename T>
328 value_ct() const
329 {
330  index_type result;
331 
332  // Preconditions:
333 
334  // Body:
335 
336  result = _values.ct();
337 
338  // Postconditions:
339 
340  // Exit
341 
342  return result;
343 };
344 
345 template <typename T>
346 T*
348 row(const index_type xrow_index) const
349 {
350  T* result;
351 
352  // Preconditions:
353 
354  require(xrow_index < row_ct());
355 
356  // Body:
357 
358  result = _values.base() + _row_ptrs[xrow_index];
359 
360  // Postconditions:
361 
362  ensure(result != 0);
363 
364  // Exit
365 
366  return result;
367 };
368 
369 template <typename T>
370 T*
372 operator[](const index_type xrow_index) const
373 {
374  T* result;
375 
376  // Preconditions:
377 
378  require(xrow_index < row_ct());
379 
380  // Body:
381 
382  result = _values.base() + _row_ptrs[xrow_index];
383 
384  // Postconditions:
385 
386  ensure(result != 0);
387 
388  // Exit
389 
390  return result;
391 };
392 
393 template <typename T>
394 void
397 {
398  // Preconditions:
399 
400  // Body:
401 
402  // Initialize the row pointers.
403 
404  index_type loffset = 0;
405  for(index_type i = 0; i < row_ct(); i++)
406  {
407  _row_ptrs[i] = loffset;
408  loffset += _col_cts[i];
409  }
410 
411  _values.reserve(loffset);
412  _values.set_ct(loffset);
413 
414  // Postconditions:
415 
416  ensure(value_ct() == sum_col_cts());
417 
418  // Exit
419 
420  return;
421 };
422 
423 template <typename T>
424 void
426 reset_rows(const index_type* xcol_cts, const index_type xcol_cts_ub)
427 {
428  // Preconditions:
429 
430  require(xcol_cts != 0);
431 
432  // Body:
433 
434  initialize(xcol_cts, xcol_cts_ub);
435 
436  // Postconditions:
437 
438  ensure(invariant());
439  ensure(row_ct() == xcol_cts_ub);
440  ensure_for_all(i, 0, row_ct(), col_ct(i) == xcol_cts[i]);
441  ensure(value_ct() == sum_col_cts());
442 
443  // Exit
444 
445  return;
446 };
447 
448 template <typename T>
451 sum_col_cts() const
452 {
453  index_type result = 0;
454 
455  // Preconditions:
456 
457  // Body:
458 
459  result = sum_col_cts(_col_cts.base(), _col_cts.ct());
460 
461  // Postconditions:
462 
463  // Exit
464 
465  return result;
466 };
467 
468 template <typename T>
471 sum_col_cts(const index_type* xcol_cts, const index_type xcol_cts_ub) const
472 {
473  index_type result = 0;
474 
475  // Preconditions:
476 
477  require(xcol_cts != 0);
478 
479  // Body:
480 
481  for(index_type i=0; i<xcol_cts_ub; i++)
482  {
483  result += xcol_cts[i];
484  }
485 
486  // Postconditions:
487 
488  // Exit
489 
490  return result;
491 };
492 
493 template <typename T>
494 void
497 {
498  // Preconditions:
499 
500  // Body:
501 
502  // Reserve space for xrow_ct rows.
503 
504  _col_cts.reserve(xrow_ct);
505  _row_ptrs.reserve(xrow_ct);
506 
507  // Create one row with col count 0;
508  // becomes back_row().
509 
510  _col_cts.set_ct(0);
511  _col_cts.push_back(0);
512 
513  _row_ptrs.set_ct(0);
514  _row_ptrs.push_back(0);
515 
516  // Reserve space for xct values.
517 
518  _values.reserve(xvalue_ct);
519  _values.set_ct(0);
520 
521  // Postconditions:
522 
523  ensure(back_row() == 0);
524  ensure(col_ct(back_row()) == 0);
525  ensure(value_ct() == 0);
526 
527  // Exit:
528 
529  return;
530 }
531 
532 template <typename T>
535 back_row() const
536 {
537  // Preconditions:
538 
539  // Body:
540 
541  index_type result = row_ct() - 1;
542 
543  // Postconditions:
544 
545  ensure(result == (row_ct() - 1));
546 
547  // Exit:
548 
549  return result;
550 }
551 
552 template <typename T>
553 void
556 {
557  // Preconditions:
558 
559  // Body:
560 
561  define_old_variable(size_t old_value_ct = value_ct());
562  define_old_variable(size_t old_col_ct = col_ct(back_row()));
563  define_old_variable(index_type old_back_row = back_row());
564 
565  _row_ptrs.push_back(_row_ptrs.back() + _col_cts.back());
566  _col_cts.push_back(0);
567 
568  // Postconditions:
569 
570  ensure(back_row() == old_back_row + 1);
571  ensure(col_ct(back_row()) == 0);
572  ensure(value_ct() == old_value_ct);
573 
574  // Exit:
575 
576  return;
577 }
578 
579 template <typename T>
580 void
582 push_back(const T& xvalue)
583 {
584  // Preconditions:
585 
586  // Body:
587 
588  define_old_variable(size_t old_value_ct = value_ct());
589  define_old_variable(size_t old_col_ct = col_ct(back_row()));
590  define_old_variable(index_type old_back_row = back_row());
591 
592  _values.push_back(xvalue);
593  _col_cts.back()++;
594 
595  // Postconditions:
596 
597  ensure(back_row() == old_back_row);
598  ensure(col_ct(back_row()) == old_col_ct + 1);
599  ensure(value_ct() == old_value_ct + 1);
600 
601  // Exit:
602 
603  return;
604 }
605 
606 // PROTECTED MEMBER FUNCTIONS
607 
608 template <typename T>
609 void
611 initialize(const index_type* xcol_cts,
612  index_type xcol_cts_ub)
613 {
614  // Preconditions:
615 
616  require(xcol_cts != 0);
617 
618  // Body:
619 
620  // Allocate column counts and row pointers.
621 
622  _col_cts.reserve(xcol_cts_ub);
623  _col_cts.set_ct(0);
624 
625  _row_ptrs.reserve(xcol_cts_ub);
626  _row_ptrs.set_ct(0);
627 
628  // Initialize column counts and row pointers
629  // while adding up the number of values.
630 
631  size_t lvalue_ct = 0;
632  for(index_type i = 0; i < xcol_cts_ub; i++)
633  {
634  _col_cts.push_back(xcol_cts[i]);
635  _row_ptrs.push_back(lvalue_ct);
636  lvalue_ct += xcol_cts[i];
637  }
638 
639  // Allocate values.
640 
641  _values.reserve(lvalue_ct);
642  _values.set_ct(lvalue_ct);
643 
644  // Postconditions:
645 
646  ensure(invariant());
647  ensure(row_ct() == xcol_cts_ub);
648  ensure_for_all(i, 0, row_ct(), col_ct(i) == xcol_cts[i]);
649 
650  // Exit
651 
652  return;
653 };
654 
655 // PRIVATE MEMBER FUNCTIONS
656 
657 
658 // =============================================================================
659 // ANY FACET
660 // =============================================================================
661 
662 // PUBLIC MEMBER FUNCTIONS
663 
664 template <typename T>
667 clone() const
668 {
669  ragged_array* result;
670 
671  // Preconditions:
672 
673  // Body:
674 
675  result = new ragged_array(*this);
676 
677  // Postconditions:
678 
679  ensure(result->row_ct() == row_ct());
680  ensure_for_all(i, 0, row_ct(), result->col_ct(i) == col_ct(i));
681  ensure_for_all(i, 0, value_ct(), result->values()[i] == values()[i]);
682 
683  // Exit
684 
685  return result;
686 };
687 
688 
689 template <typename T>
690 bool
692 invariant() const
693 {
694  // Preconditions:
695 
696  // Body:
697 
699  //invariance(values() != 0);
700  invariance(col_cts() != 0);
701  invariance(sum_col_cts() == value_ct());
702 
703  // Postconditions:
704 
705  // Exit
706 
707  return true;
708 };
709 
710 template <typename T>
711 bool
713 is_ancestor_of(const any* xother) const
714 {
715  bool result;
716 
717  // Preconditions:
718 
719  require(xother != 0);
720 
721  // Body:
722 
723  result = dynamic_cast<const ragged_array<T>*>(xother) != 0;
724 
725  // Postconditions:
726 
727  // Exit
728 
729  return result;
730 };
731 
732 // PROTECTED MEMBER FUNCTIONS
733 
734 // PRIVATE MEMBER FUNCTIONS
735 
736 
737 // ===========================================================
738 // NON-MEMBER FUNCTIONS
739 // ===========================================================
740 
741 template <typename T>
742 std::ostream&
743 operator << (std::ostream& xos, const ragged_array<T>& xra)
744 {
745  for(size_type i=0; i<xra.row_ct(); ++i)
746  {
747  for(size_type j=0; j< xra.col_ct(i); ++j)
748  {
749  xos << " " << xra[i][j];
750  }
751  xos << std::endl;
752  }
753 
754  return xos;
755 }
756 
757 template <typename T>
758 size_t
759 deep_size(const ragged_array<T>& xra, bool xinclude_shallow)
760 {
761  size_t result;
762 
763  // Preconditions:
764 
765  // Body:
766 
767  result = xinclude_shallow ? sizeof(xra) : 0;
768 
769  // Add memory associated in member _values.
770 
771  result += deep_size(xra._values, false);
772 
773  // Add memory associated in member _col_cts.
774 
775  result += deep_size(xra._col_cts, false);
776 
777  // Add memory associated in member _row_ptrs.
778 
779  result += deep_size(xra._row_ptrs, false);
780 
781  // Postconditions:
782 
783  ensure(result >= 0);
784 
785  // Exit:
786 
787  return result;
788 }
789 
790 } // namespace sheaf
791 
792 #endif // ifndef RAGGED_ARRAY_IMPL_H
793 
794 
795 
796 
797 
798 
size_type ct() const
The number of items currently in use.
void initialize(const index_type *xcol_cts, index_type xcol_cts_ub)
Creates an instance with xcol_cts_ub rows, with the number of columns in the i-th row given by xcol_c...
virtual bool operator==(const ragged_array &xother) const
True if this is equivalent to xother.
index_type value_ct() const
The number of values.
T * row(const index_type xrow_index) const
The row with index xrow_index.
index_type sum_col_cts() const
The sum of the column counts in col_cts().
index_type * col_cts() const
The naked, underlying storage for number of columns for each row.
ragged_array(size_t xct=0)
Default constructor; creates an empty array with one row and space reserved for xct values...
T * operator[](const index_type xrow_index) const
The row index operator; alias for row(index_type).
virtual bool is_ancestor_of(const any *xother) const
Conformance test; true if other conforms to this.
Abstract base class with useful features for all objects.
Definition: any.h:39
void push_back(const T &xvalue)
Add a value to the back of the back row.
pointer_type base() const
The underlying storage array.
block< index_type > _col_cts
The number of columns in each row.
Definition: ragged_array.h:211
SHEAF_DLL_SPEC size_t deep_size(const dof_descriptor_array &xp, bool xinclude_shallow=true)
The deep size of the referenced object of type dof_descriptor_array.
virtual bool invariant() const
Class invariant.
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
index_type row_ct() const
The number of rows.
index_type back_row() const
The last row; the active row for push_back.
virtual ~ragged_array()
Destructor.
block< T > _values
The values stored in the array.
Definition: ragged_array.h:206
ragged_array & operator=(const ragged_array &xother)
Assignment operator.
block< index_type > _row_ptrs
Index of the first value in each row.
Definition: ragged_array.h:216
Namespace for the sheaves component of the sheaf system.
void new_back_row()
Creates a new last row.
void initialize_push_back(index_type xrow_ct, index_type xvalue_ct)
Reserves storage for xrow_ct rows containing xvalue_ct total values and initializes push_back into ro...
A two index array with variable length rows.
unsigned long index_type
The integer type used to index this.
Definition: ragged_array.h:70
virtual ragged_array * clone() const
Virtual constructor; makes a new instance of the same type as this.
index_type col_ct(const index_type xrow_index) const
The number of columns for the xrow_index-th row.
void reset_rows()
Reinitializes access by row index using the column counts in col_cts().
T * values() const
The naked, underlying storage for the values in the array.