SheafSystem  0.0.0.0
record_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 RECORD_MAP_IMPL_H
22 #define RECORD_MAP_IMPL_H
23 
24 #ifndef SHEAF_DLL_SPEC_H
25 #include "SheafSystem/sheaf_dll_spec.h"
26 #endif
27 
28 #ifndef RECORD_MAP_H
29 #include "SheafSystem/record_map.h"
30 #endif
31 
32 #ifndef ASSERT_CONTRACT_H
33 #include "SheafSystem/assert_contract.h"
34 #endif
35 
36 #ifndef INDEX_TRAITS_H
37 #include "SheafSystem/index_traits.h"
38 #endif
39 
40 #ifndef STD_IOMANIP_H
41 #include "SheafSystem/std_iomanip.h"
42 #endif
43 
44 namespace sheaf
45 {
46 
47 // ===========================================================
48 // RECORD_MAP FACET
49 // ===========================================================
50 
51 // PUBLIC MEMBER FUNCTIONS
52 
53 template<typename internal_index_type, typename external_index_type>
56 {
57  // Preconditions:
58 
59  // Body:
60 
61  _internal_ids_sequential = false;
62  _external_ids_sequential = false;
63 
64  _scratch_internal_id = index_traits<internal_index_type>::invalid();
65  _scratch_external_id = index_traits<external_index_type>::invalid();
66 
67  _internal_id_ub = index_traits<internal_index_type>::min();
68  _external_id_ub = index_traits<external_index_type>::min();
69 
70  _entry_removed = false;
71 
72  // Postconditions:
73 
74  ensure(invariant());
75  ensure(!internal_ids_sequential());
76  ensure(!external_ids_sequential());
77  ensure(!index_traits< internal_index_type >::is_valid(scratch_internal_id()));
78  ensure(!index_traits< external_index_type >::is_valid(scratch_external_id()));
79  ensure(internal_id_ub() == index_traits<internal_index_type>::min());
80  ensure(external_id_ub() == index_traits<external_index_type>::min());
81  ensure(!ub_is_max());
82 
83  // Exit
84 
85  return;
86 }
87 
88 template <typename internal_index_type, typename external_index_type>
90 record_map(const record_map& xother)
91 {
92  // Preconditions:
93 
94  // Body:
95 
96  (*this) = xother;
97 
98  // Postconditions:
99 
100  ensure(invariant());
101  ensure(unexecutable((*this) == xother));
102 
103  // Exit
104 
105  return;
106 }
107 
108 template <typename internal_index_type, typename external_index_type>
111 operator=(const record_map& xother)
112 {
113  // Preconditions:
114 
115  // Body:
116 
117  if(this != &xother)
118  {
119  record_map& lother = const_cast<record_map&>(xother);
120 
121  _to_external = lother._to_external;
122  _to_internal = lother._to_internal;
123  _internal_ids_sequential = lother._internal_ids_sequential;
124  _external_ids_sequential = lother._external_ids_sequential;
125 
126  _scratch_internal_id = lother._scratch_internal_id;
127  _scratch_external_id = lother._scratch_external_id;
128 
129  _internal_id_ub = lother._internal_id_ub;
130  _external_id_ub = lother._external_id_ub;
131 
132  _entry_removed = lother._entry_removed;
133  }
134 
135  // Postconditions:
136 
137  ensure(invariant());
138  ensure((*this) == xother);
139 
140  // Exit
141 
142  return *this;
143 }
144 
145 template <typename internal_index_type, typename external_index_type>
148 {
149  // Preconditions:
150 
151  // Body:
152 
153  // Postconditions:
154 
155  return;
156 }
157 
158 template <typename internal_index_type, typename external_index_type>
159 bool
161 invariant() const
162 {
163  bool result = true;
164 
165  // Internal and external maps always the same size.
166 
167  invariance(_to_internal.size() == _to_external.size());
168 
169  // Internal and external sequential ids are
170  // mutually exclusive, but both can be false.
171 
172  invariance(_internal_ids_sequential ? !_external_ids_sequential : true);
173  invariance(_external_ids_sequential ? !_internal_ids_sequential : true);
174 
175  // Definition of upper bounds.
176 
177  invariance(unexecutable("for all internal ids i: i <= internal_id_ub()"));
178  invariance(unexecutable("ub_is_max() ? there exists entry (int_id, ext_id) such that int_id= internal_id_ub()"));
179  invariance(unexecutable("for all external ids i: i <= external_id_ub()"));
180  invariance(unexecutable("ub_is_max() ? there exists entry (int_id, ext_id) such that ext_id= external_id_ub()"));
181 
182  return result;
183 }
184 
185 template <typename internal_index_type, typename external_index_type>
186 external_index_type
188 external_id(internal_index_type xinternal_id) const
189 {
190  // Preconditions:
191 
192  // Body:
193 
194  typename unordered::unordered_map<internal_index_type, external_index_type>::const_iterator itr = _to_external.find(xinternal_id);
195  external_index_type result =
196  itr != _to_external.end() ? itr->second : index_traits<external_index_type>::invalid();
197 
198  // Postconditions:
199 
200  ensure(invariant());
201 
202  // Exit
203 
204  return result;
205 }
206 
207 
208 template <typename internal_index_type, typename external_index_type>
209 internal_index_type
211 internal_id(external_index_type xexternal_id) const
212 {
213  // Preconditions:
214 
215  // Body:
216 
217  typename unordered::unordered_map<external_index_type, internal_index_type>::const_iterator itr = _to_internal.find(xexternal_id);
218  internal_index_type result =
219  itr != _to_internal.end() ? itr->second : index_traits<internal_index_type>::invalid();
220 
221  // Postconditions:
222 
223  ensure(invariant());
224 
225  // Exit
226 
227  return result;
228 }
229 
230 template <typename internal_index_type, typename external_index_type>
231 void
233 put_ids(internal_index_type xinternal_id, external_index_type xexternal_id)
234 {
235  // Preconditions:
236 
237  require(!is_empty() ? !internal_ids_sequential() && !external_ids_sequential() : true);
238  require(!contains_internal_id(xinternal_id));
239  require(!contains_external_id(xexternal_id));
240 
241  // Body:
242 
243  unguarded_put_ids(xinternal_id, xexternal_id);
244 
245  // Postconditions:
246 
247  ensure(invariant());
248  ensure(external_id(xinternal_id) == xexternal_id);
249  ensure(internal_id(xexternal_id) == xinternal_id);
250 
251  // Exit
252 
253  return;
254 }
255 
256 template <typename internal_index_type, typename external_index_type>
257 void
259 unguarded_put_ids(internal_index_type xinternal_id, external_index_type xexternal_id)
260 {
261  // Preconditions:
262 
263  // Body:
264 
265  _to_external.insert(typename external_map_type::value_type(xinternal_id, xexternal_id));
266  _to_internal.insert(typename internal_map_type::value_type(xexternal_id, xinternal_id));
267 
268  _internal_id_ub = (xinternal_id > _internal_id_ub) ? xinternal_id : _internal_id_ub;
269  _external_id_ub = (xexternal_id > _external_id_ub) ? xexternal_id : _external_id_ub;
270 
271  // Postconditions:
272 
273  ensure(invariant());
274 
275  // Exit
276 
277  return;
278 }
279 
280 template <typename internal_index_type, typename external_index_type>
281 bool
284 {
285  return _internal_ids_sequential;
286 }
287 
288 template <typename internal_index_type, typename external_index_type>
289 bool
292 {
293  return _external_ids_sequential;
294 }
295 
296 template <typename internal_index_type, typename external_index_type>
297 external_index_type
299 put_internal_id(internal_index_type xinternal_id)
300 {
301  external_index_type result;
302 
303  // Preconditions:
304 
305  require(!is_empty() ? external_ids_sequential() : true);
306  require(!contains_internal_id(xinternal_id));
307 
308  // Body:
309 
310  typename index_traits<external_index_type>::pod_type lpod = _to_external.size();
312 
313  unguarded_put_ids(xinternal_id, result);
314  _external_ids_sequential = true;
315 
316  // Postconditions:
317 
318  ensure(invariant());
319  ensure(index_traits<external_index_type>::pod(result) == (ct() - 1));
320  ensure(external_id(xinternal_id) == result);
321  ensure(external_ids_sequential());
322 
323  // Exit
324 
325  return result;
326 }
327 
328 template <typename internal_index_type, typename external_index_type>
329 internal_index_type
331 put_external_id(external_index_type xexternal_id)
332 {
333  internal_index_type result;
334 
335  // Preconditions:
336 
337  require(!is_empty() ? internal_ids_sequential() : true);
338  require(!contains_external_id(xexternal_id));
339 
340  // Body:
341 
342  typename index_traits<internal_index_type>::pod_type lpod = _to_internal.size();
344 
345 
346  unguarded_put_ids(result, xexternal_id);
347  _internal_ids_sequential = true;
348 
349  // Postconditions:
350 
351  ensure(invariant());
352  ensure(index_traits<internal_index_type>::pod(result) == (ct() - 1));
353  ensure(internal_id(xexternal_id) == result);
354  ensure(internal_ids_sequential());
355 
356  // Exit
357 
358  return result;
359 }
360 
361 template <typename internal_index_type, typename external_index_type>
362 bool
364 contains_internal_id(internal_index_type xint_id) const
365 {
366  bool result;
367 
368  // Preconditions:
369 
370  // Body:
371 
372 
373  typename external_map_type::const_iterator lresult = _to_external.find(xint_id);
374 
375  result = lresult != _to_external.end();
376 
377  // Postconditions:
378 
379  ensure(invariant());
380 
381  // Exit
382 
383  return result;
384 }
385 
386 template <typename internal_index_type, typename external_index_type>
387 bool
389 contains_external_id(external_index_type xext_id) const
390 {
391  bool result;
392 
393  // Preconditions:
394 
395  // Body:
396 
397 
398  typename internal_map_type::const_iterator lresult = _to_internal.find(xext_id);
399 
400  result = lresult != _to_internal.end();
401 
402  // Postconditions:
403 
404  ensure(invariant());
405 
406  // Exit
407 
408  return result;
409 }
410 
411 template <typename internal_index_type, typename external_index_type>
412 bool
414 operator==(const record_map& xother) const
415 {
416  bool result = true;
417 
418  // Preconditions:
419 
420  // Body:
421 
422  record_map& lother = const_cast<record_map&>(xother);
423 
430 
431  // result = result && (_to_internal == lother._to_internal);
432  // result = result && (_to_external == lother._to_external);
433 
434  result = result && (_scratch_internal_id == lother._scratch_internal_id);
435  result = result && (_scratch_external_id == lother._scratch_external_id);
436 
437  result = result && (_internal_id_ub == lother._internal_id_ub);
438  result = result && (_external_id_ub == lother._external_id_ub);
439 
440  result = result && (_entry_removed == lother._entry_removed);
441 
442  // Postconditions:
443 
444  ensure(invariant());
445 
446  // Exit
447 
448  return result;
449 }
450 
451 template <typename internal_index_type, typename external_index_type>
452 size_type
454 ct() const
455 {
456  return _to_internal.size();
457 }
458 
459 template <typename internal_index_type, typename external_index_type>
460 bool
462 is_empty() const
463 {
464  return ct() == 0;
465 }
466 
467 template <typename internal_index_type, typename external_index_type>
468 void
471 {
472  // Preconditions:
473 
474  // Body:
475 
476  _to_external.clear();
477  _to_internal.clear();
478 
479  _internal_ids_sequential = false;
480  _external_ids_sequential = false;
481 
482  _scratch_internal_id = index_traits<internal_index_type>::invalid();
483  _scratch_external_id = index_traits<external_index_type>::invalid();
484 
485  _internal_id_ub = index_traits<internal_index_type>::min();
486  _external_id_ub = index_traits<external_index_type>::min();
487 
488  _entry_removed = false;
489 
490  // Postconditions:
491 
492  ensure(invariant());
493  ensure(!internal_ids_sequential());
494  ensure(!external_ids_sequential());
495  ensure(is_empty());
496  ensure(!index_traits< internal_index_type >::is_valid(scratch_internal_id()));
497  ensure(!index_traits< external_index_type >::is_valid(scratch_external_id()));
498  ensure(internal_id_ub() == index_traits<internal_index_type>::min());
499  ensure(external_id_ub() == index_traits<external_index_type>::min());
500  ensure(!ub_is_max());
501 
502  // Exit
503 
504  return;
505 }
506 
507 template <typename internal_index_type, typename external_index_type>
508 void
510 remove_internal_id(internal_index_type xinternal_id)
511 {
512  // Preconditions:
513 
514  // Body:
515 
516  typename external_map_type::iterator litr = _to_external.find(xinternal_id);
517 
518  if(litr != _to_external.end())
519  {
520  _to_internal.erase(litr->second);
521  _to_external.erase(litr);
522  }
523 
529 
530  _entry_removed = true;
531 
532  // Postconditions:
533 
534  ensure(invariant());
535  ensure(!contains_internal_id(xinternal_id));
536  ensure(!ub_is_max());
537 
538  // Exit
539 
540  return;
541 }
542 
543 template <typename internal_index_type, typename external_index_type>
544 void
546 remove_external_id(external_index_type xexternal_id)
547 {
548  // Preconditions:
549 
550  // Body:
551 
552  typename internal_map_type::iterator litr = _to_internal.find(xexternal_id);
553 
554  if(litr != _to_internal.end())
555  {
556  _to_external.erase(litr->second);
557  _to_internal.erase(litr);
558  _entry_removed = true;
559  }
560 
561  // Postconditions:
562 
563  ensure(invariant());
564  ensure(!contains_external_id(xexternal_id));
565  ensure(!ub_is_max());
566 
567  // Exit
568 
569  return;
570 }
571 
572 template <typename internal_index_type, typename external_index_type>
573 internal_index_type
576 {
577  // Preconditions:
578 
579  // Body:
580 
581  // Postconditions:
582 
583  // Exit:
584 
585  return _scratch_internal_id;
586 }
587 
588 
589 template <typename internal_index_type, typename external_index_type>
590 void
592 put_scratch_internal_id(internal_index_type xid)
593 {
594  // Preconditions:
595 
596  // Body:
597 
598  _scratch_internal_id = xid;
599 
600  // Postconditions:
601 
602  ensure(scratch_internal_id() == xid);
603 
604  // Exit:
605 
606  return;
607 }
608 
609 template <typename internal_index_type, typename external_index_type>
610 external_index_type
613 {
614  // Preconditions:
615 
616  // Body:
617 
618  // Postconditions:
619 
620  // Exit:
621 
622  return _scratch_external_id;
623 }
624 
625 template <typename internal_index_type, typename external_index_type>
626 void
628 put_scratch_external_id(external_index_type xid)
629 {
630  // Preconditions:
631 
632  // Body:
633 
634  _scratch_external_id = xid;
635 
636  // Postconditions:
637 
638  ensure(scratch_external_id() == xid);
639 
640  // Exit:
641 
642  return;
643 }
644 
645 template <typename internal_index_type, typename external_index_type>
646 internal_index_type
649 {
650  // Preconditions:
651 
652  // Body:
653 
654  internal_index_type result = _internal_id_ub;
655 
656  // Postconditions:
657 
658  ensure(unexecutable("for all internal ids i: i <= result"));
659  ensure(unexecutable("if remove_internal_id has not been called result = maximum internal id"));
660 
661  // Exit:
662 
663  return result;
664 }
665 
666 template <typename internal_index_type, typename external_index_type>
667 external_index_type
670 {
671  // Preconditions:
672 
673  // Body:
674 
675  external_index_type result = _external_id_ub;
676 
677  // Postconditions:
678 
679  ensure(unexecutable("for all external ids i: i <= result"));
680  ensure(unexecutable("if remove_external_id has not been called result = maximum external id"));
681 
682  // Exit:
683 
684  return result;
685 }
686 
687 template <typename internal_index_type, typename external_index_type>
688 bool
690 ub_is_max() const
691 {
692  bool result;
693 
694  // Preconditions:
695 
696  // Body:
697 
698  // Upper bounds are accumulated as entries are inserted,
699  // but can not be efficiently reduced when entries are removed.
700  // So upper bounds will be maxima if there have been no removals.
701 
702  result = (ct() > 0) && !_entry_removed;
703 
704  // Postconditions:
705 
706  ensure(unexecutable("result == (upper bounds are in fact maxima)"));
707 
708  // Exit
709 
710  return result;
711 }
712 
713 template <typename internal_index_type, typename external_index_type>
716 begin() const
717 {
718  return _to_external.begin();
719 }
720 
721 template <typename internal_index_type, typename external_index_type>
724 end() const
725 {
726  return _to_external.end();
727 }
728 
729 template <typename internal_index_type, typename external_index_type>
730 inline void
732 print() const
733 {
734  // Preconditions:
735 
736  // Body:
737 
738  print(std::cout, *this);
739 
740  // Postconditions:
741 
742  // Exit:
743 }
744 
745 template <typename internal_index_type, typename external_index_type>
746 void
748 print(std::ostream& xos,
750 {
751  // Preconditions:
752 
753  // Body:
754 
755  using namespace std;
756  using namespace unordered;
757 
760 
761  xos << endl << "internal to external map:" << endl;
762 
763  xos << "int:";
764  typename unordered_map<internal_index_type, external_index_type>::iterator itr0;
765  itr0 = lp._to_external.begin();
766  while(itr0 != lp._to_external.end())
767  {
768  xos << setw(6) << itr0->first;
769  itr0++;
770  }
771  xos << endl;
772  xos << "ext:";
773  itr0 = lp._to_external.begin();
774  while(itr0 != lp._to_external.end())
775  {
776  xos << setw(6) << itr0->second;
777  itr0++;
778  }
779  xos << endl;
780 
781  xos << "external to internal map:" << endl;
782 
783  xos << "ext:";
784  typename unordered_map<external_index_type, internal_index_type>::iterator itr1;
785  itr1 = lp._to_internal.begin();
786  while(itr1 != lp._to_internal.end())
787  {
788  xos << setw(6) << itr1->first;
789  itr1++;
790  }
791  xos << endl;
792  xos << "int:";
793  itr1 = lp._to_internal.begin();
794  while(itr1 != lp._to_internal.end())
795  {
796  xos << setw(6) << itr1->second;
797  itr1++;
798  }
799  xos << endl;
800 
801  // Postconditions:
802 
803  // Exit:
804 
805 }
806 
807 // PROTECTED MEMBER FUNCTIONS
808 
809 // PRIVATE MEMBER FUNCTIONS
810 
811 
812 //==============================================================================
813 // NON-MEMBER FUNCTIONS
814 //==============================================================================
815 
816 template<typename internal_index_type, typename external_index_type>
817 std::ostream&
818 operator<<(std::ostream& xos,
820 {
821  // Preconditions:
822 
823  // Body:
824 
825  xp.print(xos, xp);
826 
827  // Postconditions:
828 
829  // Exit:
830 
831  return xos;
832 }
833 
834 } // namespace sheaf
835 
836 #endif // ifndef RECORD_MAP_IMPL_H
internal_index_type internal_id(external_index_type xexternal_id) const
The internal id corresponding to xexternal_id.
static T invalid()
The invalid index value.
Definition: index_traits.h:70
T pod_type
An integral type representing a relative index.
Definition: index_traits.h:48
external_index_type external_id(internal_index_type xinternal_id) const
The external id corresponding to xinternal_id.
void put_scratch_external_id(external_index_type xid)
Sets the value of the external id scratch register to xid.
bool operator==(const record_map &xother) const
True if same external_id and internal_id.
void put_scratch_internal_id(internal_index_type xid)
Sets the value of the internal id scratch register to xid.
bool is_empty() const
True if there are no entries in the map.
STL namespace.
const_iterator end() const
The end of the range of internal ids contained in this.
bool contains_internal_id(internal_index_type xint_id) const
True if this map contains an entry for internal index xint_id.
Features describing T as an index type.
Definition: index_traits.h:38
record_map()
Default constructor.
external_index_type external_id_ub() const
The maximum external id in this map.
bool external_ids_sequential() const
True if sequentially assigning external ids.
size_type ct() const
The number of entries in the map.
internal_index_type internal_id_ub() const
The maximum internal id in this map.
const_iterator begin() const
The beginning of the range of internal ids contained in this.
internal_index_type scratch_internal_id() const
The value of the internal id scratch register. The scratch register is a convenient place for a clien...
bool ub_is_max() const
True if internal_id_ub and external_id_ub are in fact maxima; i.e. if there exists an entry (int_id...
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
void clear()
Removes all entries.
bool internal_ids_sequential() const
True if sequentially assigning internal ids.
void remove_internal_id(internal_index_type xinternal_id)
Removes xinternal_id and its external image from the map.
virtual bool invariant() const
The class invariant.
SHEAF_DLL_SPEC std::ostream & operator<<(std::ostream &os, const dof_descriptor_array &p)
Insert dof_descriptor_array& p into ostream& os.
unordered::unordered_map< internal_index_type, external_index_type >::const_iterator const_iterator
The type of const iterator for this.
Definition: record_map.h:224
Namespace for the sheaves component of the sheaf system.
external_index_type scratch_external_id() const
The value of the external id scratch register. The scratch register is a convenient place for a clien...
void put_ids(internal_index_type xinternal_id, external_index_type xexternal_id)
Defines the mapping between xinternal_id and xexternal_id.
static T min()
The minimum valid value.
Definition: index_traits.h:126
external_index_type put_internal_id(internal_index_type xinternal_id)
Defines a mapping between xinternal_id and a sequentially assigned external id. Returns the external ...
bool contains_external_id(external_index_type xext_id) const
True if this map contains an entry for external index xext_id.
Insert record_map& p into ostream& os.
Definition: record_map.h:46
void remove_external_id(external_index_type xexternal_id)
Removes xexternal_id and its internal image from the map.
static void put_pod(T &xindex, pod_type &xpod)
Sets the pod of index type xindex to xpod.
Definition: index_traits.h:61
virtual ~record_map()
Destructor.
internal_index_type put_external_id(external_index_type xexternal_id)
Defines a mapping between xexternal_id and a sequentially assigned internal id.
void print() const
Prints the data members of this on cout. Intended for use debugging.
record_map & operator=(const record_map &xother)
Assignment operator.