SheafSystem  0.0.0.0
array_poset_dof_map.cc
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 array_poset_dof_map
19 
20 #include "SheafSystem/array_poset_dof_map.h"
21 
22 #include "SheafSystem/arg_list.h"
23 #include "SheafSystem/assert_contract.h"
24 #include "SheafSystem/error_message.h"
25 #include "SheafSystem/dof_descriptor_array.h"
26 #include "SheafSystem/dof_map_factory.h"
27 #include "SheafSystem/poset_state_handle.h"
28 #include "SheafSystem/std_string.h"
29 
30 using namespace std;
31 
32 //#define DIAGNOSTIC_OUTPUT
33 //#undef DIAGNOSTIC_OUTPUT
34 
35 #define BOUNDS_CHECK
36 
37 // PUBLIC MEMBER FUNCTIONS
38 
40 const std::string&
42 class_name() const
43 {
44  // Preconditions:
45 
46  // Body:
47 
48  const string& result = static_class_name();
49 
50  // Postconditions:
51 
52  ensure(!result.empty());
53 
54  // Exit:
55 
56  return result;
57 }
58 
60 const std::string&
63 {
64  // Preconditions:
65 
66  // Body:
67 
68  static const string result("array_poset_dof_map");
69 
70  // Postconditions:
71 
72  ensure(!result.empty());
73  ensure(result == "array_poset_dof_map");
74 
75  // Exit:
76 
77  return result;
78 }
79 
80 // CANONICAL MEMBERS
81 
85  : poset_dof_map()
86 {
87 
88  // Preconditions:
89 
90 
91  // Body:
92 
93  _dofs = 0;
94  _dof_descriptors = 0;
95  _this_owns_dofs = false;
96 
97  // Postconditions:
98 
99  ensure(invariant());
100  ensure(!is_initialized());
101 
102  // Exit
103 
104  return;
105 }
106 
110 clone() const
111 {
112  array_poset_dof_map* result;
113 
114  // Preconditions:
115 
116 
117  // Body:
118 
119  result = new array_poset_dof_map();
120 
121  // Postconditions:
122 
123  ensure(result != 0);
124  ensure(result->is_same_type(this));
125  ensure(postcondition_of(array_poset_dof_map()));
126 
127  // Exit:
128 
129  return result;
130 }
131 
132 
136 {
137 
138  // Preconditions:
139 
140  require(xother.is_initialized());
141 
142  // Body:
143 
144  _dofs = 0;
145  _dof_descriptors = 0;
146  _this_owns_dofs = false;
147 
148  *this = xother;
149 
150  // Postconditions:
151 
152  ensure(invariant());
153 
154  // Exit
155 
156  return;
157 }
158 
162 copy() const
163 {
164  array_poset_dof_map* result;
165 
166  // Preconditions:
167 
168 
169  // Body:
170 
171  result = new array_poset_dof_map(*this);
172 
173  // Postconditions:
174 
175  ensure(result != 0);
176  ensure(result->is_same_type(this));
177  ensure(postcondition_of(array_poset_dof_map(*this)));
178 
179  // Exit:
180 
181  return result;
182 }
183 
184 
189 {
190 
191  // Preconditions:
192 
193  require(xother.is_initialized());
194 
195  // Body:
196 
197  poset_dof_map::operator=(xother);
198 
199  if(_dof_descriptors != 0)
200  _dof_descriptors->remove_reference();
201 
202  if((_dofs != 0) && _this_owns_dofs)
203  delete[] _dofs;
204 
205  if(xother._dofs != 0)
206  {
207  // Allocate and copy dof offsets
208 
209  _dof_descriptors = xother._dof_descriptors;
210  _dof_descriptors->add_reference();
211 
212 
213  // Allocate and copy the dof storage
214 
215  _this_owns_dofs = xother._this_owns_dofs;
216 
217  if(_this_owns_dofs)
218  {
219  _dofs = new char[dof_tuple_ub()];
220  memcpy(_dofs, xother._dofs, dof_tuple_ub());
221  }
222  else
223  {
224  _dofs = xother._dofs;
225  }
226  }
227  else
228  {
229  _dofs = 0;
230  _dof_descriptors = 0;
231  _this_owns_dofs = false;
232  }
233 
234  // Postconditions:
235 
236  ensure(invariant());
237 
238  // Exit
239 
240  return *this;
241 }
242 
243 
247 {
248 
249  // Preconditions:
250 
251 
252  // Body:
253 
254 
255  if(_dof_descriptors != 0)
256  _dof_descriptors->remove_reference();
257 
258  if(_this_owns_dofs)
259  delete[] _dofs;
260 
263 
266 
267 
268  // Postconditions:
269 
270 }
271 
272 
274 bool
276 invariant() const
277 {
278  bool result = true;
279 
280  // Preconditions:
281 
282  // Body:
283 
284  result = result && poset_dof_map::invariant();
285 
286  if(invariant_check())
287  {
288  // Prevent recursive calls to invariant
289 
291 
292  // Invariants for this class:
293 
294  // Last offset is upper bound on _dofs
295 
296  result = result && ( _dof_descriptors != 0 ? dof_tuple_ub() == (*_dof_descriptors)[dof_ct()].offset : true);
297 
298  // Finished, turn invariant checking back on.
299 
301  }
302 
303  // Postconditions:
304 
305  // Exit
306 
307  return result;
308 }
309 
310 
311 // OTHER CONSTRUCTORS
312 
316  bool xis_table_dof_map,
317  void* xdofs,
318  size_t xdofs_ub)
319  : poset_dof_map(xhost, xis_table_dof_map)
320 {
321 
322  // Preconditions:
323 
324  require(xhost != 0);
325  require(xhost->state_is_read_accessible());
326  require((xdofs != 0) ? xdofs_ub >= xhost->schema().dof_tuple_ub(xis_table_dof_map): true);
327  require(unexecutable("if xdofs != 0 it points to buffer of length xdofs_ub"));
328 
329  // Body:
330 
331  // Get the dof offsets from the dofs subposet in the schema,
332  // via the host. Increment the reference count
333 
334  _dof_descriptors = schema().dof_descriptors(xis_table_dof_map);
335  _dof_descriptors->add_reference();
336 
337  // Initialize dof storage
338 
339  init_dofs(xdofs);
340 
341  // Postconditions:
342 
343  ensure(dof_ct() == schema().dof_ct(is_table_dof_map()));
344  ensure((dof_tuple() != 0) == (dof_ct() != 0));
345  ensure(((dof_ct() != 0) && (xdofs != 0)) ? dof_tuple() == xdofs : true);
346 }
347 
350 array_poset_dof_map(const schema_poset_member* xschema, bool xis_table_dof_map)
351  : poset_dof_map(xschema, xis_table_dof_map)
352 {
353 
354  // Preconditions:
355 
356  require(xschema != 0);
357  require(xschema->state_is_read_accessible());
358 
359  // Body:
360 
361  // Get the dof offsets from the dofs subposet in the schema,
362  // increment the reference count
363 
364  _dof_descriptors = xschema->dof_descriptors(xis_table_dof_map);
365  _dof_descriptors->add_reference();
366 
367  // Initialize dof storage
368 
369  init_dofs(0);
370 
371  // Postconditions:
372 
373  ensure(dof_ct() == xschema->dof_ct(is_table_dof_map()));
374  ensure((dof_tuple() != 0) == (dof_ct() != 0));
375 }
376 
377 // ===========================================================
378 // MAP FACET
379 // ===========================================================
380 
381 
382 
386 type_id() const
387 {
388  dof_tuple_type result;
389 
390  // Preconditions:
391 
392  // Body:
393 
394  result = ARRAY_POSET_DOF_TUPLE_ID;
395 
396  // Postconditions:
397 
398  ensure(result == ARRAY_POSET_DOF_TUPLE_ID);
399 
400  // Exit:
401 
402  return result;
403 }
404 
405 
406 
407 // ===========================================================
408 // NEW DOF ACCESS FACET
409 // ===========================================================
410 
411 
412 void
414 get_dof(pod_index_type xdof_id, void* xdof, size_type xdof_size) const
415 {
416  // Preconditions:
417 
418  require(schema().state_is_read_accessible());
419  require(schema().dof_id_space(is_table_dof_map()).contains(xdof_id));
420  require(unexecutable("xdof points to buffer of size xdof_size"));
421  require(xdof_size >= schema().size(xdof_id, is_table_dof_map()));
422 
423  // Body:
424 
425  dof_descriptor_array::dof_descriptor& ldesc = (*_dof_descriptors)[xdof_id];
426 
427  // Compute a pointer to the beginning of
428  // the current dof in the dof tuple.
429 
430  char* ldof = _dofs+ldesc.offset;
431 
432  // Copy the dof into result.
433 
434 #ifdef BOUNDS_CHECK
435  dof_in_bounds(xdof_id);
436 #endif
437 
438  memcpy(xdof, ldof, ldesc.size);
439 
440  // Postconditions:
441 
442  // Exit:
443 
444  return;
445 }
446 
447 void
449 put_dof(pod_index_type xdof_id, const void* xdof, size_type xdof_size)
450 {
451  // Preconditions:
452 
453  require(schema().state_is_read_accessible());
454  require(schema().dof_id_space(is_table_dof_map()).contains(xdof_id));
455  require(unexecutable("xdof points to buffer of size xdof_size"));
456  require(xdof_size >= schema().size(xdof_id, is_table_dof_map()));
457 
458  // Body:
459 
460  dof_descriptor_array::dof_descriptor& ldesc = (*_dof_descriptors)[xdof_id];
461 
462  // Compute a pointer to the beginning of
463  // the current dof in the dof tuple.
464 
465  char* ldof = _dofs+ldesc.offset;
466 
467  // Copy the xdof into the dof.
468 
469 #ifdef BOUNDS_CHECK
470  dof_in_bounds(xdof_id);
471 #endif
472 
473  memcpy(ldof, xdof, ldesc.size);
474 
475  // Postconditions:
476 
477  // Exit:
478 
479  return;
480 }
481 
482 // ===========================================================
483 // END NEW DOF ACCESS FACET
484 // ===========================================================
485 
487 void*
490 {
491  void* result;
492 
493  // Preconditions:
494 
495  // Body:
496 
497  result = _dofs;
498 
499  // Postconditions:
500 
501  ensure(invariant());
502  ensure((result != 0) == (dof_ct() != 0));
503 
504  // Exit
505 
506  return result;
507 }
508 
510 const void*
512 dof_tuple() const
513 {
514  const void* result;
515 
516  // Preconditions:
517 
518  // Body:
519 
520  result = _dofs;
521 
522  // Postconditions:
523 
524  ensure(invariant());
525  ensure((result != 0) == (dof_ct() != 0));
526 
527  // Exit
528 
529  return result;
530 }
531 
533 void
535 get_dof_tuple(void* xbuf, size_t xbuflen) const
536 {
537  // Preconditions:
538 
539  require(dof_ct() > 0);
540  require(xbuf != 0);
541  require(dof_tuple_ub() <= xbuflen);
542 
543  // Body:
544 
545  memcpy(xbuf, static_cast<void*>(_dofs), dof_tuple_ub());
546 
547  // Postconditions:
548 
549  ensure(invariant());
550  ensure(unexecutable(dof tuple copied to xbuf));
551 
552  // Exit
553 
554  return;
555 }
556 
557 
559 void
561 put_dof_tuple(const void* xbuf, size_t xbuflen)
562 {
563  // Preconditions:
564 
565  require(dof_ct() > 0);
566  require(xbuf != 0);
567  require(dof_tuple_ub() <= xbuflen);
568 
569  // Body:
570 
571  memcpy(static_cast<void*>(_dofs), xbuf, dof_tuple_ub());
572 
573  // Postconditions:
574 
575  ensure(invariant());
576  ensure(unexecutable(xbuf copied to dof tuple));
577 
578  // Exit
579 
580  return;
581 }
582 
584 char*
586 dof_ptr(const schema_poset_member& xschema_mbr)
587 {
588  char* result;
589 
590  // Preconditions:
591 
592  require(schema().contains_row_dof(xschema_mbr));
593 
594  // Body:
595 
596  result = dof_ptr(client_id_space().pod(xschema_mbr.index()));
597 
598  // Postconditions:
599 
600  ensure(result != 0);
601 
602  // Exit
603 
604  return result;
605 }
606 
608 char*
610 dof_ptr(int xclient_id)
611 {
612  char* result;
613 
614  // Preconditions:
615 
616  require(dof_ct() > 0);
617  require((0 <= xclient_id) && (xclient_id < dof_ct()));
618 
619  // Body:
620 
621  size_t ldof_offset = (*_dof_descriptors)[xclient_id].offset;
622  result = _dofs+ldof_offset;
623 
624  // Postconditions:
625 
626  ensure(result != 0);
627 
628  // Exit
629 
630  return result;
631 }
632 
633 // PROTECTED MEMBER FUNCTIONS
634 
636 void
638 init_dofs(void* xdofs)
639 {
640  // Preconditions:
641 
642  // Body:
643 
644  if(dof_ct() > 0)
645  {
646  if(xdofs == 0)
647  {
648  _dofs = new char[dof_tuple_ub()];
649  _this_owns_dofs = true;
650  }
651  else
652  {
653  _dofs = static_cast<char*>(xdofs);
654  _this_owns_dofs = false;
655  }
656  }
657  else
658  {
659  _this_owns_dofs = false;
660  _dofs = 0;
661  }
662 
663  // Postconditions:
664 
665  ensure((dof_ct() != 0) == (_dofs != 0));
666  ensure(unexecutable(size of _dofs array == dof_tuple_ub()));
667 
668  // Exit
669 
670  return;
671 }
672 
674 void
677 {
678  // Preconditions:
679 
680 
681  // Body:
682 
683  // Get the dof offsets from the dofs subposet in the schema,
684  // via the host. Increment the reference count
685 
686  _dof_descriptors = schema().dof_descriptors(false);
687  _dof_descriptors->add_reference();
688 
689  init_dofs(0);
690 
691  // Postconditions:
692 
693 
694  // Exit:
695 
696  return;
697 }
698 
699 bool
702 {
703  // Preconditions:
704 
705 
706  // Body:
707 
708  dof_descriptor_array::dof_descriptor& ldesc = (*_dof_descriptors)[xdof_id];
709  size_type loffset = ldesc.offset;
710  size_type lsize = ldesc.size;
711  size_type lub = loffset + lsize;
712 
713  bool result = (lub <= _dof_tuple_ub);
714 
715 #ifdef DIAGNOSTIC_OUTPUT
716  cout << " xdof_id: " << xdof_id
717  << " offset: " << loffset
718  << " size: " << lsize
719  << " ub: " << lub
720  << " dofs ub: " << _dof_tuple_ub
721  << " result: " << boolalpha << result << noboolalpha
722  << endl;
723 #endif
724 
725  if(!result)
726  {
727  post_fatal_error_message("dof_in_bounds check failed");
728  }
729 
730  // Postconditions:
731 
732 
733  // Exit:
734 
735  return result;
736 }
737 
739 bool
740 sheaf::array_poset_dof_map::
741 make_prototype()
742 {
743  bool result = false;
744 
745  // Preconditions:
746 
747 
748  // Body:
749 
750  dof_tuple_type ltype = ARRAY_POSET_DOF_TUPLE_ID;
751 
752  poset_dof_map* lproto = new array_poset_dof_map;
753 
754  factory().insert_prototype(lproto);
755  factory().insert_prototype(ltype, lproto);
756 
757  // Postconditions:
758 
759 
760  // Exit:
761 
762  return result;
763 }
764 
765 
766 // ===========================================================
767 // NON-MEMBER FUNCTIONS
768 // ===========================================================
769 
virtual const index_space_handle & client_id_space() const
The map from library ids to clients ids for the schema this is defined on.
static const std::string & static_class_name()
The name of this class.
bool is_table_dof_map() const
True if this is a table dof map.
virtual void allocate_dofs()
Allocates dof storage.
virtual ~array_poset_dof_map()
Destructor.
virtual array_poset_dof_map * clone() const
Virtual default constructor.
bool state_is_read_accessible() const
True if this is attached and if the state is accessible for read or access control is disabled...
virtual schema_poset_member & schema()
The schema on which this is allocated (mutable version).
primitive_value dof(pod_index_type xdof_id) const
The dof referred to by xdof_id.
A client handle for a general, abstract partially order set.
static int dof_ct(const namespace_poset &xns, const poset_path &xpath, bool xis_table_dof, bool xauto_access=true)
The number of table dofs (xis_table_dof true) or row dofs defined by the schema specified by xns and ...
dof_descriptor_array * dof_descriptors(bool xis_table_dof) const
The dof_descriptors_array for the table dof tuple (xis_table_dof true) or row dof tuple defined by th...
bool is_initialized() const
True if this has been initialized, that is, if the schema has been set and the dof map storage alloca...
STL namespace.
char * dof_ptr(const schema_poset_member &xschema_mbr)
Pointer to the first byte of the dof associated with xschema_mbr.
poset_dof_map & operator=(const poset_dof_map &xother)
Assignment operator.
const scoped_index & index() const
The index of the component state this handle is attached to.
The general, abstract map from dof ids to dof values.
Definition: poset_dof_map.h:59
size_t _dof_tuple_ub
The size of the dof tuple.
static dof_map_factory & factory()
The dof map factory.
virtual dof_tuple_type type_id() const
An identifer for the type of dof tuple this is.
virtual schema_poset_member & schema()
The schema for this poset (mutable version).
virtual bool invariant() const
The class invariant.
size_t dof_tuple_ub() const
The size of the dof tuple in bytes.
virtual bool invariant() const
The class invariant.
virtual void get_dof(pod_index_type xdof_id, void *xdof, size_type xdof_size) const
Copies the dof referred to by xdof_id into xdof.
unsigned long size_type
An unsigned integral type used to represent sizes and capacities.
Definition: sheaf.h:52
dof_tuple_type
Identifiers for dof tuple types.
void disable_invariant_check() const
Disable invariant check. Intended for preventing recursive calls to invariant and for suppressing inv...
Definition: any.h:97
array_poset_dof_map()
Default constructor; protected because doesn&#39;t initialize schema.
bool dof_in_bounds(pod_index_type xdof_id) const
True if and only if the dof asociated with id xdof_id is within the bounds of the dofs storage...
int dof_ct() const
The number of dofs in this map.
void remove_reference()
Remove a reference from this.
virtual void * dof_tuple()
The dof tuple (mutable version).
virtual void put_dof_tuple(const void *xbuf, size_t xbuflen)
Copies the entire dof tuple from xbuf into internal storage.
void init_dofs(void *xdofs)
Allocates dof array.
virtual void put_dof(pod_index_type xdof_id, const void *xdof, size_type xdof_size)
Sets the dof referred to by xdof_id to the value at xdof.
bool invariant_check() const
True if invariant checking is enabled.
Definition: any.h:79
size_t dof_tuple_ub(bool xis_table_dof) const
The size in bytes of the table dof tuple (xis_table_dof true) or the row dof tuple defined by this sc...
virtual const std::string & class_name() const
The name of the actual (possibly derived) class of this instance.
int_type pod_index_type
The plain old data index type.
Definition: pod_types.h:49
void add_reference()
Add a reference to this.
virtual void get_dof_tuple(void *xbuf, size_t xbuflen) const
Copies the entire dof tuple from internal storage into xbuf.
void tuple(pod_index_type x, size_type xj_ub, pod_index_type &xi, pod_index_type &xj)
Ordinal to 2-tuple conversion.
void insert_prototype(const poset_dof_map *xprototype)
Sets xprototype as the prototype for its client class.
An array representation of abstract class poset_dof_map.
bool is_same_type(const any *other) const
True if other is the same type as this.
Definition: any.cc:79
void enable_invariant_check() const
Enable invariant checking.
Definition: any.h:87
virtual array_poset_dof_map * copy() const
Virtual copy constructor.
A client handle for a poset member which has been prepared for use as a schema.
array_poset_dof_map & operator=(const array_poset_dof_map &xother)
Assignment operator.