Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C1F2BD492 for ; Fri, 13 Jul 2012 20:14:41 +0000 (UTC) Received: (qmail 8039 invoked by uid 500); 13 Jul 2012 20:14:41 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 7835 invoked by uid 500); 13 Jul 2012 20:14:41 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 7820 invoked by uid 99); 13 Jul 2012 20:14:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Jul 2012 20:14:40 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Jul 2012 20:14:35 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 1791A23889F7 for ; Fri, 13 Jul 2012 20:14:15 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1361376 - in /commons/proper/lang/trunk/src: main/java/org/apache/commons/lang3/EnumUtils.java test/java/org/apache/commons/lang3/EnumUtilsTest.java Date: Fri, 13 Jul 2012 20:14:14 -0000 To: commits@commons.apache.org From: mbenson@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120713201415.1791A23889F7@eris.apache.org> Author: mbenson Date: Fri Jul 13 20:14:14 2012 New Revision: 1361376 URL: http://svn.apache.org/viewvc?rev=1361376&view=rev Log: [LANG-812] Permit bitvector generation for Enums with \> 64 values; plus some test corrections Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java?rev=1361376&r1=1361375&r2=1361376&view=diff ============================================================================== --- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java (original) +++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/EnumUtils.java Fri Jul 13 20:14:14 2012 @@ -18,6 +18,7 @@ package org.apache.commons.lang3; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.EnumSet; import java.util.LinkedHashMap; import java.util.List; @@ -33,6 +34,11 @@ import java.util.Map; */ public class EnumUtils { + private static final String NULL_ELEMENTS_NOT_PERMITTED = "null elements not permitted"; + private static final String CANNOT_STORE_S_S_VALUES_IN_S_BITS = "Cannot store %s %s values in %s bits"; + private static final String S_DOES_NOT_SEEM_TO_BE_AN_ENUM_TYPE = "%s does not seem to be an Enum type"; + private static final String ENUM_CLASS_MUST_BE_DEFINED = "EnumClass must be defined."; + /** * This constructor is public to permit tools that require a JavaBean * instance to operate. @@ -124,24 +130,59 @@ public class EnumUtils { * would create a value greater than a long can hold.

* * @param enumClass the class of the enum we are working with, not {@code null} - * @param values the values we want to convert, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} * @param the type of the enumeration - * @return a long whose binary value represents the given set of enum values. + * @return a long whose value provides a binary representation of the given set of enum values. * @throws NullPointerException if {@code enumClass} or {@code values} is {@code null} - * @throws IllegalArgumentException if {@code enumClass} is not an enum class or has more than 64 values + * @throws IllegalArgumentException if {@code enumClass} is not an enum class or has more than 64 values, + * or if any {@code values} {@code null} * @since 3.0.1 + * @see #generateBitVectors(Class, Iterable) */ public static > long generateBitVector(Class enumClass, Iterable values) { checkBitVectorable(enumClass); Validate.notNull(values); long total = 0; for (E constant : values) { + Validate.isTrue(constant != null, NULL_ELEMENTS_NOT_PERMITTED); total |= 1 << constant.ordinal(); } return total; } /** + *

Creates a bit vector representation of the given subset of an Enum using as many {@code long}s as needed.

+ * + *

