SheafSystem  0.0.0.0
implicit_entry_map.impl.h
Go to the documentation of this file.
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 
20 
21 #ifndef IMPLICIT_ENTRY_MAP_IMPL_H
22 #define IMPLICIT_ENTRY_MAP_IMPL_H
23 
24 #ifndef IMPLICIT_ENTRY_MAP_H
25 #include "SheafSystem/implicit_entry_map.h"
26 #endif
27 
28 #ifndef ASSERT_CONTRACT_H
29 #include "SheafSystem/assert_contract.h"
30 #endif
31 
32 #ifndef DEEP_SIZE_H
33 #include "SheafSystem/deep_size.h"
34 #endif
35 
36 #ifndef IMPLICIT_ENTRY_MAP_ITERATOR_H
37 #include "SheafSystem/implicit_entry_map_iterator.h"
38 #endif
39 
40 #ifndef RC_PTR_H
41 #include "SheafSystem/rc_ptr.h"
42 #endif
43 
44 namespace sheaf
45 {
46 
47 // =============================================================================
48 // IMPLICIT_ENTRY_MAP FACET
49 // =============================================================================
50 
51 // PUBLIC MEMBER FUNCTIONS
52 
53 template <typename E, typename I>
56  : _ct(0),
57  _begin(invalid_pod_index()),
58  _end(invalid_pod_index())
59 {
60  // Preconditions:
61 
62  // Body:
63 
64  // Nothing to do.
65 
66  // Postconditions:
67 
68  // Exit:
69 
70  return;
71 };
72 
73 template <typename E, typename I>
76 {
77  // Preconditions:
78 
79  // Body:
80 
81  // Delete the explicit value reference counted pointers.
82 
83  typename explicit_value_map_type::iterator lexplicit_value_itr =
84  _explicit_value_map.begin();
85  while(lexplicit_value_itr != _explicit_value_map.end())
86  {
87  // Delete reference counted pointer.
88 
89  if(lexplicit_value_itr->second != 0)
90  {
91  delete lexplicit_value_itr->second;
92  }
93 
94  // Move to the next entry.
95 
96  lexplicit_value_itr++;
97  }
98 
99  // Delete the implicit interval reference counted pointers.
100 
101  typename interval_map_type::iterator linterval_itr = _interval_map.begin();
102  while(linterval_itr != _interval_map.end())
103  {
104  // Delete reference counted pointer.
105 
106  if(linterval_itr->second != 0)
107  {
108  delete linterval_itr->second;
109  }
110 
111  // Move to the next entry.
112 
113  linterval_itr++;
114  }
115 
116  // Postconditions:
117 
118  // Exit:
119 
120  return;
121 };
122 
123 template <typename E, typename I>
124 bool
127 {
128  // Preconditions:
129 
130  // Body:
131 
132  typename explicit_value_map_type::const_iterator litr =
133  _explicit_value_map.find(xid);
134 
135  bool result = (litr != _explicit_value_map.end());
136 
137  // Postconditions:
138 
139  // Exit:
140 
141  return result;
142 };
143 
144 template <typename E, typename I>
145 bool
148 {
149  // Preconditions:
150 
151  // Body:
152 
153  typename interval_map_type::const_iterator litr =
154  _interval_map.upper_bound(xid);
155 
156  bool result = (litr != _interval_map.end()) && (litr->second != 0);
157 
158  // Postconditions:
159 
160  // Exit:
161 
162  return result;
163 };
164 
165 template <typename E, typename I>
166 bool
169 {
170  // Preconditions:
171 
172  // Body:
173 
174  bool result = (contains_explicit_entry(xid) ||
176 
177  // Postconditions:
178 
179  // Exit:
180 
181  return result;
182 };
183 
184 template <typename E, typename I>
185 E&
187 value(pod_type xid) const
188 {
189  // Preconditions:
190 
191  require(contains_entry(xid));
192 
193  // Body:
194 
195  E* result;
196 
197  const explicit_value_type& lexplicit_value = explicit_value(xid);
198 
199  if(!lexplicit_value)
200  {
201  // No explicit value found, get the value from the implicit interval.
202 
203  result = &implicit_interval(xid)->value(xid);
204  }
205  else
206  {
207  // Explicit value found, get the value from the reference
208  // counted pointer.
209 
210  result = &*lexplicit_value;
211  }
212 
213  // Postconditions:
214 
215  // Exit:
216 
217  return *result;
218 };
219 
220 template <typename E, typename I>
221 E&
224 {
225  // Preconditions:
226 
227  require(contains_entry(xid));
228 
229  // Body:
230 
231  E& result = value(xid);
232 
233  // Postconditions:
234 
235  // Exit:
236 
237  return result;
238 };
239 
240 template <typename E, typename I>
241 void
244 {
245  // Preconditions:
246 
247  require(!contains_explicit_entry(xid));
248 
249  // Body:
250 
251  define_old_variable(size_type old_ct = ct());
252 
253  _explicit_value_map[xid] = new explicit_value_type(&xvalue);
254 
255  // Update count.
256 
257  _ct++;
258 
259  // Update extrema.
260 
261  update_extrema_for_insert(xid, xid+1);
262 
263  // Postconditions:
264 
265  ensure(contains_explicit_entry(xid));
266  ensure(ct() == old_ct+1);
267  ensure(begin() <= xid);
268  ensure(end() >= xid+1);
269 
270  // Exit:
271 
272  return;
273 };
274 
275 template <typename E, typename I>
276 void
279 {
280  // Preconditions:
281 
283  require(unexecutable("interval is empty"));
284 
285  // Body:
286 
287  define_old_variable(size_type old_ct = ct());
288 
289  pod_type lbegin = xinterval.begin();
290  pod_type lend = xinterval.end();
291 
292  _interval_map[lend] = new interval_type(&xinterval);
293 
294  if(_interval_map.find(lbegin) == _interval_map.end())
295  {
296  // The beginning of the interval is not the end of some other
297  // interval.
298 
299  _interval_map[lbegin] = 0;
300  }
301 
302  // Update count.
303 
304  _ct += xinterval.ct();
305 
306  // Update extrema.
307 
308  update_extrema_for_insert(lbegin, lend);
309 
310  // Postconditions:
311 
313  ensure(unexecutable("interval is full"));
314  ensure(ct() == old_ct + xinterval.ct());
315  ensure(begin() <= xinterval.begin());
316  ensure(end() >= xinterval.end());
317 
318  // Exit:
319 
320  return;
321 };
322 
323 template <typename E, typename I>
324 void
327 {
328  // Preconditions:
329 
330  require(contains_explicit_entry(xid));
331 
332  // Body:
333 
334  define_old_variable(size_type old_ct = ct());
335  define_old_variable(pod_type old_begin = begin());
336  define_old_variable(pod_type old_end = end());
337 
338  explicit_value_type* lrc_ptr = _explicit_value_map.find(xid)->second;
339 
340  // Erase from data structure.
341 
342  _explicit_value_map.erase(xid);
343 
344  // Delete the reference counted pointer.
345 
346  delete lrc_ptr;
347 
348  // Update the count.
349 
350  _ct--;
351 
352  // Update the extrema.
353 
354  update_extrema_for_remove(xid, xid+1);
355 
356  // Postconditions:
357 
358  ensure(!contains_explicit_entry(xid));
359  ensure(ct() == old_ct - 1);
360  ensure((ct() == 0) ? !is_valid(begin()) : true);
361  ensure((ct() == 0) ? !is_valid(end()) : true);
362  ensure(((ct() > 0) && (xid == old_begin)) ? begin() > xid : true);
363  ensure(((ct() > 0) && ((xid + 1) == old_end)) ? end() <= xid : true);
364 
365  // Exit:
366 
367  return;
368 };
369 
370 template <typename E, typename I>
371 void
374 {
375  // Preconditions:
376 
377  require(contains_implicit_entry(xid));
378 
379  // Body:
380 
381  typename interval_map_type::iterator litr = _interval_map.upper_bound(xid);
382  pod_type lend = litr->first;
383 
384  typename interval_map_type::iterator lprevious = litr;
385  lprevious--;
386  pod_type lbegin = lprevious->first;
387 
388  typename interval_map_type::iterator lnext = litr;
389  lnext++;
390 
391  if(lprevious->second == 0)
392  {
393  if((lnext == _interval_map.end()) || (lnext->second == 0))
394  {
395  // Remove previous so that no void value is at the end or
396  // back-to-back void values.
397 
398  _interval_map.erase(litr);
399  if(litr->second != 0)
400  delete litr->second;
401 
402  _interval_map.erase(lprevious);
403  }
404  else
405  {
406  // Adjust the void value to be the beginning of the next.
407 
408  _interval_map[lend] = 0;
409  _interval_map.erase(lprevious);
410  }
411  }
412  else
413  {
414  if((lnext == _interval_map.end()) || (lnext->second == 0))
415  {
416  // The void value is in the correct spot, erase current entry.
417 
418  _interval_map.erase(litr);
419  if(litr->second != 0)
420  delete litr->second;
421  }
422  else
423  {
424  // A void value needs inserted at the current entry.
425 
426  _interval_map[lend] = 0;
427  }
428  }
429 
430  // Update the count.
431 
432  _ct -= (lend-lbegin);
433 
434  // Update the extrema.
435 
436  update_extrema_for_remove(lbegin, lend);
437 
438  // Postconditions:
439 
440  ensure(!contains_implicit_entry(xid));
441 
445 
446  // Exit:
447 
448  return;
449 };
450 
451 template <typename E, typename I>
452 void
454 remove_entry(pod_type xid, bool xremove_interval)
455 {
456  // Preconditions:
457 
458  // Body:
459 
463 
464  if(contains_explicit_entry(xid))
465  {
466  // Remove the explicit entry.
467 
469  }
470 
471  if(contains_implicit_entry(xid))
472  {
473  // Remove the implicit entry.
474 
475  if(xremove_interval)
476  {
477  // Remove the entire implicit interval.
478 
480  }
481  else
482  {
483  // Remove the implicit entry.
484 
485  typename interval_map_type::iterator litr = _interval_map.upper_bound(xid);
486  pod_type lend = litr->first;
487 
488  typename interval_map_type::iterator lprevious = litr;
489  lprevious--;
490  pod_type lbegin = lprevious->first;
491 
492  interval_type* linterval = litr->second;
493 
494  if(lbegin == lend-1)
495  {
496  // Removing the only entry in the interval; remove the entire interval.
497 
501 
503  }
504  else if(xid == lbegin)
505  {
506  // Removing the first entry.
507 
508  if(lprevious->second == 0)
509  {
510  // The previous interval is void, remove it.
511 
512  _interval_map.erase(lprevious);
513  }
514 
515  // Add a void interval.
516 
517  _interval_map[xid+1] = 0;
518 
519  // Update the count.
520 
521  _ct--;
522 
523  // Update the extrema; the beginning extrema may have increased by one.
524 
525  if(xid == _begin)
526  _begin++;
527  }
528  else if(xid == lend-1)
529  {
530  // Removing the last entry.
531 
532  typename interval_map_type::iterator lnext = litr;
533  lnext++;
534 
535  // Adjust the current interval.
536 
537  _interval_map.erase(litr);
538  _interval_map[xid] = linterval;
539 
540  if((lnext != _interval_map.end()) && (lnext->second != 0))
541  {
542  // The next interval is not void, add void interval.
543 
544  _interval_map[lend] = 0;
545  }
546 
547  // Update the count.
548 
549  _ct--;
550 
551  // Update the extrema; the ending extrema may have decreased by one.
552 
553  if(xid == _end-1)
554  _end--;
555  }
556  else
557  {
558  // Removing an entry in the middle of the interval.
559 
560  _interval_map[xid] = new interval_type(*linterval);
561  _interval_map[xid+1] = 0;
562 
563  // Update the count.
564 
565  _ct--;
566 
567  // No need to update the extrema.
568  }
569  }
570  }
571 
572  // Postconditions:
573 
574  ensure(!contains_entry(xid));
575 
576  // Exit:
577 
578  return;
579 };
580 
581 template <typename E, typename I>
584 iterator() const
585 {
586  // Preconditions:
587 
588  // Body:
589 
590  iterator_type* result = new iterator_type(*this);
591 
592  // Postconditions:
593 
594  ensure(result != 0);
595 
596  // Exit:
597 
598  return result;
599 };
600 
601 template <typename E, typename I>
604 begin() const
605 {
606  return _begin;
607 };
608 
609 template <typename E, typename I>
612 end() const
613 {
614  return _end;
615 };
616 
617 template <typename E, typename I>
618 size_type
620 ct() const
621 {
622  return _ct;
623 };
624 
625 // PROTECTED MEMBER FUNCTIONS
626 
627 template <typename E, typename I>
631 {
632  static const explicit_value_type result;
633  return result;
634 }
635 
636 template <typename E, typename I>
640 {
641  static const interval_type result;
642  return result;
643 }
644 
645 template <typename E, typename I>
649 {
650  // Preconditions:
651 
652  // Body:
653 
654  typename explicit_value_map_type::const_iterator litr =
655  _explicit_value_map.find(xid);
656 
657  const explicit_value_type& result =
658  ((litr != _explicit_value_map.end()) ? *litr->second : null_explicit_value());
659 
660  // Postconditions:
661 
662  // Exit:
663 
664  return result;
665 };
666 
667 template <typename E, typename I>
671 {
672  // Preconditions:
673 
674  // Body:
675 
676  typename interval_map_type::const_iterator litr =
677  _interval_map.upper_bound(xid);
678 
679  const interval_type& result =
680  (((litr != _interval_map.end()) && (litr->second != 0)) ?
681  *litr->second : null_interval());
682 
683  // Postconditions:
684 
685  // Exit:
686 
687  return result;
688 };
689 
690 // PRIVATE MEMBER FUNCTIONS
691 
692 template <typename E, typename I>
693 void
696 {
697  // Preconditions:
698 
699  // Body:
700 
701  // Update the begin.
702 
703  if(!is_valid(_begin) || (xbegin < _begin))
704  {
705  _begin = xbegin;
706  }
707 
708  // Update the end.
709 
710  if(!is_valid(_end) || (xend > _end))
711  {
712  _end = xend;
713  }
714 
715  // Postconditions:
716 
717  ensure(begin() <= xbegin);
718  ensure(end() >= xend);
719 
720  // Exit:
721 
722  return;
723 };
724 
725 template <typename E, typename I>
726 void
729 {
730  // Preconditions:
731 
732  require(unexecutable("containers have been updated."));
733  require(unexecutable("ct() has been updated."));
734 
735  // Body:
736 
737  define_old_variable(pod_type old_begin = begin());
738  define_old_variable(pod_type old_end = end());
739 
740  if(_ct == 0)
741  {
742  // No more entries, invalid the extrema.
743 
744  _begin = invalid_pod_index();
745  _end = invalid_pod_index();
746  }
747  else if(xbegin == _begin)
748  {
749  // The id is the beginning, find new beginning.
750 
751  for(pod_type i = _begin; i < _end; i++)
752  {
753  if(contains_entry(i))
754  {
755  _begin = i;
756  break;
757  }
758  }
759  }
760  else if(xend == _end)
761  {
762  // The id is the end, find new end.
763 
764  for(pod_type i = xend - 1; i >= _begin; i--)
765  {
766  if(contains_entry(i))
767  {
768  _end = i+1;
769  break;
770  }
771  }
772  }
773 
774  // Postconditions:
775 
776  ensure((ct() == 0) ? !is_valid(begin()) : true);
777  ensure((ct() == 0) ? !is_valid(end()) : true);
778  ensure(((ct() > 0) && (xbegin == old_begin)) ? begin() > xbegin : true);
779  ensure(((ct() > 0) && (xend == old_end)) ? end() < xend : true);
780 
781  // Exit:
782 
783  return;
784 };
785 
786 // =============================================================================
787 // IMPLICIT_ENTRY_MAP FACET
788 // =============================================================================
789 
790 // PUBLIC MEMBER FUNCTIONS
791 
792 template <typename E, typename I>
793 bool
795 is_ancestor_of(const any* other) const
796 {
797  // Preconditions:
798 
799  require(other != 0);
800 
801  // Body:
802 
803  bool result = dynamic_cast< const implicit_entry_map<E, I>* >(other) != 0;
804 
805  // Postconditions:
806 
807  // Exit:
808 
809  return result;
810 };
811 
812 template <typename E, typename I>
815 clone() const
816 {
817  // Preconditions:
818 
819  // Body:
820 
822 
823  // Postconditions:
824 
825  ensure(result != 0);
826  ensure(is_same_type(result));
827 
828  // Exit:
829 
830  return result;
831 };
832 
833 template <typename E, typename I>
834 bool
836 invariant() const
837 {
838  bool result = true;
839 
840  if(invariant_check())
841  {
842  // Must satisfy base class invariant
843 
844  invariance(any::invariant());
845 
846  // Prevent recursive calls to invariant
847 
849 
850  // Invariances for this class:
851 
852  ensure((ct() > 0) == is_valid(begin()));
853  ensure((ct() > 0) == is_valid(end()));
854 
855  // Finished, turn invariant checking back on.
856 
858  }
859 
860  // Exit
861 
862  return result;
863 };
864 
865 // PROTECTED MEMBER FUNCTIONS
866 
867 // PRIVATE MEMBER FUNCTIONS
868 
869 
870 // =============================================================================
871 // NON-MEMBER FUNCTIONS
872 // =============================================================================
873 
874 template <typename E, typename I>
875 size_t
876 deep_size(const implicit_entry_map<E, I>& xmap, bool xinclude_shallow)
877 {
878  // Preconditions:
879 
880  // Body:
881 
882  size_t result = xinclude_shallow ? sizeof(xmap) : 0;
883 
886 
888 
889 // // Add contribution from member _explicit_value_map.
890 
891 // typedef no_deep_size_policy<typename implicit_entry_map<E, I>::explicit_value_map_type> explicit_policy_type;
892 // result += deep_size<pod_index_type, E*, explicit_policy_type>(xmap._explicit_value_map, false);
893 
894 // // Add contribution from member _interval_map.
895 
896 // typedef no_deep_size_policy<typename implicit_entry_map<E, I>::interval_map_type> interval_policy_type;
897 // result += deep_size<pod_index_type, I*, interval_policy_type>(xmap._interval_map, false);
898 
899  // Postconditions:
900 
901  ensure(result >= 0);
902 
903  // Exit:
904 
905  return result;
906 };
907 
908 } // namespace sheaf
909 
910 #endif // ifndef IMPLICIT_ENTRY_MAP_IMPL_H
911 
912 
913 
914 
915 
916 
virtual bool invariant() const
Class invariant, intended to be redefined in each descendant. See below for template for invariant in...
Definition: any.cc:153
static const interval_type & null_interval()
Null implicit interval.
void insert_explicit_entry(pod_type xid, E &xvalue)
Insert the explicit value xvalue at xid.
const explicit_value_type & explicit_value(pod_type xid) const
The explicit value at xid.
rc_ptr< E > explicit_value_type
The type of an explicit value.
bool contains_entry(pod_type xid) const
True if and only if contains_explicit_entry(xid) or contains_implicit_entry(xid). ...
void remove_implicit_interval(pod_type xid)
Remove the entire interval that contains xid.
pod_type begin() const
The beginning id of this.
void remove_explicit_entry(pod_type xid)
Remove the explicit entry at xid.
E & operator[](pod_type xid) const
The value at xid. If this map contains an explicit entry at xid, the explicit value is returned...
Abstract base class with useful features for all objects.
Definition: any.h:39
A map in which the entries may be implicit.
An iterator over the entries in an implicit_entry_map. This iteration is NOT order preserving...
~implicit_entry_map()
Destructor.
void remove_entry(pod_type xid, bool xremove_interval)
Remove the entry at xid. If xremove_interval remove the entire interval at xid otherwise only remove ...
void insert_implicit_interval(I &xinterval)
Insert the implicit interval xinterval.
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
size_type ct() const
The number of entries in this.
virtual bool is_ancestor_of(const any *other) const
Conformance test; true if other conforms to this.
void disable_invariant_check() const
Disable invariant check. Intended for preventing recursive calls to invariant and for suppressing inv...
Definition: any.h:97
bool contains_implicit_entry(pod_type xid) const
True if and only if this map contains an implicit entry for xid.
E & value(pod_type xid) const
The value at xid. If this map contains an explicit entry at xid, the explicit value is returned...
implicit_entry_map()
Default Constructor.
virtual bool invariant() const
Class invariant.
const interval_type & implicit_interval(pod_type xid) const
The implicit interval that contains xid.
virtual implicit_entry_map< E, I > * clone() const
Virtual constructor, makes a new instance of the same type as this.
bool contains_explicit_entry(pod_type xid) const
True if and only if this map contains an explicit entry for xid.
bool invariant_check() const
True if invariant checking is enabled.
Definition: any.h:79
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
pod_type end() const
The ending id of this.
Namespace for the sheaves component of the sheaf system.
static const explicit_value_type & null_explicit_value()
Null explicit value.
implicit_entry_map_iterator< E, I > iterator_type
The type of iterator for this map.
friend size_t deep_size(const implicit_entry_map< E, I > &xmap, bool xinclude_shallow)
The deep size of the referenced object of type implicit_entry_map<E, I>; if xinclude_shallow, add the sizeof xvalue to the result.
rc_ptr< I > interval_type
The type of an interval.
SHEAF_DLL_SPEC bool is_valid(pod_index_type xpod_index)
True if an only if xpod_index is valid.
Definition: pod_types.cc:37
SHEAF_DLL_SPEC pod_index_type invalid_pod_index()
The invalid pod index value.
Definition: pod_types.cc:31
bool is_same_type(const any *other) const
True if other is the same type as this.
Definition: any.cc:79
pod_index_type pod_type
The "plain old data" index type for this.
void enable_invariant_check() const
Enable invariant checking.
Definition: any.h:87
implicit_entry_map_iterator< E, I > * iterator() const
An iterator for the entries of this map.
Reference-counted pointer to object of type T. T must be an implementation of concept class rc_any...
Definition: factory_2.h:47