EnumTools.java
package eu.javaexperience.collection.enumerations;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import eu.javaexperience.collection.CollectionTools;
import eu.javaexperience.collection.list.NullList;
import eu.javaexperience.interfaces.simple.getBy.GetBy1;
import eu.javaexperience.reflect.CastTo;
public class EnumTools
{
public static <E extends Enum<?>> boolean isSet(int num, E elem)
{
int bit = 0x1 << elem.ordinal();
return (num & bit) == bit;
}
public static <E extends Enum<?>> boolean isSet(int num, int check)
{
return (num & check) == check;
}
public static <E extends Enum<?>> boolean isAllSet(int num, E... elems)
{
int bit = 0;
for(E e:elems)
{
bit |= 0x1 << e.ordinal();
}
return (num & bit) == bit;
}
public static <E extends Enum<?>> int setBit(int num, E elem)
{
return num | 0x1 << elem.ordinal();
}
public static <E extends Enum<?>> int resetBit(int num, E elem)
{
return num & ~(0x1 << elem.ordinal());
}
public static <E extends Enum<?>> int setBitValue(int num, E elem, boolean set)
{
if(set)
{
return setBit(num, elem);
}
else
{
return resetBit(num, elem);
}
}
public static <E extends Enum<?>> E getRandomEnum(Class<E> cls)
{
E[] es = cls.getEnumConstants();
return es[(int)(Math.random()*es.length-1)];
}
public static <E extends Enum<?>> int assembleLeastOne(E elem, E... values)
{
int ret = 0x1 << elem.ordinal();
for(E i:values)
{
ret |= 1 << i.ordinal();
}
return ret;
}
public static <E extends Enum<?>> int assemble(E... values)
{
int ret = 0x0;
for(E i:values)
{
ret |= 1 << i.ordinal();
}
return ret;
}
public static <E extends Enum<E>> String[] getNames(Class<E> cls)
{
Enum[] e = cls.getEnumConstants();
String[] ret = new String[e.length];
for(int i=0;i<e.length;++i)
{
ret[i] = e[i].name();
}
return ret;
}
public static <E extends Enum<E>> void getNames(Collection<String> dst, Class<E> cls)
{
for(Enum e:cls.getEnumConstants())
{
dst.add(e.name());
}
}
public static <E extends Enum<E>> Enum<E> getByName(Class<E> cls, String str)
{
E[] ret = cls.getEnumConstants();
if(null != ret)
{
for(E e:ret)
{
if(e.name().equals(str))
{
return e;
}
}
}
return null;
}
public static final SimpleFixedEnumManager EMPTY_ENUM_MANAGER = new SimpleFixedEnumManager<>(NullList.instance);
public static <E extends Enum<E>, L extends EnumLike<L>> EnumManager<L> createFromEnumClass(final Class<E> cls)
{
List<L> values = new ArrayList<>();
final HashMap<String, L> byName = new HashMap<>();
final EnumManager<L>[] BIND_LATER = new EnumManager[1];
for(E val:cls.getEnumConstants())
{
final E c = val;
EnumLike<L> instance = new EnumLike<L>()
{
@Override
public boolean isRegistered()
{
return true;
}
@Override
public String getName()
{
return c.name();
}
@Override
public int getOrdinal()
{
return c.ordinal();
}
@Override
public EnumManager<L> getEnumManager()
{
return BIND_LATER[0];
}
@Override
public void setEnumManager(EnumManager<L> mngr)
{
throw new UnsupportedOperationException();
}
@Override
public void setOrdinal(int oridinal)
{
throw new UnsupportedOperationException();
}
};
byName.put(val.name(), (L) instance);
values.add((L) instance);
}
final List<L> cnst = Collections.unmodifiableList(values);
return new EnumManager<L>()
{
{
BIND_LATER[0] = this;
}
@Override
public Iterator<L> iterator()
{
return cnst.iterator();
}
@Override
public void registerElement(L elem)
{
throw new UnsupportedOperationException();
}
@Override
public L getByOrdinal(int ord)
{
return cnst.get(ord);
}
@Override
public L getByName(String name)
{
return byName.get(name);
}
@Override
public Object[] getValues()
{
return cnst.toArray();
}
@Override
public L[] getValues(L[] arr)
{
return cnst.toArray(arr);
}
@Override
public List<L> getValueList()
{
return cnst;
}
@Override
public String toString()
{
return "EnumManager for enum class: "+cls;
}
};
}
public static <E extends EnumLike<E>>/*<E extends Enum<E> & EnumLike<E>>*/ EnumManager<E> createFromCompatibleEnumClass(final Class<E> cls)
{
return new SimpleFixedEnumManager<E>(CollectionTools.inlineAdd(new ArrayList<E>(), cls.getEnumConstants()));
}
public static <E extends EnumLike<E>> EnumManager<E> createFromEnumLikes(E... elems)
{
SimpleEnumManager<E> ret = new SimpleEnumManager<E>();
for(E e:elems)
{
ret.registerElement(e);
}
return ret;
}
public static <C> C recogniseSymbol(Class<C> enumClass, Object ident)
{
if(null == ident)
{
return null;
}
Integer NUM = (Integer) CastTo.Int.cast(ident);
int id = -1;
if(null != NUM)
{
id = NUM;
}
String str = (String) CastTo.String.cast(ident);
for(Object o:enumClass.getEnumConstants())
{
Enum ee = (Enum) o;
if(id == ee.ordinal() || str.equals(ee.name()))
{
return (C) ee;
}
}
return null;
}
public static <E extends Enum> void recogniseSymbols
(
Class<E> enumClass,
Collection<String> keys,
Collection<E> dst
)
{
for(String s:keys)
{
E val = recogniseSymbol(enumClass, s);
if(null != val)
{
dst.add(val);
}
}
}
public static <T extends Enum<T>> GetBy1<T, Object> createParserFunction(final Class<T> enumClass)
{
return new GetBy1<T, Object>()
{
@Override
public T getBy(Object a)
{
return recogniseSymbol(enumClass, a);
}
};
}
public static <E extends Enum, M extends Map<String, E>> M mapByName(M dst, Class<E> enum_)
{
for(E e:enum_.getEnumConstants())
{
dst.put(e.name(), e);
}
return dst;
}
/**
* ret:
* len = (enum).values().length
*
* len > 64
* {@link BigInteger}
* len > 32
* {@link long}
* else
* {@link int}
* */
public static <T extends Enum<T>> Number enumSetBits(Class<T> cls, EnumSet<T> enumSet)
{
Enum[] vals = cls.getEnumConstants();
if(vals.length > 64)
{
BigInteger in = BigInteger.ZERO;
for(Enum e:enumSet)
in = in.setBit(e.ordinal());
return in;
}
if(vals.length > 32)
{
long ret = 0x0;
for(Enum e:enumSet)
ret |= 1 << e.ordinal();
return ret;
}
int ret = 0x0;
for(Enum e:enumSet)
ret |= 1 << e.ordinal();
return ret;
}
public static <T extends Enum<T>> EnumSet<T> enumSetBits(Class<T> cls,Number num)
{
EnumSet<T> ret = EnumSet.noneOf(cls);
T[] vals = cls.getEnumConstants();
if(num instanceof BigInteger)
{
BigInteger in = (BigInteger) num;
for(T e:vals)
if(in.testBit(e.ordinal()))
ret.add(e);
return ret;
}
long val = num.longValue();
for(T e:vals)
if((val & (1L << e.ordinal())) != 0)
ret.add(e);
return ret;
}
}