Files
Primitive-Collections/src/builder/resources/speiger/assets/collections/templates/utils/Sets.template
T
Speiger c4964806f0 Loads of new features & fixes.
- Added: pour function directly into Iterable which allows to collect
all elements in the Iterable directly.
- Added: The new ToArray method from Java9 and newer into the library.
Using a functional interface. (Just a backport)
- Changed: Reworked how the Map Builder functions are created. They are
now in a SubClass that moves them out of the way. Less Clutter. (This
might break things if that was used before)
- Added: Map Builder that allows now to Build Maps like Guava
ImmutableMaps can be build. Note: This has a slight performance
overhead.
- Added: Unmodifiable and Synchronize wrapper functions direclty into
Collection Interfaces. This is mostly a quality of life thing.
- Added: Unmodifiable and Synchronized Wrapper Collections can now be
cloned. They clone the underlying map which doesn't break functionality.
(Had a usecase for it)
- Added: A boxed putAll array variant.
- Fixed: EnumMaps didn't keep track of their size and now got proper
care and implementations as needed. There might be more work required
but at least the core functionality is now up to date.
2021-12-09 09:14:55 +01:00

583 lines
20 KiB
Plaintext

package speiger.src.collections.PACKAGE.utils;
#if TYPE_BOOLEAN
import speiger.src.collections.booleans.collections.BooleanIterator;
import speiger.src.collections.booleans.sets.AbstractBooleanSet;
import speiger.src.collections.booleans.sets.BooleanSet;
import speiger.src.collections.booleans.utils.BooleanCollections.EmptyCollection;
#else
#if TYPE_OBJECT
import java.util.Comparator;
#endif
import speiger.src.collections.PACKAGE.collections.BI_ITERATOR;
#if !TYPE_OBJECT
import speiger.src.collections.PACKAGE.functions.COMPARATOR;
#endif
import speiger.src.collections.PACKAGE.collections.ITERATOR;
import speiger.src.collections.PACKAGE.sets.NAVIGABLE_SET;
import speiger.src.collections.PACKAGE.sets.ABSTRACT_SET;
import speiger.src.collections.PACKAGE.sets.SET;
import speiger.src.collections.PACKAGE.sets.SORTED_SET;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.EmptyCollection;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.SynchronizedCollection;
import speiger.src.collections.PACKAGE.utils.COLLECTIONS.UnmodifiableCollection;
import speiger.src.collections.utils.ITrimmable;
#endif
/**
* A Helper class for sets
*/
public class SETS
{
/**
* Empty Set Variable
*/
public static final SET NO_GENERIC_TYPE EMPTY = new EmptySetBRACES();
/**
* EmptySet getter
* @Type(T)
* @return a EmptySet
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE empty() {
#if TYPE_OBJECT
return (SET<KEY_TYPE>)EMPTY;
#else
return EMPTY;
#endif
}
#if !TYPE_BOOLEAN
/**
* Creates a Synchronized set while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @Type(T)
* @return a set that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE synchronize(SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s) : new SynchronizedSetBRACES(s));
}
/**
* Creates a Synchronized set while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @param mutex controller for access
* @Type(T)
* @return a set that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE synchronize(SET KEY_GENERIC_TYPE s, Object mutex) {
return s instanceof SynchronizedSet ? s : (s instanceof ITrimmable ? new SynchronizedTrimSetBRACES(s, mutex) : new SynchronizedSetBRACES(s, mutex));
}
/**
* Creates a Synchronized SortedSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @Type(T)
* @return a SortedSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE synchronize(SORTED_SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s) : new SynchronizedSortedSetBRACES(s));
}
/**
* Creates a Synchronized SortedSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @param mutex controller for access
* @Type(T)
* @return a SortedSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE synchronize(SORTED_SET KEY_GENERIC_TYPE s, Object mutex) {
return s instanceof SynchronizedSortedSet ? s : (s instanceof ITrimmable ? new SynchronizedSortedTrimSetBRACES(s, mutex) : new SynchronizedSortedSetBRACES(s, mutex));
}
/**
* Creates a Synchronized NavigableSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @Type(T)
* @return a NavigableSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE synchronize(NAVIGABLE_SET KEY_GENERIC_TYPE s) {
return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s) : new SynchronizedNavigableSetBRACES(s));
}
/**
* Creates a Synchronized NavigableSet while preserving the ITrimmable interface
* @param s the set that should be synchronized
* @param mutex controller for access
* @Type(T)
* @return a NavigableSet that is synchronized
* @note if the set is already synchronized then it will just self return it
*/
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE synchronize(NAVIGABLE_SET KEY_GENERIC_TYPE s, Object mutex) {
return s instanceof SynchronizedNavigableSet ? s : (s instanceof ITrimmable ? new SynchronizedNavigableTrimSetBRACES(s, mutex) : new SynchronizedNavigableSetBRACES(s, mutex));
}
/**
* Creates Unmodifyable Set wrapper
* @param s set that should be made unmodifiable
* @Type(T)
* @return a UnmodifyableSet, if the set is already unmodifiable then it returns itself
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE unmodifiable(SET KEY_GENERIC_TYPE s) {
return s instanceof UnmodifiableSet ? s : new UnmodifiableSetBRACES(s);
}
/**
* Creates Unmodifyable SortedSet wrapper
* @param s sortedSet that should be made unmodifiable
* @Type(T)
* @return a UnmodifyableSortedSet, if the set is already unmodifiable then it returns itself
*/
public static GENERIC_KEY_BRACES SORTED_SET KEY_GENERIC_TYPE unmodifiable(SORTED_SET KEY_GENERIC_TYPE s) {
return s instanceof UnmodifiableSortedSet ? s : new UnmodifiableSortedSetBRACES(s);
}
/**
* Creates Unmodifyable NavigableSet wrapper
* @param s navigableSet that should be made unmodifiable
* @Type(T)
* @return a UnmodifyableNavigableSet, if the set is already unmodifiable then it returns itself
*/
public static GENERIC_KEY_BRACES NAVIGABLE_SET KEY_GENERIC_TYPE unmodifiable(NAVIGABLE_SET KEY_GENERIC_TYPE s) {
return s instanceof UnmodifiableNavigableSet ? s : new UnmodifiableNavigableSetBRACES(s);
}
#endif
/**
* Creates a Singleton set of a given element
* @param element the element that should be converted into a singleton set
* @Type(T)
* @return a singletonset of the given element
*/
public static GENERIC_KEY_BRACES SET KEY_GENERIC_TYPE singleton(KEY_TYPE element) {
return new SingletonSetBRACES(element);
}
private static class SingletonSet KEY_GENERIC_TYPE extends ABSTRACT_SET KEY_GENERIC_TYPE
{
KEY_TYPE element;
SingletonSet(KEY_TYPE element) {
this.element = element;
}
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
@Override
public boolean add(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public ITERATOR KEY_GENERIC_TYPE iterator()
{
return new ITERATOR KEY_GENERIC_TYPE() {
boolean next = true;
@Override
public boolean hasNext() { return next = false; }
@Override
public KEY_TYPE NEXT() {
if(!next) throw new IllegalStateException();
next = false;
return element;
}
};
}
@Override
public int size() { return 1; }
@Override
public SingletonSet KEY_GENERIC_TYPE copy() { return new SingletonSetBRACES(element); }
}
private static class EmptySet KEY_GENERIC_TYPE extends EmptyCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
@Override
public EmptySet KEY_GENERIC_TYPE copy() { return this; }
}
#if !TYPE_BOOLEAN
private static class UnmodifiableNavigableSet KEY_GENERIC_TYPE extends UnmodifiableSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{
NAVIGABLE_SET KEY_GENERIC_TYPE n;
UnmodifiableNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c);
n = c;
}
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) { return n.contains(o); }
#endif
@Override
@Deprecated
public boolean contains(Object o) { return n.contains(o); }
@Override
public KEY_TYPE lower(KEY_TYPE e) { return n.lower(e); }
@Override
public KEY_TYPE floor(KEY_TYPE e) { return n.floor(e); }
@Override
public KEY_TYPE ceiling(KEY_TYPE e) { return n.ceiling(e); }
@Override
public KEY_TYPE higher(KEY_TYPE e) { return n.higher(e); }
#if !TYPE_OBJECT
@Override
public void setDefaultMaxValue(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE getDefaultMaxValue() { return n.getDefaultMaxValue(); }
@Override
public void setDefaultMinValue(KEY_TYPE e) { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE getDefaultMinValue() { return n.getDefaultMinValue(); }
#endif
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE copy() { throw new UnsupportedOperationException(); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { return SETS.unmodifiable(n.subSet(fromElement, fromInclusive, toElement, toInclusive)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) { return SETS.unmodifiable(n.headSet(toElement, inclusive)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) { return SETS.unmodifiable(n.tailSet(fromElement, inclusive)); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { return ITERATORS.unmodifiable(n.descendingIterator()); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() { return SETS.unmodifiable(n.descendingSet()); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return SETS.unmodifiable(n.subSet(fromElement, toElement)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return SETS.unmodifiable(n.headSet(toElement)); }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return SETS.unmodifiable(n.tailSet(fromElement)); }
}
private static class UnmodifiableSortedSet KEY_GENERIC_TYPE extends UnmodifiableSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{
SORTED_SET KEY_GENERIC_TYPE s;
UnmodifiableSortedSet(SORTED_SET KEY_GENERIC_TYPE c)
{
super(c);
s = c;
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToFirst(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public boolean moveToLast(KEY_TYPE o) { throw new UnsupportedOperationException(); }
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator() { return s.comparator(); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { return ITERATORS.unmodifiable(s.iterator()); }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { return ITERATORS.unmodifiable(s.iterator(fromElement)); }
@Override
public SORTED_SET KEY_GENERIC_TYPE copy() { return s.copy(); }
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { return SETS.unmodifiable(s.subSet(fromElement, toElement)); }
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { return SETS.unmodifiable(s.headSet(toElement)); }
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { return SETS.unmodifiable(s.tailSet(fromElement)); }
@Override
public KEY_TYPE FIRST_KEY() { return s.FIRST_KEY(); }
@Override
public KEY_TYPE POLL_FIRST_KEY() { throw new UnsupportedOperationException(); }
@Override
public KEY_TYPE LAST_KEY() { return s.LAST_KEY(); }
@Override
public KEY_TYPE POLL_LAST_KEY() { throw new UnsupportedOperationException(); }
}
/**
* Unmodifyable Set wrapper that helps is used with unmodifyableSet function
* @Type(T)
*/
public static class UnmodifiableSet KEY_GENERIC_TYPE extends UnmodifiableCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{
SET KEY_GENERIC_TYPE s;
protected UnmodifiableSet(SET KEY_GENERIC_TYPE c)
{
super(c);
s = c;
}
@Override
public SET KEY_GENERIC_TYPE copy() { return s.copy(); }
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) { throw new UnsupportedOperationException(); }
#endif
}
private static class SynchronizedNavigableTrimSet KEY_GENERIC_TYPE extends SynchronizedNavigableSet KEY_GENERIC_TYPE implements ITrimmable
{
ITrimmable trim;
SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c);
trim = (ITrimmable)c;
}
SynchronizedNavigableTrimSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
trim = (ITrimmable)c;
}
@Override
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } }
@Override
public void clearAndTrim(int size) { synchronized(mutex) { trim.clearAndTrim(size); } }
}
private static class SynchronizedNavigableSet KEY_GENERIC_TYPE extends SynchronizedSortedSet KEY_GENERIC_TYPE implements NAVIGABLE_SET KEY_GENERIC_TYPE
{
NAVIGABLE_SET KEY_GENERIC_TYPE n;
SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c) {
super(c);
n = c;
}
SynchronizedNavigableSet(NAVIGABLE_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
n = c;
}
@Override
@Deprecated
public boolean contains(Object o) { synchronized(mutex) { return n.contains(o); } }
#if !TYPE_OBJECT
@Override
public boolean contains(KEY_TYPE o) { synchronized(mutex) { return n.contains(o); } }
#endif
@Override
public KEY_TYPE lower(KEY_TYPE e) { synchronized(mutex) { return n.lower(e); } }
@Override
public KEY_TYPE floor(KEY_TYPE e) { synchronized(mutex) { return n.floor(e); } }
@Override
public KEY_TYPE ceiling(KEY_TYPE e) { synchronized(mutex) { return n.ceiling(e); } }
@Override
public KEY_TYPE higher(KEY_TYPE e) { synchronized(mutex) { return n.higher(e); } }
#if !TYPE_OBJECT
@Override
public void setDefaultMaxValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMaxValue(e); } }
@Override
public KEY_TYPE getDefaultMaxValue() { synchronized(mutex) { return n.getDefaultMaxValue(); } }
@Override
public void setDefaultMinValue(KEY_TYPE e) { synchronized(mutex) { n.setDefaultMinValue(e); } }
@Override
public KEY_TYPE getDefaultMinValue() { synchronized(mutex) { return n.getDefaultMinValue(); } }
#endif
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE copy() { synchronized(mutex) { return n.copy(); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, boolean fromInclusive, KEY_TYPE toElement, boolean toInclusive) { synchronized(mutex) { return SETS.synchronize(n.subSet(fromElement, fromInclusive, toElement, toInclusive), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement, boolean inclusive) { synchronized(mutex) { return SETS.synchronize(n.headSet(toElement, inclusive), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement, boolean inclusive) { synchronized(mutex) { return SETS.synchronize(n.tailSet(fromElement, inclusive), mutex); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE descendingIterator() { synchronized(mutex) { return n.descendingIterator(); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE descendingSet() { synchronized(mutex) { return SETS.synchronize(n.descendingSet(), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { synchronized(mutex) { return SETS.synchronize(n.subSet(fromElement, toElement), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { synchronized(mutex) { return SETS.synchronize(n.headSet(toElement), mutex); } }
@Override
public NAVIGABLE_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { synchronized(mutex) { return SETS.synchronize(n.tailSet(fromElement), mutex); } }
}
private static class SynchronizedSortedTrimSet KEY_GENERIC_TYPE extends SynchronizedSortedSet KEY_GENERIC_TYPE implements ITrimmable
{
ITrimmable trim;
SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c) {
super(c);
trim = (ITrimmable)c;
}
SynchronizedSortedTrimSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
trim = (ITrimmable)c;
}
@Override
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } }
@Override
public void clearAndTrim(int size) { synchronized(mutex) { trim.clearAndTrim(size); } }
}
private static class SynchronizedSortedSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements SORTED_SET KEY_GENERIC_TYPE
{
SORTED_SET KEY_GENERIC_TYPE s;
SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c) {
super(c);
s = c;
}
SynchronizedSortedSet(SORTED_SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
s = c;
}
@Override
public boolean addAndMoveToFirst(KEY_TYPE o) { synchronized(mutex) { return s.addAndMoveToFirst(o); } }
@Override
public boolean addAndMoveToLast(KEY_TYPE o) { synchronized(mutex) { return s.addAndMoveToLast(o); } }
@Override
public boolean moveToFirst(KEY_TYPE o) { synchronized(mutex) { return s.moveToFirst(o); } }
@Override
public boolean moveToLast(KEY_TYPE o) { synchronized(mutex) { return s.moveToLast(o); } }
@Override
public COMPARATOR KEY_GENERIC_TYPE comparator(){ synchronized(mutex) { return s.comparator(); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator() { synchronized(mutex) { return s.iterator(); } }
@Override
public BI_ITERATOR KEY_GENERIC_TYPE iterator(KEY_TYPE fromElement) { synchronized(mutex) { return s.iterator(fromElement); } }
@Override
public SORTED_SET KEY_GENERIC_TYPE copy() { synchronized(mutex) { return s.copy(); } }
@Override
public SORTED_SET KEY_GENERIC_TYPE subSet(KEY_TYPE fromElement, KEY_TYPE toElement) { synchronized(mutex) { return SETS.synchronize(s.subSet(fromElement, toElement), mutex); } }
@Override
public SORTED_SET KEY_GENERIC_TYPE headSet(KEY_TYPE toElement) { synchronized(mutex) { return SETS.synchronize(s.headSet(toElement), mutex); } }
@Override
public SORTED_SET KEY_GENERIC_TYPE tailSet(KEY_TYPE fromElement) { synchronized(mutex) { return SETS.synchronize(s.tailSet(fromElement), mutex); } }
@Override
public KEY_TYPE FIRST_KEY() { synchronized(mutex) { return s.FIRST_KEY(); } }
@Override
public KEY_TYPE POLL_FIRST_KEY() { synchronized(mutex) { return s.POLL_FIRST_KEY(); } }
@Override
public KEY_TYPE LAST_KEY() { synchronized(mutex) { return s.LAST_KEY(); } }
@Override
public KEY_TYPE POLL_LAST_KEY() { synchronized(mutex) { return s.POLL_LAST_KEY(); } }
}
private static class SynchronizedTrimSet KEY_GENERIC_TYPE extends SynchronizedSet KEY_GENERIC_TYPE implements ITrimmable
{
ITrimmable trim;
SynchronizedTrimSet(SET KEY_GENERIC_TYPE c) {
super(c);
trim = (ITrimmable)c;
}
SynchronizedTrimSet(SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
trim = (ITrimmable)c;
}
@Override
public boolean trim(int size) { synchronized(mutex) { return trim.trim(size); } }
@Override
public void clearAndTrim(int size) { synchronized(mutex) { trim.clearAndTrim(size); } }
}
private static class SynchronizedSet KEY_GENERIC_TYPE extends SynchronizedCollection KEY_GENERIC_TYPE implements SET KEY_GENERIC_TYPE
{
SET KEY_GENERIC_TYPE s;
SynchronizedSet(SET KEY_GENERIC_TYPE c) {
super(c);
s = c;
}
SynchronizedSet(SET KEY_GENERIC_TYPE c, Object mutex) {
super(c, mutex);
s = c;
}
@Override
public SET KEY_GENERIC_TYPE copy() { synchronized(mutex) { return s.copy(); } }
#if !TYPE_OBJECT
@Override
public boolean remove(KEY_TYPE o) { synchronized(mutex) { return s.remove(o); } }
#endif
}
#endif
}