This generates a value that is usable by {@link EnumUtils#processBitVectors}.

+ * + *

Use this method if you have more than 64 values in your Enum.

+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @param the type of the enumeration + * @return a long[] whose values provide a binary representation of the given set of enum values + * with least significant digits rightmost. + * @throws NullPointerException if {@code enumClass} or {@code values} is {@code null} + * @throws IllegalArgumentException if {@code enumClass} is not an enum class, or if any {@code values} {@code null} + * @since 3.2 + */ + public static > long[] generateBitVectors(Class enumClass, Iterable values) { + asEnum(enumClass); + Validate.notNull(values); + final EnumSet condensed = EnumSet.noneOf(enumClass); + for (E constant : values) { + Validate.isTrue(constant != null, NULL_ELEMENTS_NOT_PERMITTED); + condensed.add(constant); + } + final long[] result = new long[(enumClass.getEnumConstants().length - 1) / Long.SIZE + 1]; + for (E value : condensed) { + result[value.ordinal() / Long.SIZE] |= 1 << (value.ordinal() % Long.SIZE); + } + ArrayUtils.reverse(result); + return result; + } + + /** *

Creates a long bit vector representation of the given array of Enum values.

* *

This generates a value that is usable by {@link EnumUtils#processBitVector}.

@@ -152,10 +193,11 @@ public class EnumUtils { * @param enumClass the class of the enum we are working with, not {@code null} * @param values the values we want to convert, not {@code null} * @param the type of the enumeration - * @return a long whose binary value represents the given set of enum values. + * @return a long whose value provides a binary representation of the given set of enum values. * @throws NullPointerException if {@code enumClass} or {@code values} is {@code null} * @throws IllegalArgumentException if {@code enumClass} is not an enum class or has more than 64 values * @since 3.0.1 + * @see #generateBitVectors(Class, Iterable) */ public static > long generateBitVector(Class enumClass, E... values) { Validate.noNullElements(values); @@ -163,6 +205,35 @@ public class EnumUtils { } /** + *

Creates a bit vector representation of the given subset of an Enum using as many {@code long}s as needed.

+ * + *

This generates a value that is usable by {@link EnumUtils#processBitVectors}.

+ * + *

Use this method if you have more than 64 values in your Enum.

+ * + * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the values we want to convert, not {@code null}, neither containing {@code null} + * @param the type of the enumeration + * @return a long[] whose values provide a binary representation of the given set of enum values + * with least significant digits rightmost. + * @throws NullPointerException if {@code enumClass} or {@code values} is {@code null} + * @throws IllegalArgumentException if {@code enumClass} is not an enum class, or if any {@code values} {@code null} + * @since 3.2 + */ + public static > long[] generateBitVectors(Class enumClass, E... values) { + asEnum(enumClass); + Validate.noNullElements(values); + final EnumSet condensed = EnumSet.noneOf(enumClass); + Collections.addAll(condensed, values); + final long[] result = new long[(enumClass.getEnumConstants().length - 1) / Long.SIZE + 1]; + for (E value : condensed) { + result[value.ordinal() / Long.SIZE] |= 1 << (value.ordinal() % Long.SIZE); + } + ArrayUtils.reverse(result); + return result; + } + + /** *

Convert a long value created by {@link EnumUtils#generateBitVector} into the set of * enum values that it represents.

* @@ -176,10 +247,30 @@ public class EnumUtils { * @since 3.0.1 */ public static > EnumSet processBitVector(Class enumClass, long value) { - final E[] constants = checkBitVectorable(enumClass).getEnumConstants(); - final EnumSet results = EnumSet.noneOf(enumClass); - for (E constant : constants) { - if ((value & 1 << constant.ordinal()) != 0) { + checkBitVectorable(enumClass).getEnumConstants(); + return processBitVectors(enumClass, value); + } + + /** + *

Convert a {@code long[]} created by {@link EnumUtils#generateBitVectors} into the set of + * enum values that it represents.

+ * + *

If you store this value, beware any changes to the enum that would affect ordinal values.

+ * @param enumClass the class of the enum we are working with, not {@code null} + * @param values the long[] bearing the representation of a set of enum values, least significant digits rightmost, not {@code null} + * @param the type of the enumeration + * @return a set of enum values + * @throws NullPointerException if {@code enumClass} is {@code null} + * @throws IllegalArgumentException if {@code enumClass} is not an enum class + * @since 3.2 + */ + public static > EnumSet processBitVectors(Class enumClass, long... values) { + final EnumSet results = EnumSet.noneOf(asEnum(enumClass)); + values = ArrayUtils.clone(Validate.notNull(values)); + ArrayUtils.reverse(values); + for (E constant : enumClass.getEnumConstants()) { + int block = constant.ordinal() / Long.SIZE; + if (block < values.length && (values[block] & 1 << (constant.ordinal() % Long.SIZE)) != 0) { results.add(constant); } } @@ -196,13 +287,25 @@ public class EnumUtils { * @since 3.0.1 */ private static > Class checkBitVectorable(Class enumClass) { - Validate.notNull(enumClass, "EnumClass must be defined."); - - final E[] constants = enumClass.getEnumConstants(); - Validate.isTrue(constants != null, "%s does not seem to be an Enum type", enumClass); - Validate.isTrue(constants.length <= Long.SIZE, "Cannot store %s %s values in %s bits", constants.length, + final E[] constants = asEnum(enumClass).getEnumConstants(); + Validate.isTrue(constants.length <= Long.SIZE, CANNOT_STORE_S_S_VALUES_IN_S_BITS, constants.length, enumClass.getSimpleName(), Long.SIZE); return enumClass; } + + /** + * Validate {@code enumClass}. + * @param the type of the enumeration + * @param enumClass to check + * @return {@code enumClass} + * @throws NullPointerException if {@code enumClass} is {@code null} + * @throws IllegalArgumentException if {@code enumClass} is not an enum class + * @since 3.2 + */ + private static > Class asEnum(Class enumClass) { + Validate.notNull(enumClass, ENUM_CLASS_MUST_BE_DEFINED); + Validate.isTrue(enumClass.isEnum(), S_DOES_NOT_SEEM_TO_BE_AN_ENUM_TYPE, enumClass); + return enumClass; + } } Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java?rev=1361376&r1=1361375&r2=1361376&view=diff ============================================================================== --- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java (original) +++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/EnumUtilsTest.java Fri Jul 13 20:14:14 2012 @@ -23,10 +23,12 @@ import static org.junit.Assert.assertFal import static org.junit.Assert.assertTrue; import java.util.ArrayList; +import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Map; +import org.junit.Assert; import org.junit.Test; /** @@ -98,20 +100,60 @@ public class EnumUtilsTest { } @Test(expected=NullPointerException.class) + public void test_generateBitVectors_nullClass() { + EnumUtils.generateBitVectors(null, EnumSet.of(Traffic.RED)); + } + + @Test(expected=NullPointerException.class) public void test_generateBitVector_nullIterable() { - EnumUtils.generateBitVector(null, (Iterable) null); + EnumUtils.generateBitVector(Traffic.class, (Iterable) null); } @Test(expected=NullPointerException.class) + public void test_generateBitVectors_nullIterable() { + EnumUtils.generateBitVectors(null, (Iterable) null); + } + + @Test(expected=IllegalArgumentException.class) + public void test_generateBitVector_nullElement() { + EnumUtils.generateBitVector(Traffic.class, Arrays.asList(Traffic.RED, null)); + } + + @Test(expected=IllegalArgumentException.class) + public void test_generateBitVectors_nullElement() { + EnumUtils.generateBitVectors(Traffic.class, Arrays.asList(Traffic.RED, null)); + } + + @Test(expected=NullPointerException.class) public void test_generateBitVector_nullClassWithArray() { EnumUtils.generateBitVector(null, Traffic.RED); } @Test(expected=NullPointerException.class) + public void test_generateBitVectors_nullClassWithArray() { + EnumUtils.generateBitVectors(null, Traffic.RED); + } + + @Test(expected=NullPointerException.class) public void test_generateBitVector_nullArray() { - EnumUtils.generateBitVector(null, (Traffic[]) null); + EnumUtils.generateBitVector(Traffic.class, (Traffic[]) null); } + @Test(expected=NullPointerException.class) + public void test_generateBitVectors_nullArray() { + EnumUtils.generateBitVectors(Traffic.class, (Traffic[]) null); + } + + @Test(expected=IllegalArgumentException.class) + public void test_generateBitVector_nullArrayElement() { + EnumUtils.generateBitVector(Traffic.class, Traffic.RED, null); + } + + @Test(expected=IllegalArgumentException.class) + public void test_generateBitVectors_nullArrayElement() { + EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, null); + } + @Test(expected=IllegalArgumentException.class) public void test_generateBitVector_longClass() { EnumUtils.generateBitVector(TooMany.class, EnumSet.of(TooMany.A1)); @@ -134,11 +176,29 @@ public class EnumUtilsTest { @SuppressWarnings("unchecked") @Test(expected=IllegalArgumentException.class) + public void test_generateBitVectors_nonEnumClass() { + @SuppressWarnings("rawtypes") + Class rawType = Object.class; + @SuppressWarnings("rawtypes") + List rawList = new ArrayList(); + EnumUtils.generateBitVectors(rawType, rawList); + } + + @SuppressWarnings("unchecked") + @Test(expected=IllegalArgumentException.class) public void test_generateBitVector_nonEnumClassWithArray() { @SuppressWarnings("rawtypes") Class rawType = Object.class; EnumUtils.generateBitVector(rawType); } + + @SuppressWarnings("unchecked") + @Test(expected=IllegalArgumentException.class) + public void test_generateBitVectors_nonEnumClassWithArray() { + @SuppressWarnings("rawtypes") + Class rawType = Object.class; + EnumUtils.generateBitVectors(rawType); + } @Test public void test_generateBitVector() { @@ -153,6 +213,18 @@ public class EnumUtilsTest { } @Test + public void test_generateBitVectors() { + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.noneOf(Traffic.class)), 0L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED)), 1L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.AMBER)), 2L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.GREEN)), 4L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER)), 3L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.GREEN)), 5L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.AMBER, Traffic.GREEN)), 6L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN)), 7L); + } + + @Test public void test_generateBitVectorFromArray() { assertEquals(0L, EnumUtils.generateBitVector(Traffic.class)); assertEquals(1L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED)); @@ -166,15 +238,34 @@ public class EnumUtilsTest { assertEquals(7L, EnumUtils.generateBitVector(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN, Traffic.GREEN)); } + @Test + public void test_generateBitVectorsFromArray() { + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class), 0L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED), 1L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.AMBER), 2L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.GREEN), 4L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER), 3L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.GREEN), 5L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.AMBER, Traffic.GREEN), 6L); + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN), 7L); + //gracefully handles duplicates: + assertArrayEquals(EnumUtils.generateBitVectors(Traffic.class, Traffic.RED, Traffic.AMBER, Traffic.GREEN, Traffic.GREEN), 7L); + } + + private void assertArrayEquals(long[] actual, long... expected) { + Assert.assertArrayEquals(expected, actual); + } + @Test(expected=NullPointerException.class) public void test_processBitVector_nullClass() { final Class empty = null; EnumUtils.processBitVector(empty, 0L); } - @Test(expected=IllegalArgumentException.class) - public void test_processBitVector_longClass() { - EnumUtils.processBitVector(TooMany.class, 0L); + @Test(expected=NullPointerException.class) + public void test_processBitVectors_nullClass() { + final Class empty = null; + EnumUtils.processBitVectors(empty, 0L); } @Test @@ -188,6 +279,85 @@ public class EnumUtilsTest { assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 6L)); assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVector(Traffic.class, 7L)); } + + @Test + public void test_processBitVectors() { + assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVectors(Traffic.class, 0L)); + assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVectors(Traffic.class, 1L)); + assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 2L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 3L)); + assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 4L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 5L)); + assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 6L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 7L)); + + assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVectors(Traffic.class, 0L, 0L)); + assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVectors(Traffic.class, 0L, 1L)); + assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 0L, 2L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 0L, 3L)); + assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 0L, 4L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 0L, 5L)); + assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 0L, 6L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 0L, 7L)); + + // demonstrate tolerance of irrelevant high-order digits: + assertEquals(EnumSet.noneOf(Traffic.class), EnumUtils.processBitVectors(Traffic.class, 666L, 0L)); + assertEquals(EnumSet.of(Traffic.RED), EnumUtils.processBitVectors(Traffic.class, 666L, 1L)); + assertEquals(EnumSet.of(Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 666L, 2L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER), EnumUtils.processBitVectors(Traffic.class, 666L, 3L)); + assertEquals(EnumSet.of(Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 4L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 5L)); + assertEquals(EnumSet.of(Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 6L)); + assertEquals(EnumSet.of(Traffic.RED, Traffic.AMBER, Traffic.GREEN), EnumUtils.processBitVectors(Traffic.class, 666L, 7L)); + } + + @Test(expected=IllegalArgumentException.class) + public void test_processBitVector_longClass() { + EnumUtils.processBitVector(TooMany.class, 0L); + } + + public void test_processBitVectors_longClass() { + assertEquals(EnumSet.noneOf(TooMany.class), EnumUtils.processBitVectors(TooMany.class, 0L)); + assertEquals(EnumSet.of(TooMany.A), EnumUtils.processBitVectors(TooMany.class, 1L)); + assertEquals(EnumSet.of(TooMany.B), EnumUtils.processBitVectors(TooMany.class, 2L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B), EnumUtils.processBitVectors(TooMany.class, 3L)); + assertEquals(EnumSet.of(TooMany.C), EnumUtils.processBitVectors(TooMany.class, 4L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 5L)); + assertEquals(EnumSet.of(TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 6L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 7L)); + + assertEquals(EnumSet.noneOf(TooMany.class), EnumUtils.processBitVectors(TooMany.class, 0L, 0L)); + assertEquals(EnumSet.of(TooMany.A), EnumUtils.processBitVectors(TooMany.class, 0L, 1L)); + assertEquals(EnumSet.of(TooMany.B), EnumUtils.processBitVectors(TooMany.class, 0L, 2L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B), EnumUtils.processBitVectors(TooMany.class, 0L, 3L)); + assertEquals(EnumSet.of(TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 4L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 5L)); + assertEquals(EnumSet.of(TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 6L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 7L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C), EnumUtils.processBitVectors(TooMany.class, 0L, 7L)); + + assertEquals(EnumSet.of(TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 0L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 1L)); + assertEquals(EnumSet.of(TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 2L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 3L)); + assertEquals(EnumSet.of(TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 4L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 5L)); + assertEquals(EnumSet.of(TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 6L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 7L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 1L, 7L)); + + // demonstrate tolerance of irrelevant high-order digits: + assertEquals(EnumSet.of(TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 0L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 1L)); + assertEquals(EnumSet.of(TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 2L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 3L)); + assertEquals(EnumSet.of(TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 4L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 5L)); + assertEquals(EnumSet.of(TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 6L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 7L)); + assertEquals(EnumSet.of(TooMany.A, TooMany.B, TooMany.C, TooMany.M2), EnumUtils.processBitVectors(TooMany.class, 9L, 7L)); + } + } enum Traffic {