/** * Finds the index of a trait of a given type in this set. * * @param traitDef Sought trait definition * @return index of trait, or -1 if not found */ private int findIndex(RelTraitDef traitDef) { for (int i = 0; i < traits.length; i++) { RelTrait trait = traits[i]; if ((trait != null) && (trait.getTraitDef() == traitDef)) { return i; } } return -1; }
/** * Returns a trait set consisting of the current set plus a new trait. * * <p>If the set does not contain a trait of the same {@link RelTraitDef}, the trait is ignored, * and this trait set is returned. * * @param trait the new trait * @return New set * @see #plus(RelTrait) */ public RelTraitSet replace(RelTrait trait) { final RelTraitDef traitDef = trait.getTraitDef(); int index = findIndex(traitDef); if (index < 0) { // Trait is not present. Ignore it. return this; } return replace(index, trait); }
/** * Replaces an existing RelTrait in the set. Returns a different trait set; does not modify this * trait set. * * @param index 0-based index into ordered RelTraitSet * @param trait the new RelTrait * @return the old RelTrait at the index */ public RelTraitSet replace(int index, RelTrait trait) { assert traits[index].getTraitDef() == trait.getTraitDef() : "RelTrait has different RelTraitDef than replacement"; RelTrait canonizedTrait = canonize(trait); if (traits[index] == canonizedTrait) { return this; } RelTrait[] newTraits = traits.clone(); newTraits[index] = canonizedTrait; return cache.getOrAdd(new RelTraitSet(cache, newTraits)); }
/** * Returns this trait set with a given trait added or overridden. Does not modify this trait set. * * @param trait Trait * @return Trait set with given trait */ public RelTraitSet plus(RelTrait trait) { if (contains(trait)) { return this; } int i = findIndex(trait.getTraitDef()); if (i >= 0) { return replace(i, trait); } final RelTrait canonizedTrait = canonize(trait); RelTrait[] newTraits = Arrays.copyOf(traits, traits.length + 1); newTraits[newTraits.length - 1] = canonizedTrait; return cache.getOrAdd(new RelTraitSet(cache, newTraits)); }
/** * Returns whether this trait set contains the given trait, or whether the trait is not present * because its {@link RelTraitDef} is not enabled. Returns false if another trait of the same * {@code RelTraitDef} is present. * * @param trait Trait * @return Whether trait is present, or is absent because disabled */ public boolean containsIfApplicable(RelTrait trait) { // Note that '==' is sufficient, because trait should be canonized. final RelTrait trait1 = getTrait(trait.getTraitDef()); return trait1 == null || trait1 == trait; }