It is desirable to implement the notion of a bad item representing for example a simplex that was previously erased or that is currently unused.
Possible implementations that have been / are being explored are:
-
Implement a BadSimplex class deriving from Simplex and implementing overriding throwing behavior (i.e. all methods of Simplex are overridden by BadSimplex and throwing a 'Bad Simplex' exception). This solution, however, requires to implement throwing behavior for all methods of Simplex and therefore it is heavy to maintain. In addition, other classes (e.g. OrientedSimplex, Point) may need the same structure, which would lead then to significant code duplication.
-
Implement a more general BadItem class template with respect to a Resource (e.g. a Simplex, OrientedSimplex, Point, ...) deriving directly from SharedPointer<Resource>. This implementation allows a more general behavior where the exception is thrown at the 'upper' operator-> level, regardless of the type of Resource. This also allows to manage the 'bad' behavior above the scope of the SegmentedConatainer, in the sense that the SegmentedContainer will wrap a bad resource in a BadItem, which is perfectly exchangeable with the original SharedPointer instance. This implementation is therefore easier to integrate with the clients of the SegmentedContainer. However, this implementation, much like the previous one requires to virtualize the arrow operator with potential performance pitfalls. In addition, this option requires more reasoning on what is allowed for a BadItem (as compared to a SharedPointer): are the copy/move constructor allowed? What is the meaning of having multiple BadItem instances? Should the BadItem be a singleton. If yes, who should own it?
(This is the current implementation in the head of the bad-simplex branch. However, revision 925fb49 clearly shows that erasing a cell from topology twice leads to a segmentation fault, and not to the desired throwing behavior. This is also discussed in a comment added in revision be8112c).
-
A different point of view sees the BadItem as simply a special instance of Resource (as opposed to a class) with some property being set to an evidently faulty / inadmissible value. Examples are: 1) a SharedPointer with a nullptr handle, 2) a Shareable with a negative reference count. The first case is not ideal because the inadmissibility information is not maintained within the SegmentedContainer (in fact, the SegmentedContainer stores the Resource but has no control on the SharedPointer that they are wrapped into). The second case is also not ideal because a negative reference count may be inadvertently incremented to an admissible value (albeit adding a check with an if condition checking the sanity of the object prior to every resource acquisition).
The current implementation in the main branch uses a nullptr notion for a SharedPointer. The is_nullptr method will tell if the resource is invalid or not. Branch bad-simplex explores the options discussed above and hopefully will implement the final one.
It is desirable to implement the notion of a bad item representing for example a simplex that was previously erased or that is currently unused.
Possible implementations that have been / are being explored are:
Implement a
BadSimplexclass deriving fromSimplexand implementing overriding throwing behavior (i.e. all methods ofSimplexare overridden byBadSimplexand throwing a 'Bad Simplex' exception). This solution, however, requires to implement throwing behavior for all methods ofSimplexand therefore it is heavy to maintain. In addition, other classes (e.g.OrientedSimplex,Point) may need the same structure, which would lead then to significant code duplication.Implement a more general
BadItemclass template with respect to aResource(e.g. aSimplex,OrientedSimplex,Point, ...) deriving directly fromSharedPointer<Resource>. This implementation allows a more general behavior where the exception is thrown at the 'upper'operator->level, regardless of the type ofResource. This also allows to manage the 'bad' behavior above the scope of theSegmentedConatainer, in the sense that theSegmentedContainerwill wrap a bad resource in aBadItem, which is perfectly exchangeable with the originalSharedPointerinstance. This implementation is therefore easier to integrate with the clients of theSegmentedContainer. However, this implementation, much like the previous one requires to virtualize the arrow operator with potential performance pitfalls. In addition, this option requires more reasoning on what is allowed for aBadItem(as compared to aSharedPointer): are the copy/move constructor allowed? What is the meaning of having multipleBadIteminstances? Should theBadItembe a singleton. If yes, who should own it?(This is the current implementation in the head of the
bad-simplexbranch. However, revision 925fb49 clearly shows that erasing a cell from topology twice leads to a segmentation fault, and not to the desired throwing behavior. This is also discussed in a comment added in revision be8112c).A different point of view sees the BadItem as simply a special instance of Resource (as opposed to a class) with some property being set to an evidently faulty / inadmissible value. Examples are: 1) a
SharedPointerwith anullptrhandle, 2) aShareablewith a negative reference count. The first case is not ideal because the inadmissibility information is not maintained within theSegmentedContainer(in fact, theSegmentedContainerstores theResourcebut has no control on theSharedPointerthat they are wrapped into). The second case is also not ideal because a negative reference count may be inadvertently incremented to an admissible value (albeit adding a check with anifcondition checking the sanity of the object prior to every resource acquisition).The current implementation in the main branch uses a
nullptrnotion for a SharedPointer. Theis_nullptrmethod will tell if the resource is invalid or not. Branchbad-simplexexplores the options discussed above and hopefully will implement the final one.