template<int BitWidth>
class TPropertyCombinationSet< BitWidth >
TPropertyCombinationSet is a set of integers where the integers are bit fields for whether each of n independent properties are present. We refer to each element in the set as a corner; this term is derived from the model of a BitWidth-dimensional hypercube; each corner of the hypercube maps to one of the possible combinations of the bit field. TPropertyCombinationSet has another trait: redundant child corners are culled from the set. Corner B is a redundant child of Corner A if every property present in B is also present in A.
The motivations for having a set of property bit fields, and culling the redundant child corners: 1) We need a set of property bit fields when a combination of properties in a single element is important to distinguish from multiple elements with those properties in isolation e.g. it is important to know whether we have (A) [(a not-used-in-game hard dependency) AND (a used-in-game soft dependency)] vs (B) [(a used-in-game hard dependency)] 2) We need to cull redundant child corners for performance, if we are allowed to. Minimizing the number of property combinations necessary to iterate over is important for performance of any calling iteration code We are allowed to eliminate redundant child corners when each property is an increasing superset - the behavior when the property is present is a superset of the behavior when the property is not present e.g. When we have a hard dependency, that means everything that having a soft dependency means, PLUS some other behavior that is specific to the hard-ness of the dependency
Note that adding elements (aka bitfields aka corners) to a TPropertyCombinationSet is not reversible; we lose information about what the original corners were when we remove redundant corners after the add
For the generic template implementation of TPropertyCombinationSet, it remains an unsolved problem for how to enumerate all possible sets non-redundant corners in this general case We therefore fall back to a less-optimal case where each corner gets assigned to a bit, and dynamically check for redundant corners whenever adding to the set More optimal (fewer bits required) instantiations for specific bitwidths with manual solutions are defined below the generic implementation.