1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the GNU General Public License v3+, or later.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package net
.multiphasicapps
.classfile
;
12 import java
.util
.AbstractSet
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Arrays
;
15 import java
.util
.HashSet
;
16 import java
.util
.Iterator
;
17 import java
.util
.List
;
21 * This is the base class for all flag collections.
23 * @param <F> The flag type.
26 public abstract class Flags
<F
extends Flag
>
27 extends AbstractSet
<F
>
29 /** The class type to use. */
30 protected final Class
<F
> cast
;
32 /** The set ordinals. */
33 protected final int setbits
;
35 /** The slower access set. */
36 private final Set
<F
> _flags
;
39 * Initializes the flag set.
41 * @param __cl The class type of the flag.
42 * @param __fl The input flags.
43 * @throws NullPointerException On null arguments.
46 Flags(Class
<F
> __cl
, F
[] __fl
)
47 throws NullPointerException
49 this(__cl
, Arrays
.<F
>asList(__fl
));
53 * Initializes the flag set.
55 * @param __cl The class type of the flag.
56 * @param __fl The input flags.
57 * @throws NullPointerException On null arguments.
60 Flags(Class
<F
> __cl
, Iterable
<F
> __fl
)
63 if (__cl
== null || __fl
== null)
64 throw new NullPointerException("NARG");
69 // Go through all input flags
70 Set
<F
> to
= new HashSet
<>();
94 public final boolean contains(Object __o
)
96 if (!(__o
instanceof Flag
))
100 if (this.cast
.isInstance(__o
))
101 return 0 != (this.setbits
& (1 << (((Flag
)__o
).ordinal())));
104 return this._flags
.contains(__o
);
112 public final Iterator
<F
> iterator()
114 return new __Iterator__
<F
>(this._flags
.iterator());
122 public final int size()
124 return this._flags
.size();
128 * Converts the flags to Java bits.
130 * @return The Java bits.
133 public final int toJavaBits()
138 rv
|= f
.javaBitMask();
144 * Decodes the specified bitfield and returns the used flags.
146 * @param <F> The type of flags to decode.
147 * @param __i The input bitfield.
148 * @param __f The flag values to decode.
149 * @return The flags specified in the bitfield.
150 * @throws InvalidClassFormatException If extra flags were specified.
151 * @throws NullPointerException On null arguments.
154 static <F
extends Flag
> Iterable
<F
> __decode(int __i
, F
[] __f
)
155 throws InvalidClassFormatException
, NullPointerException
157 // Find all matching flags in the bitfield
158 List
<F
> fl
= new ArrayList
<>(__f
.length
);
161 int v
= f
.javaBitMask();
169 // {@squirreljme.error JC2w An undefined flag has been specified.
170 // (The extra bitfield flags)}
172 throw new InvalidClassFormatException(
173 String
.format("JC2w %02x", __i
));
179 * Iterates over flags.
183 private static final class __Iterator__
<F
>
184 implements Iterator
<F
>
186 /** The iterator used. */
187 protected final Iterator
<F
> iterator
;
190 * Wraps the iterator.
192 * @param __it The iterator to wrap.
195 private __Iterator__(Iterator
<F
> __it
)
197 this.iterator
= __it
;
205 public boolean hasNext()
207 return this.iterator
.hasNext();
217 return this.iterator
.next();
227 throw new UnsupportedOperationException("RORO");