All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.wildfly.common.flags.Flags Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2018 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.wildfly.common.flags;

import static java.lang.Integer.bitCount;
import static java.lang.Integer.highestOneBit;
import static java.lang.Integer.lowestOneBit;
import static java.lang.Integer.numberOfTrailingZeros;

import java.util.AbstractSet;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
import java.util.function.Consumer;

import org.wildfly.common.Assert;

/**
 * A base class for implementing value-like flags and flag sets, where flags and flag sets may be used without allocation
 * overhead.
 * 

*/ public abstract class Flags, This extends Flags> extends AbstractSet implements SortedSet { final int bits; /** * Construct a new instance. This constructor should only be called during initial array construction. * * @param bits the bits of this set */ protected Flags(final int bits) { this.bits = bits; } /** * Get the set value of the given bit combination. The bit combination may contain extraneous one-bits so * any bits beyond the bit of the last flag should be masked off if an array is used for lookup. * * @param bits the bit combination (possibly with extra bits) * @return the set instance */ protected abstract This value(int bits); /** * Return {@code this}. * * @return {@code this} */ protected abstract This this_(); /** * Get the flag item with the given index. * * @param index the index * @return the flag */ protected abstract E itemOf(int index); /** * Get the item (cast to the correct {@code enum} type), or {@code null} if it is not of the correct type. * * @param obj the object to cast * @return the cast object, or {@code null} */ protected abstract E castItemOrNull(Object obj); /** * Cast the given object to this class, throwing an exception if the cast fails. * * @param obj the object to cast * @return the cast object */ protected abstract This castThis(Object obj); /** * Get the size of the flag set. * * @return the flag set size */ public final int size() { return bitCount(bits); } /** * Get the first flag in the set. * * @return the first flag */ public final E first() { final int bits = this.bits; if (bits == 0) throw new NoSuchElementException(); return itemOf(numberOfTrailingZeros(lowestOneBit(bits))); } /** * Get the last flag in the set. * * @return the last flag */ public final E last() { final int bits = this.bits; if (bits == 0) throw new NoSuchElementException(); return itemOf(numberOfTrailingZeros(highestOneBit(bits))); } /** * Get the {@code null} comparator, indicating that this set is always sorted in natural order. * * @return {@code null} */ public final Comparator comparator() { return null; } /** * Determine if this flag set is empty. * * @return {@code true} if the flag set is empty, {@code false} otherwise */ public boolean isEmpty() { return bits == 0; } /** * Get the subset of flags from this set, up to (but not including) the given element. * * @param toElement the "to" element (must not be {@code null}) * @return the subset */ public final This headSet(final E toElement) { Assert.checkNotNullParam("toElement", toElement); return value(bits & bitOf(toElement) - 1); } /** * Get the subset of flags from this set, starting from the given element. * * @param fromElement the "from" element (must not be {@code null}) * @return the subset */ public final This tailSet(final E fromElement) { Assert.checkNotNullParam("fromElement", fromElement); return value(bits & ~(bitOf(fromElement) - 1)); } /** * Get the subset of flags, starting from {@code fromElement} up to (but not including) {@code toElement}. * * @param fromElement the "from" element (must not be {@code null}) * @param toElement the "to" element (must not be {@code null}) * @return the subset */ public final This subSet(final E fromElement, final E toElement) { Assert.checkNotNullParam("fromElement", fromElement); Assert.checkNotNullParam("toElement", toElement); return value(bits & (bitOf(toElement) - 1) & ~(bitOf(fromElement) - 1)); } /** * Get an {@code Object} array containing all the flag values of this set. * * @return the {@code Object} array */ public final Object[] toArray() { int b = bits; final Object[] array = new Object[bitCount(b)]; int idx = 0; while (bitCount(b) > 0) { final int lob = lowestOneBit(b); array[idx + 1] = itemOf(numberOfTrailingZeros(lob)); b ^= lob; } return array; } /** * Get a typed array containing all the flag values of this set. * * @param array the array to populate or clone * @param the element type * @return the populated array */ @SuppressWarnings("unchecked") public final T[] toArray(T[] array) { int b = bits; final int size = bitCount(b); if (size > array.length) { array = Arrays.copyOf(array, size); } int idx = 0; while (bitCount(b) > 0) { final int lob = lowestOneBit(b); array[idx + 1] = (T) itemOf(numberOfTrailingZeros(lob)); b ^= lob; } return array; } /** * Determine if this flag set contains the given flag. * * @param flag the flag * @return {@code true} if the flag is contained by this set */ public final boolean contains(E flag) { return flag != null && (bits & bitOf(flag)) != 0; } /** * Determine if this flag set contains the given object. * * @param o the object * @return {@code true} if the object is contained by this set */ public final boolean contains(final Object o) { return contains(castItemOrNull(o)); } /** * Determine if this flag set contains all of the objects in the given collection. * * @param c the collection * @return {@code true} if all of the collection's objects are contained by this set */ public final boolean containsAll(final Collection c) { if (c.getClass() == getClass()) { return containsAll(castThis(c)); } else { for (Object o : c) { if (! contains(o)) return false; } return true; } } /** * Determine if this flag set contains all of the flags in the given flag set. * * @param other the flag set * @return {@code true} if all of the given set's flags are contained by this set */ public final boolean containsAll(This other) { final int otherBits = other.bits; return (this.bits & otherBits) == otherBits; } /** * Determine if this flag set contains all of the given flags. * * @param flag1 the first flag * @param flag2 the second flag * @return {@code true} if all of the given flags are contained by this set */ public final boolean containsAll(E flag1, E flag2) { return contains(flag1) && contains(flag2); } /** * Determine if this flag set contains all of the given flags. * * @param flag1 the first flag * @param flag2 the second flag * @param flag3 the third flag * @return {@code true} if all of the given flags are contained by this set */ public final boolean containsAll(E flag1, E flag2, E flag3) { return containsAll(flag1, flag2) && contains(flag3); } /** * Determine if this flag set contains any of the flags in the given flag set. * * @param other the flag set * @return {@code true} if all of the given set's flags are contained by this set */ public final boolean containsAny(This other) { return other != null && (bits & other.bits) != 0; } /** * Determine if this flag set contains any of the given flags. * * @param flag1 the first flag * @param flag2 the second flag * @return {@code true} if any of the given flags are contained by this set */ public final boolean containsAny(E flag1, E flag2) { return contains(flag1) || contains(flag2); } /** * Determine if this flag set contains any of the given flags. * * @param flag1 the first flag * @param flag2 the second flag * @param flag3 the third flag * @return {@code true} if any of the given flags are contained by this set */ public final boolean containsAny(E flag1, E flag2, E flag3) { return containsAny(flag1, flag2) || contains(flag3); } /** * Get the complement of this set. * * @return the complement of this set */ public final This complement() { return value(~bits); } /** * Return a set which includes all of the flags in this set and the given additional flag. * * @param flag the additional flag * @return the combined set */ public final This with(E flag) { return flag == null ? this_() : value(bits | bitOf(flag)); } /** * Return a set which includes all of the flags in this set and the given additional flags. * * @param flag1 the first flag * @param flag2 the second flag * @return the combined set */ public final This with(E flag1, E flag2) { return with(flag1).with(flag2); } /** * Return a set which includes all of the flags in this set and the given additional flags. * * @param flag1 the first flag * @param flag2 the second flag * @param flag3 the third flag * @return the combined set */ public final This with(E flag1, E flag2, E flag3) { return with(flag1, flag2).with(flag3); } /** * Return a set which includes all of the flags in this set and the given additional flags. * * @param flags the additional flags * @return the combined set */ @SafeVarargs public final This with(E... flags) { if (flags == null) return this_(); int b = bits; for (E flag : flags) { if (flag != null) b |= bitOf(flag); } return value(b); } /** * Return a set which includes all of the flags in this set and the given additional flags. * * @param other the additional flags * @return the combined set */ public final This with(This other) { return other == null ? this_() : value(bits | other.bits); } /** * Return a set which includes all of the flags except for the given flag. * * @param flag the flag * @return the reduced set */ public final This without(E flag) { return flag == null ? this_() : value(bits & ~bitOf(flag)); } /** * Return a set which includes all of the flags except for the given flags. * * @param other the flags * @return the reduced set */ public final This without(This other) { return other == null ? this_() : value(bits & ~other.bits); } /** * Determine if this flag set is equal to the given object. * * @param o the other object * @return {@code true} if the object is equal to this set, {@code false} otherwise */ public final boolean equals(final Object o) { return o == this || o instanceof Set && equals((Set) o); } /** * Determine if this flag set is equal to the given set. * * @param o the other set * @return {@code true} if the set is equal to this set, {@code false} otherwise */ public final boolean equals(final Set o) { return o == this || o.containsAll(this) && containsAll(o); } /** * Determine if this flag set is equal to the given flag set. * * @param o the other flag set * @return {@code true} if the flag set is equal to this set, {@code false} otherwise */ public final boolean equals(final This o) { return o == this; } /** * Get the hash code of this flag set. * * @return the flag set hash code */ public final int hashCode() { int hc = 0; int b = this.bits; while (b != 0) { int lob = lowestOneBit(b); hc += itemOf(numberOfTrailingZeros(lob)).hashCode(); b ^= lob; } return hc; } /** * Iterate this set in order from first to last flag. * * @return the iterator */ public final Iterator iterator() { return new Iterator() { int b = bits; public boolean hasNext() { return b != 0; } public E next() { int b = this.b; if (b == 0) throw new NoSuchElementException(); final int lob = lowestOneBit(b); final E item = itemOf(numberOfTrailingZeros(lob)); this.b = b ^ lob; return item; } }; } /** * Iterate this set in order from last to first flag. * * @return the iterator */ public final Iterator descendingIterator() { return new Iterator() { int b = bits; public boolean hasNext() { return b != 0; } public E next() { int b = this.b; if (b == 0) throw new NoSuchElementException(); final int hob = highestOneBit(b); final E item = itemOf(numberOfTrailingZeros(hob)); this.b = b ^ hob; return item; } }; } /** * Apply the given action for every flag in this set. * * @param action the action to apply */ public void forEach(final Consumer action) { Assert.checkNotNullParam("action", action); int b = this.bits; while (b != 0) { int lob = lowestOneBit(b); action.accept(itemOf(numberOfTrailingZeros(lob))); b = b ^ lob; } } /** * Get a string representation of this flag set. * * @return the string representation */ public final String toString() { StringBuilder buf = new StringBuilder(); buf.append(getClass().getSimpleName()).append('['); int lob; int bits = this.bits; if (bits != 0) { lob = lowestOneBit(bits); buf.append(itemOf(numberOfTrailingZeros(lob))); bits ^= lob; while (bits != 0) { buf.append(' '); lob = lowestOneBit(bits); buf.append(itemOf(numberOfTrailingZeros(lob))); bits ^= lob; } } buf.append(']'); return buf.toString(); } private static int bitOf(Enum item) { return 1 << item.ordinal(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy