SheafSystem  0.0.0.0
auto_block.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 AUTO_BLOCK.
19 
20 #ifndef AUTO_BLOCK_IMPL_H
21 #define AUTO_BLOCK_IMPL_H
22 
23 #ifndef SHEAF_DLL_SPEC_H
24 #include "SheafSystem/sheaf_dll_spec.h"
25 #endif
26 
27 #ifndef AUTO_BLOCK_H
28 #include "SheafSystem/auto_block.h"
29 #endif
30 
31 #ifndef ASSERT_CONTRACT_H
32 #include "SheafSystem/assert_contract.h"
33 #endif
34 
35 #ifndef DEEP_SIZE_H
36 #include "SheafSystem/deep_size.h"
37 #endif
38 
39 #ifndef INDEX_TRAITS_H
40 #include "SheafSystem/index_traits.h"
41 #endif
42 
43 namespace sheaf
44 {
45 
46 // ===========================================================
47 // UN_BLOCK_INITIALIZATION_POLICY
48 // ===========================================================
49 
51 template <typename T>
52 void
54 initialize(T* xbegin, T* xend)
55 {
56  // Do nothing.
57 }
58 
60 template <typename T>
61 void
63 initialize(T& xvalue)
64 {
65  // Do nothing.
66 }
67 
68 // ===========================================================
69 // INVALID_BLOCK_INITIALIZATION_POLICY
70 // ===========================================================
71 
73 template <typename T>
74 void
76 initialize(T* xbegin, T* xend)
77 {
78  for(T* i=xbegin; i<xend; ++i)
79  {
81  }
82 }
83 
85 template <typename T>
86 void
88 initialize(T& xvalue)
89 {
90  xvalue = index_traits<T>::invalid();
91 }
92 
93 // ===========================================================
94 // ZERO_BLOCK_INITIALIZATION_POLICY
95 // ===========================================================
96 
98 template <typename T>
99 void
101 initialize(T* xbegin, T* xend)
102 {
103  for(T* i=xbegin; i<xend; ++i)
104  {
105  *i = 0;
106  }
107 }
108 
110 template <typename T>
111 void
113 initialize(T& xvalue)
114 {
115  xvalue = 0;
116 }
117 
118 
119 
121 template <typename T, typename S>
122 T *
124 base() const
125 {
126  // Preconditions:
127 
128  // Body:
129 
130  pointer_type result = _base;
131 
132  // Postconditions:
133 
134  ensure(invariant());
135  ensure((result != 0) == (ub() > 0));
136 
137  // Return:
138 
139  return result;
140 }
141 
143 template <typename T, typename S>
146 ct() const
147 {
148  // Preconditions:
149 
150  // Body:
151 
152  size_type result = _ct;
153 
154  // Postconditions:
155 
156  ensure(invariant());
157  ensure(result >= 0);
158 
159  // Return:
160 
161  return result;
162 }
163 
165 template <typename T, typename S>
166 bool
168 invariant() const
169 {
170  // Preconditions:
171 
172  // Body:
173 
174  // Postconditions:
175 
176  bool result = true;
177 
178  result = result && ( _ub >= 0 );
179  result = result && ( _ct >= 0 );
180  result = result && ( _ct <= _ub );
181  result = result && ((_ub > 0) == (_base != 0));
182 
183  // Return:
184 
185  return result;
186 }
187 
189 template <typename T, typename S>
190 T &
192 item(index_type xindex) const
193 {
194 
195  // Preconditions:
196 
197  require(xindex >= 0 && xindex < ub());
198 
199  // Body:
200 
201  T & result = *(_base+xindex);
202 
203  // Postconditions:
204 
205  ensure(invariant());
206 
207  // Return:
208 
209  return result;
210 }
211 
213 template <typename T, typename S>
214 T &
216 operator [](index_type xindex) const
217 {
218 
219  // Preconditions:
220 
221  require(xindex >= 0 && xindex < ub());
222 
223  // Body:
224 
225  T & result = *(_base+xindex);
226 
227  // Postconditions:
228 
229  ensure(invariant());
230 
231  // Return:
232 
233  return result;
234 }
235 
237 template <typename T, typename S>
240 ub() const
241 {
242  // Preconditions:
243 
244  // Body:
245 
246  // Postconditions:
247 
248  ensure(invariant());
249 
250  // Return:
251 
252  return _ub;
253 }
254 
255 
257 template <typename T, typename S>
260 {
261 
262  // Preconditions:
263 
264  require(xub >= 0);
265 
266  // Body:
267 
268  _base = 0;
269  _ct = 0;
270  _ub = 0;
271  reserve(xub);
272 
273  // Postconditions:
274 
275  ensure(invariant());
276  ensure(ub() >= xub);
277  ensure((xub > 0) == (base() != 0));
278  ensure(ct() == 0);
279 }
280 
282 template <typename T, typename S>
284 auto_block(index_type xub, size_type xct, const T *xitems)
285 {
286 
287  // Preconditions:
288 
289  require(xub >= 0);
290  require((0 <= xct) && (xct <= xub));
291  require((xct > 0) == (xitems != 0));
292  require(unexecutable("xitems != 0 implies xitems points to array of length >= xct"));
293 
294  // Body:
295 
296  _base = 0;
297  _ct = 0;
298  _ub = 0;
299  reserve(xub);
300 
301  for(index_type i = 0; i < xct; ++i)
302  {
303  _base[i] = xitems[i];
304  }
305  _ct = xct;
306 
307  // Postconditions:
308 
309  ensure(invariant());
310  ensure(ub() >= xub);
311  ensure((xub > 0) == (base() != 0));
312  ensure(ct() == xct);
313  // Unexecutable because would require T::operator==
314  ensure_for_all(i, 0, ct(), unexecutable(item(i) == xitems[i]));
315 }
316 
318 template <typename T, typename S>
320 auto_block(const auto_block& xother)
321 {
322 
323  // Preconditions:
324 
325  // Body:
326 
327  _base = 0;
328  _ct = 0;
329  _ub = 0;
330 
331  *this = xother;
332 
333  // Postconditions:
334 
335  ensure(invariant());
336  // ensure((*this) == xother);
337 }
338 
340 template <typename T, typename S>
343 operator=(const auto_block& xother)
344 {
345 
346  // Preconditions:
347 
348  // Body:
349 
350  reserve(xother.ub());
351  _ct = xother._ct;
352 
353  for(index_type i=0; i<_ct; ++i)
354  {
355  _base[i] = xother._base[i];
356  }
357 
358  // Postconditions:
359 
360  ensure(invariant());
361  ensure(unexecutable(*this == xother));
362 
363  // Return:
364 
365  return *this;
366 }
367 
369 template <typename T, typename S>
372 {
373  // Preconditions:
374 
375  // Body:
376 
377  delete [] _base;
378 
379  // Postconditions:
380 }
381 
382 template <typename T, typename S>
383 void
386 {
387 
388  // Preconditions:
389 
390  require(0 <= xindex);
391 
392  // Body:
393 
394  if (xindex >= _ub)
395  {
396  index_type new_ub = _ub*2 > xindex ? _ub*2 : xindex + 1;
397 
399 
400  reserve(new_ub);
401  }
402 
403  set_item(xindex, xitem);
404 
405  // Postconditions:
406 
407  ensure(invariant());
408 
410 
411  ensure(unexecutable(item(xindex) == xitem));
412 }
413 
415 template <typename T, typename S>
416 void
419 {
420 
421  // Preconditions:
422 
423  require(xub >= 0);
424 
425  // Body:
426 
427  define_old_variable(size_type old_ct = _ct);
428 
429  index_type old_ub = _ub;
430 
431  if(xub > _ub)
432  {
433  // Allocate a new base array
434 
435  pointer_type newbase = new T[xub];
436 
437  // Copy the old contents to the new base
438  // and delete the old base.
439 
440  if(_base != 0)
441  {
442  for (index_type i = 0; i < _ub; ++i)
443  {
444  newbase[i] = _base[i];
445  }
446 
447  delete [] _base;
448  }
449 
450  // Update base and bound.
451 
452  _base = newbase;
453  _ub = xub;
454 
455  // Enforce the initialization policy.
456 
457  initialization_policy::initialize(_base+old_ub, _base+_ub);
458  }
459 
460  // Postconditions:
461 
462  ensure(invariant());
463  ensure(ct() == old_ct);
464  ensure(ub() >= old_ub);
465  ensure(ub() >= xub);
466  ensure((ub() > 0) == (base() != 0));
467 }
468 
470 template <typename T, typename S>
471 void
474 {
475 
476  // Preconditions:
477 
478  require(0 <= xct && xct <= ub());
479 
480  // Body:
481 
482  _ct = xct;
483 
484  // Postconditions:
485 
486  ensure(ct() == xct);
487 }
488 
490 template <typename T, typename S>
491 void
494 {
495 
496  // Preconditions:
497 
498  require(0 <= xindex && xindex < ub());
499 
500  // Body:
501 
502  *(_base+xindex) = xitem;
503 
504  // Postconditions:
505 
506  ensure(invariant());
507 
509 
510  ensure(unexecutable(item(xindex)==xitem));
511 }
512 
514 template <typename T, typename S>
515 void
518 {
519  // Preconditions:
520 
521  // Body:
522 
523  define_old_variable(size_type old_ct = ct());
524 
525  for(index_type i=0; i<_ct; i++)
526  {
527  _base[i] = xitem;
528  }
529 
530  // Postconditions:
531 
532  ensure(invariant());
533  ensure(ct() == old_ct);
534 
536 
537  ensure(unexecutable(ensure_for_all(i, 0, ct(), item(i) == xitem)));
538 
539 }
540 
542 template <typename T, typename S>
543 void
546 {
547  // Preconditions:
548 
549  require(xbegin >= 0);
550  require(xend >= xbegin);
551 
552  // Body:
553 
554  reserve(xend);
555  if(_ct < xend)
556  {
557  set_ct(xend);
558  }
559 
560  for(index_type i=xbegin; i<xend; i++)
561  {
562  _base[i] = xitem;
563  }
564 
565  // Postconditions:
566 
567  ensure(invariant());
568  ensure(ct() >= xend);
569 
571 
572  ensure(unexecutable(ensure_for_all(i, xbegin, xend, item(i) == xitem)));
573 
574 }
575 
577 template <typename T, typename S>
580 back() const
581 {
582  // Preconditions:
583 
584  require(ct() > 0);
585 
586  // Body:
587 
588  reference_type result = item(ct() - 1);
589 
590  // Postconditions:
591 
593 
594  ensure(unexecutable(result == item(ct() - 1)));
595 
596  // Exit
597 
598  return result;
599 }
600 
602 template <typename T, typename S>
603 void
606 {
607  // Preconditions:
608 
609  // Body:
610 
611  force_item(_ct, item);
612  set_ct(_ct+1);
613 
614  // Postconditions:
615 
616  ensure(invariant());
617  ensure(unexecutable(ct() == old ct()+1));
618 
620 
621  ensure(unexecutable(back() == item));
622 
623  // Exit
624 
625  return;
626 }
627 
628 template <typename T, typename S>
629 void
631 push_back(const auto_block& xother)
632 {
633  // Preconditions:
634 
635  // Body:
636 
637  define_old_variable(size_type old_ct = this->ct());
638 
639 
640  for(index_type i=0; i<xother.ct(); ++i)
641  {
642  push_back(xother[i]);
643  }
644 
645  // Postconditions:
646 
647  ensure(this->ct() == old_ct + xother.ct());
648  // ensure_for_all(i, 0, xother.ct(), ((*this)[i + old_ct] == xother[i]) );
649 
650  // Exit:
651 
652  return;
653 }
654 
656 template <typename T, typename S>
657 void
660 {
661  // Preconditions:
662 
663  require(ct() > 0);
664 
665  // Body:
666 
667  define_old_variable( size_type old_ct = ct() );
668 
669  set_ct(_ct-1);
670  initialization_policy::initialize(_base[_ct]);
671 
672  // Postconditions:
673 
674  ensure(invariant());
675  ensure(ct() == old_ct-1);
676 
677  // Exit
678 
679  return;
680 }
681 
683 template <typename T, typename S>
684 void
687 {
688  // Preconditions:
689 
690  // Body:
691 
692  set_ct(0);
693  initialization_policy::initialize(_base, _base+_ub);
694 
695  // Postconditions:
696 
697  ensure(invariant());
698  ensure(ct() == 0);
699 
700  // Exit
701 
702  return;
703 }
704 
706 template <typename T, typename S>
707 void
710 {
711  // Preconditions:
712 
713  require(0 <= xindex && xindex < ub());
714 
715  // Body:
716 
717  initialization_policy::initialize(_base[xindex]);
718 
719  // Postconditions:
720 
721  ensure(invariant());
722 
723  // Exit
724 
725  return;
726 }
727 
729 template <typename T, typename S>
730 void
733 {
734  // Preconditions:
735 
736  require(0 <= xbegin);
737  require(xbegin <= xend);
738  require(xend <= ub());
739 
740  // Body:
741 
742  initialization_policy::initialize(_base+xbegin, _base+xend);
743 
744  // Postconditions:
745 
746  ensure(invariant());
747 
748  // Exit
749 
750  return;
751 }
752 
753 // ===========================================================
754 // NON-MEMBER FUNCTIONS
755 // ===========================================================
756 
757 template <typename T, typename S>
758 bool
759 operator==(const auto_block<T, S>& xblk1, const auto_block<T, S>& xblk2)
760 {
761  bool result;
762 
763  // Preconditions:
764 
765  // Body:
766 
767  result = (xblk1.ub() >= xblk2.ub());
768  result = result && (xblk1.ct() == xblk2.ct());
769 
770  for(sheaf::pod_index_type i=0; result && (i<xblk1.ct()); ++i)
771  {
772  result = (xblk1[i] == xblk2[i]);
773  }
774 
775  // Postconditions:
776 
777  // Return:
778 
779  return result;
780 }
781 
782 template <typename T, typename S>
783 std::ostream&
784 operator << (std::ostream& xos, const auto_block<T, S>& xblk)
785 {
786  //for(auto_block::index_type i=0; i<xblk.ct(); ++i)
787  for(long int i=0; i<xblk.ct(); ++i)
788  {
789  xos << " " << xblk[i];
790  }
791 
792  return xos;
793 }
794 
795 template <typename T, typename S>
796 size_t
797 deep_size(const auto_block<T, S>& xblk, bool xinclude_shallow)
798 {
799  size_t result;
800 
801  // Preconditions:
802 
803  // Body:
804 
805  result = xinclude_shallow ? sizeof(xblk) : 0;
806 
807  for(int i=0; i<xblk.ub(); ++i)
808  {
809  result += deep_size(xblk[i], true);
810  }
811 
812  // Postconditions:
813 
814  ensure(result >= 0);
815 
816  return result;
817 }
818 
819 template <typename T, typename S>
820 size_t
821 deep_size(const auto_block<T*, S>& xblk, bool xinclude_shallow)
822 {
823  size_t result;
824 
825  // Preconditions:
826 
827  // Body:
828 
829  result = xinclude_shallow ? sizeof(xblk) : 0;
830 
831  result += xblk.ub()*sizeof(T*);
832 
833  for(int i=0; i<xblk.ub(); ++i)
834  {
835  if(xblk[i] != 0)
836  {
837  result += deep_size(*xblk[i], true);
838  }
839  }
840 
841  // Postconditions:
842 
843  ensure(result >= 0);
844 
845  return result;
846 }
847 
848 } // namespace sheaf
849 
850 #endif // AUTO_BLOCK_IMPL_H
static T invalid()
The invalid index value.
Definition: index_traits.h:70
static void initialize(T *xbegin, T *xend)
Initializes the range [xbegin, xend) to invalid().
index_type ub() const
The upper bound on the storage array. The number of items current allocated in the storage array...
size_type ct() const
The number of items currently in use.
const pod_type & const_reference_type
A type that behaves as a const reference to the container&#39;s value type.
Definition: auto_block.h:145
auto_block(index_type xub=0)
Creates an instance with ub() == xub; storage is uninitialized.
bool invariant() const
The class invariant.
static void initialize(T *xbegin, T *xend)
Initializes the range [xbegin, xend) to invalid().
unsigned long int size_type
An unsigned integral type used to represent sizes and capacities.
Definition: auto_block.h:171
reference_type back() const
The last item in the auto_block.
void force_item(index_type xindex, const_reference_type xitem)
Puts the item xitem at index xindex, resizing if necessary; any other new storage allocated is uninit...
void reserve(index_type xub)
Makes ub() at least xub; if new storage is allocated, it is uninitialized.
A contiguously allocated array of items of type T with size information and automatic resizing...
Definition: auto_block.h:122
void initialize(index_type xindex)
Invokes the initialization policy on the item at xindex.
auto_block & operator=(const auto_block &xother)
Assignment operator.
pod_type * pointer_type
A type that behaves as a pointer to the container&#39;s value type.
Definition: auto_block.h:150
reference_type item(index_type xindex) const
The item at index xindex.
void push_back(const_reference_type item)
Insert item at the end of the items in the auto_block.
void assign(const_reference_type xitem)
Sets the values of all items to xitem.
void pop_back()
Remove item at the back.
pointer_type base() const
The underlying storage array.
void set_ct(size_type xct)
Sets ct() == xct.
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.
void set_item(index_type xindex, const_reference_type xitem)
Puts the item xitem at index xindex, but will not resize.
reference_type operator[](index_type xindex) const
The item at index xindex.
size_type _ct
The number of items currently stored.
Definition: auto_block.h:316
bool operator==(const singly_linked_list< T, Alloc > &lhs, const singly_linked_list< T, Alloc > &rhs)
Checks if the contents of lhs and rhs are equal, that is, whether lhs.size() == rhs.size() and each element in lhs compares equal with the element in rhs at the same position.
sheaf::pod_index_type index_type
The containers index type.
Definition: auto_block.h:160
virtual ~auto_block()
Destructor.
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
Namespace for the sheaves component of the sheaf system.
pointer_type _base
Start of storage for this.
Definition: auto_block.h:306
pod_type & reference_type
A type that behaves as a reference to the container&#39;s value type.
Definition: auto_block.h:140
void clear()
Remove all items.
static void initialize(T *xbegin, T *xend)
Initializes the range [xbegin, xend).