1/*
2 * [The "BSD license"]
3 *  Copyright (c) 2010 Terence Parr
4 *  All rights reserved.
5 *
6 *  Redistribution and use in source and binary forms, with or without
7 *  modification, are permitted provided that the following conditions
8 *  are met:
9 *  1. Redistributions of source code must retain the above copyright
10 *      notice, this list of conditions and the following disclaimer.
11 *  2. Redistributions in binary form must reproduce the above copyright
12 *      notice, this list of conditions and the following disclaimer in the
13 *      documentation and/or other materials provided with the distribution.
14 *  3. The name of the author may not be used to endorse or promote products
15 *      derived from this software without specific prior written permission.
16 *
17 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28package org.antlr.misc;
29
30import java.util.ArrayList;
31import java.util.Iterator;
32import java.util.LinkedHashSet;
33import java.util.List;
34
35/** A HashMap that remembers the order that the elements were added.
36 *  You can alter the ith element with set(i,value) too :)  Unique list.
37 *  I need the replace/set-element-i functionality so I'm subclassing
38 *  OrderedHashSet.
39 */
40public class OrderedHashSet<T> extends LinkedHashSet {
41    /** Track the elements as they are added to the set */
42    protected List<T> elements = new ArrayList<T>();
43
44    public T get(int i) {
45        return elements.get(i);
46    }
47
48    /** Replace an existing value with a new value; updates the element
49     *  list and the hash table, but not the key as that has not changed.
50     */
51    public T set(int i, T value) {
52        T oldElement = elements.get(i);
53        elements.set(i,value); // update list
54        super.remove(oldElement); // now update the set: remove/add
55        super.add(value);
56        return oldElement;
57    }
58
59    /** Add a value to list; keep in hashtable for consistency also;
60     *  Key is object itself.  Good for say asking if a certain string is in
61     *  a list of strings.
62     */
63    public boolean add(Object value) {
64        boolean result = super.add(value);
65		if ( result ) {  // only track if new element not in set
66			elements.add((T)value);
67		}
68		return result;
69    }
70
71    public boolean remove(Object o) {
72		throw new UnsupportedOperationException();
73		/*
74		elements.remove(o);
75        return super.remove(o);
76        */
77    }
78
79    public void clear() {
80        elements.clear();
81        super.clear();
82    }
83
84    /** Return the List holding list of table elements.  Note that you are
85     *  NOT getting a copy so don't write to the list.
86     */
87    public List<T> elements() {
88        return elements;
89    }
90
91	public Iterator<T> iterator() {
92		return elements.iterator();
93	}
94
95	public Object[] toArray() {
96		return elements.toArray();
97	}
98
99    public int size() {
100		/*
101		if ( elements.size()!=super.size() ) {
102			ErrorManager.internalError("OrderedHashSet: elements and set size differs; "+
103									   elements.size()+"!="+super.size());
104        }
105        */
106        return elements.size();
107    }
108
109    public String toString() {
110        return elements.toString();
111    }
112}
113