/* Copyright (c) 2008-2015, Avian Contributors Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. There is NO WARRANTY for this software. See license.txt for details. */ package avian; import java.util.Map; import java.util.Map.Entry; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; import java.util.Collections; public class Data { public static int nextPowerOfTwo(int n) { int r = 1; while (r < n) r <<= 1; return r; } public static boolean equal(V a, V b) { return a == null ? b == null : a.equals(b); } public static T[] toArray(Collection collection, T[] array) { Class c = array.getClass().getComponentType(); if (array.length < collection.size()) { array = (T[]) java.lang.reflect.Array.newInstance(c, collection.size()); } int i = 0; for (Object o: collection) { if (c.isInstance(o)) { array[i++] = (T) o; } else { throw new ArrayStoreException(); } } return array; } public static String toString(Collection c) { StringBuilder sb = new StringBuilder(); sb.append("["); for (Iterator it = c.iterator(); it.hasNext();) { sb.append(it.next()); if (it.hasNext()) { sb.append(","); } } sb.append("]"); return sb.toString(); } public static String toString(Map m) { StringBuilder sb = new StringBuilder(); sb.append("{"); for (Iterator it = m.entrySet().iterator(); it.hasNext();) { Entry e = it.next(); sb.append(e.getKey()) .append("=") .append(e.getValue()); if (it.hasNext()) { sb.append(","); } } sb.append("}"); return sb.toString(); } public interface EntryMap { public int size(); public Entry find(Object key); public Entry remove(Object key); public void clear(); public Iterator> iterator(); } public static class EntrySet extends AbstractSet> { private final EntryMap map; public EntrySet(EntryMap map) { this.map = map; } public int size() { return map.size(); } public boolean isEmpty() { return map.size() == 0; } public boolean contains(Object o) { return (o instanceof Entry) && map.find(((Entry)o).getKey()) != null; } public boolean add(Entry e) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { return (o instanceof Entry) && map.remove(((Entry) o).getKey()) != null; } public boolean remove(Entry e) { return map.remove(e.getKey()) != null; } public Object[] toArray() { return toArray(new Object[size()]); } public T[] toArray(T[] array) { return Data.toArray(this, array); } public void clear() { map.clear(); } public Iterator> iterator() { return map.iterator(); } } public static class KeySet extends AbstractSet { private final EntryMap map; public KeySet(EntryMap map) { this.map = map; } public int size() { return map.size(); } public boolean isEmpty() { return map.size() == 0; } public boolean contains(Object key) { return map.find(key) != null; } public boolean add(K key) { throw new UnsupportedOperationException(); } public boolean remove(Object key) { return map.remove(key) != null; } public Object[] toArray() { return toArray(new Object[size()]); } public T[] toArray(T[] array) { return Data.toArray(this, array); } public void clear() { map.clear(); } public Iterator iterator() { return new KeyIterator(map.iterator()); } } public static class Values implements Collection { private final EntryMap map; public Values(EntryMap map) { this.map = map; } public int size() { return map.size(); } public boolean isEmpty() { return map.size() == 0; } public boolean contains(Object value) { for (Iterator> it = map.iterator(); it.hasNext();) { if (equal(it.next().getValue(), value)) { return true; } } return false; } public boolean containsAll(Collection c) { if (c == null) { throw new NullPointerException("collection is null"); } for (Iterator it = c.iterator(); it.hasNext();) { if (! contains(it.next())) { return false; } } return true; } public boolean add(V value) { throw new UnsupportedOperationException(); } public boolean addAll(Collection collection) { throw new UnsupportedOperationException(); } public boolean remove(Object value) { for (Iterator> it = map.iterator(); it.hasNext();) { if (equal(it.next().getValue(), value)) { it.remove(); return true; } } return false; } public boolean removeAll(Collection c) { boolean changed = false; for (Iterator> it = map.iterator(); it.hasNext();) { if (c.contains(it.next().getValue())) { it.remove(); changed = true; } } return changed; } public Object[] toArray() { return toArray(new Object[size()]); } public T[] toArray(T[] array) { return Data.toArray(this, array); } public void clear() { map.clear(); } public Iterator iterator() { return new ValueIterator(map.iterator()); } } public static class KeyIterator implements Iterator { private final Iterator> it; public KeyIterator(Iterator> it) { this.it = it; } public K next() { return it.next().getKey(); } public boolean hasNext() { return it.hasNext(); } public void remove() { it.remove(); } } public static class ValueIterator implements Iterator { private final Iterator> it; public ValueIterator(Iterator> it) { this.it = it; } public V next() { return it.next().getValue(); } public boolean hasNext() { return it.hasNext(); } public void remove() { it.remove(); } } }