diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CharArrayMapTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CharArrayMapTest.java index 9be16cc8801..006eefd56e9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CharArrayMapTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CharArrayMapTest.java @@ -10,7 +10,10 @@ *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; +import java.util.Arrays; +import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; import junit.framework.TestCase; @@ -162,23 +165,25 @@ public class CharArrayMapTest extends TestCase { public void testBasicUsage2() { char[] chars = "pantera, megadeth, soulfly, metallica, in flames, lamb of god, carcass".toCharArray(); - Slice[] slices = new Slice[7]; - slices[0] = new Slice(chars, 0, 7); - slices[1] = new Slice(chars, 9, 8); - slices[2] = new Slice(chars, 19, 7); - slices[3] = new Slice(chars, 28, 9); - slices[4] = new Slice(chars, 39, 9); - slices[5] = new Slice(chars, 50, 11); - slices[6] = new Slice(chars, 63, 7); + Slice[] slices = { + new Slice(chars, 0, 7), + new Slice(chars, 9, 8), + new Slice(chars, 19, 7), + new Slice(chars, 28, 9), + new Slice(chars, 39, 9), + new Slice(chars, 50, 11), + new Slice(chars, 63, 7) + }; - char[][] keys = new char[7][]; - keys[0] = "pantera".toCharArray(); - keys[1] = "megadeth".toCharArray(); - keys[2] = "soulfly".toCharArray(); - keys[3] = "metallica".toCharArray(); - keys[4] = "in flames".toCharArray(); - keys[5] = "lamb of god".toCharArray(); - keys[6] = "carcass".toCharArray(); + char[][] keys = { + "pantera".toCharArray(), + "megadeth".toCharArray(), + "soulfly".toCharArray(), + "metallica".toCharArray(), + "in flames".toCharArray(), + "lamb of god".toCharArray(), + "carcass".toCharArray() + }; CharArrayMap map = new CharArrayMap(); assertTrue(map.isEmpty()); @@ -232,6 +237,48 @@ public class CharArrayMapTest extends TestCase { assertEquals(0, map.size()); } + + public void testOrderedMap() { + char[] chars = "alpha beta aaa cappa almost".toCharArray(); + Slice[] slices = { + new Slice(chars, 0, 5), + new Slice(chars, 6, 4), + new Slice(chars, 11, 3), + new Slice(chars, 15, 5), + new Slice(chars, 21, 6) + }; + int[] order = {3, 4, 1, 5, 2}; + + CharArrayMap map = CharArrayMap.createOrderedMap(); + + for(int i = 0; i < slices.length; i++) { + Slice slice = slices[i]; + map.put(slice.chars, slice.start, slice.length, order[i]); + } + + List properOrder = Arrays.asList("aaa", "almost", "alpha", "beta", "cappa"); + + Collection keys = map.keys(); + assertEquals(5, keys.size()); + { + int i = 0; + for(char[] key : keys) { + assertEquals(properOrder.get(i), String.valueOf(key)); + i++; + } + } + + Collection values = map.values(); + assertEquals(5, values.size()); + { + int i = 1; + for(int value : values) { + assertEquals(i++, value); + } + } + } + + public void testProperFail() { char[] hello = "hello".toCharArray(); CharArrayMap map = new CharArrayMap(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayMap.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayMap.java index ab9c00981f5..7f63168f471 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayMap.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/util/CharArrayMap.java @@ -15,6 +15,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.TreeMap; /** @@ -33,7 +34,7 @@ public final class CharArrayMap implements ICharArrayMap { * This class is private so it is assumed that the arguments * passed to the constructor are legal. */ - private static final class Key { + private static final class Key implements Comparable{ private final char[] buffer; private final int start; private final int length; @@ -87,6 +88,16 @@ public final class CharArrayMap implements ICharArrayMap { return "'" + slice + "'@(" + start + "," + length + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } + + public int compareTo(Key other) { + char[] b1 = buffer, b2 = other.buffer; + + for(int i = start, j = other.start; i < b1.length && j < b2.length; i++, j++) { + if(b1[i] != b2[j]) + return b1[i] < b2[j] ? -1 : 1; + } + return b1.length - b2.length; + } } @@ -114,6 +125,25 @@ public final class CharArrayMap implements ICharArrayMap { map = new HashMap(); } + + /** + * Static factory method that constructs an empty CharArrayMap with default initial capacity, + * and the map will be kept in ascending key order. + * + * Characters are compared using a strictly numerical comparison; it is not locale-dependent. + */ + public static CharArrayMap createOrderedMap() { + // TreeMap does not have a constructor that takes an initial capacity + return new CharArrayMap(new TreeMap()); + } + + + private CharArrayMap(Map map) { + assert map != null; + this.map = map; + } + + /** * Constructs an empty CharArrayMap with the given initial capacity. * @throws IllegalArgumentException if the initial capacity is negative