001/*
002 * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
003 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
004 *
005 *
006 *
007 *
008 *
009 *
010 *
011 *
012 *
013 *
014 *
015 *
016 *
017 *
018 *
019 *
020 *
021 *
022 *
023 *
024 */
025
026package conexp.fx.core.collections;
027
028/*-
029 * #%L
030 * Concept Explorer FX
031 * %%
032 * Copyright (C) 2010 - 2023 Francesco Kriegel
033 * %%
034 * This program is free software: you can redistribute it and/or modify
035 * it under the terms of the GNU General Public License as
036 * published by the Free Software Foundation, either version 3 of the
037 * License, or (at your option) any later version.
038 * 
039 * This program is distributed in the hope that it will be useful,
040 * but WITHOUT ANY WARRANTY; without even the implied warranty of
041 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
042 * GNU General Public License for more details.
043 * 
044 * You should have received a copy of the GNU General Public
045 * License along with this program.  If not, see
046 * <http://www.gnu.org/licenses/gpl-3.0.html>.
047 * #L%
048 */
049
050import java.io.IOException;
051import java.io.ObjectInputStream;
052import java.io.ObjectOutputStream;
053import java.io.ObjectStreamField;
054import java.nio.ByteBuffer;
055import java.nio.ByteOrder;
056import java.nio.LongBuffer;
057import java.util.AbstractSet;
058import java.util.Arrays;
059import java.util.Collection;
060import java.util.Comparator;
061import java.util.Iterator;
062import java.util.NoSuchElementException;
063import java.util.PrimitiveIterator;
064import java.util.SortedSet;
065import java.util.Spliterator;
066import java.util.Spliterators;
067import java.util.stream.Stream;
068import java.util.stream.StreamSupport;
069
070/**
071 * This class implements a vector of bits that grows as needed. Each component of the bit set has a {@code boolean}
072 * value. The bits of a {@code BitSet} are indexed by nonnegative integers. Individual indexed bits can be examined,
073 * set, or cleared. One {@code BitSet} may be used to modify the contents of another {@code BitSet} through logical AND,
074 * logical inclusive OR, and logical exclusive OR operations.
075 *
076 * <p>
077 * By default, all bits in the set initially have the value {@code false}.
078 *
079 * <p>
080 * Every bit set has a current size, which is the number of bits of space currently in use by the bit set. Note that the
081 * size is related to the implementation of a bit set, so it may change with implementation. The length of a bit set
082 * relates to logical length of a bit set and is defined independently of implementation.
083 *
084 * <p>
085 * Unless otherwise noted, passing a null parameter to any of the methods in a {@code BitSet} will result in a
086 * {@code NullPointerException}.
087 *
088 * <p>
089 * A {@code BitSet} is not safe for multithreaded use without external synchronization.
090 *
091 * @author Arthur van Hoff
092 * @author Michael McCloskey
093 * @author Martin Buchholz
094 * @since JDK1.0
095 */
096public class BitSetFX extends AbstractSet<Integer> implements SortedSet<Integer>, Cloneable, java.io.Serializable {
097
098  /*
099   * BitSets are packed into arrays of "words." Currently a word is a long, which consists of 64 bits, requiring 6
100   * address bits. The choice of word size is determined purely by performance concerns.
101   */
102  private final static int                 ADDRESS_BITS_PER_WORD  = 6;
103  private final static int                 BITS_PER_WORD          = 1 << ADDRESS_BITS_PER_WORD;
104  private final static int                 BIT_INDEX_MASK         = BITS_PER_WORD - 1;
105
106  /* Used to shift left or right for a partial word mask */
107  private static final long                WORD_MASK              = 0xffffffffffffffffL;
108
109  /**
110   * @serialField bits
111   *                long[]
112   *
113   *                The bits in this BitSet. The ith bit is stored in bits[i/64] at bit position i % 64 (where bit
114   *                position 0 refers to the least significant bit and 63 refers to the most significant bit).
115   */
116  private static final ObjectStreamField[] serialPersistentFields = {
117      new ObjectStreamField("bits", long[].class),
118  };
119
120  /**
121   * The internal field corresponding to the serialField "bits".
122   */
123  private long[]                           words;
124
125  /**
126   * The number of words in the logical size of this BitSet.
127   */
128  private transient int                    wordsInUse             = 0;
129
130  /**
131   * Whether the size of "words" is user-specified. If so, we assume the user knows what he's doing and try harder to
132   * preserve it.
133   */
134  private transient boolean                sizeIsSticky           = false;
135
136  /* use serialVersionUID from JDK 1.0.2 for interoperability */
137  private static final long                serialVersionUID       = 7997698588986878753L;
138
139  /**
140   * Given a bit index, return word index containing it.
141   */
142  private static int wordIndex(int bitIndex) {
143    return bitIndex >> ADDRESS_BITS_PER_WORD;
144  }
145
146  /**
147   * Every public method must preserve these invariants.
148   */
149  private void checkInvariants() {
150    assert (wordsInUse == 0 || words[wordsInUse - 1] != 0);
151    assert (wordsInUse >= 0 && wordsInUse <= words.length);
152    assert (wordsInUse == words.length || words[wordsInUse] == 0);
153  }
154
155  /**
156   * Sets the field wordsInUse to the logical size in words of the bit set. WARNING:This method assumes that the number
157   * of words actually in use is less than or equal to the current value of wordsInUse!
158   */
159  private void recalculateWordsInUse() {
160    // Traverse the bitset until a used word is found
161    int i;
162    for (i = wordsInUse - 1; i >= 0; i--)
163      if (words[i] != 0)
164        break;
165
166    wordsInUse = i + 1; // The new logical size
167  }
168
169  /**
170   * Creates a new bit set. All bits are initially {@code false}.
171   */
172  public BitSetFX() {
173    initWords(BITS_PER_WORD);
174    sizeIsSticky = false;
175  }
176
177  /**
178   * Creates a bit set whose initial size is large enough to explicitly represent bits with indices in the range
179   * {@code 0} through {@code nbits-1}. All bits are initially {@code false}.
180   *
181   * @param nbits
182   *          the initial size of the bit set
183   * @throws NegativeArraySizeException
184   *           if the specified initial size is negative
185   */
186  public BitSetFX(int nbits) {
187    // nbits can't be negative; size 0 is OK
188    if (nbits < 0)
189      throw new NegativeArraySizeException("nbits < 0: " + nbits);
190
191    initWords(nbits);
192    sizeIsSticky = true;
193  }
194
195  private void initWords(int nbits) {
196    words = new long[wordIndex(nbits - 1) + 1];
197  }
198
199  /**
200   * Creates a bit set using words as the internal representation. The last word (if there is one) must be non-zero.
201   */
202  private BitSetFX(long[] words) {
203    this.words = words;
204    this.wordsInUse = words.length;
205    checkInvariants();
206  }
207
208  /**
209   * Returns a new bit set containing all the bits in the given long array.
210   *
211   * <p>
212   * More precisely, <br>
213   * {@code BitSet.valueOf(longs).get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)} <br>
214   * for all {@code n < 64 * longs.length}.
215   *
216   * <p>
217   * This method is equivalent to {@code BitSet.valueOf(LongBuffer.wrap(longs))}.
218   *
219   * @param longs
220   *          a long array containing a little-endian representation of a sequence of bits to be used as the initial
221   *          bits of the new bit set
222   * @return a {@code BitSet} containing all the bits in the long array
223   * @since 1.7
224   */
225  public static BitSetFX valueOf(long[] longs) {
226    int n;
227    for (n = longs.length; n > 0 && longs[n - 1] == 0; n--);
228    return new BitSetFX(Arrays.copyOf(longs, n));
229  }
230
231  /**
232   * Returns a new bit set containing all the bits in the given long buffer between its position and limit.
233   *
234   * <p>
235   * More precisely, <br>
236   * {@code BitSet.valueOf(lb).get(n) == ((lb.get(lb.position()+n/64) & (1L<<(n%64))) != 0)} <br>
237   * for all {@code n < 64 * lb.remaining()}.
238   *
239   * <p>
240   * The long buffer is not modified by this method, and no reference to the buffer is retained by the bit set.
241   *
242   * @param lb
243   *          a long buffer containing a little-endian representation of a sequence of bits between its position and
244   *          limit, to be used as the initial bits of the new bit set
245   * @return a {@code BitSet} containing all the bits in the buffer in the specified range
246   * @since 1.7
247   */
248  public static BitSetFX valueOf(LongBuffer lb) {
249    lb = lb.slice();
250    int n;
251    for (n = lb.remaining(); n > 0 && lb.get(n - 1) == 0; n--);
252    long[] words = new long[n];
253    lb.get(words);
254    return new BitSetFX(words);
255  }
256
257  /**
258   * Returns a new bit set containing all the bits in the given byte array.
259   *
260   * <p>
261   * More precisely, <br>
262   * {@code BitSet.valueOf(bytes).get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)} <br>
263   * for all {@code n <  8 * bytes.length}.
264   *
265   * <p>
266   * This method is equivalent to {@code BitSet.valueOf(ByteBuffer.wrap(bytes))}.
267   *
268   * @param bytes
269   *          a byte array containing a little-endian representation of a sequence of bits to be used as the initial
270   *          bits of the new bit set
271   * @return a {@code BitSet} containing all the bits in the byte array
272   * @since 1.7
273   */
274  public static BitSetFX valueOf(byte[] bytes) {
275    return BitSetFX.valueOf(ByteBuffer.wrap(bytes));
276  }
277
278  /**
279   * Returns a new bit set containing all the bits in the given byte buffer between its position and limit.
280   *
281   * <p>
282   * More precisely, <br>
283   * {@code BitSet.valueOf(bb).get(n) == ((bb.get(bb.position()+n/8) & (1<<(n%8))) != 0)} <br>
284   * for all {@code n < 8 * bb.remaining()}.
285   *
286   * <p>
287   * The byte buffer is not modified by this method, and no reference to the buffer is retained by the bit set.
288   *
289   * @param bb
290   *          a byte buffer containing a little-endian representation of a sequence of bits between its position and
291   *          limit, to be used as the initial bits of the new bit set
292   * @return a {@code BitSet} containing all the bits in the buffer in the specified range
293   * @since 1.7
294   */
295  public static BitSetFX valueOf(ByteBuffer bb) {
296    bb = bb.slice().order(ByteOrder.LITTLE_ENDIAN);
297    int n;
298    for (n = bb.remaining(); n > 0 && bb.get(n - 1) == 0; n--);
299    long[] words = new long[(n + 7) / 8];
300    bb.limit(n);
301    int i = 0;
302    while (bb.remaining() >= 8)
303      words[i++] = bb.getLong();
304    for (int remaining = bb.remaining(), j = 0; j < remaining; j++)
305      words[i] |= (bb.get() & 0xffL) << (8 * j);
306    return new BitSetFX(words);
307  }
308
309  /**
310   * Returns a new byte array containing all the bits in this bit set.
311   *
312   * <p>
313   * More precisely, if <br>
314   * {@code byte[] bytes = s.toByteArray();} <br>
315   * then {@code bytes.length == (s.length()+7)/8} and <br>
316   * {@code s.get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)} <br>
317   * for all {@code n < 8 * bytes.length}.
318   *
319   * @return a byte array containing a little-endian representation of all the bits in this bit set
320   * @since 1.7
321   */
322  public byte[] toByteArray() {
323    int n = wordsInUse;
324    if (n == 0)
325      return new byte[0];
326    int len = 8 * (n - 1);
327    for (long x = words[n - 1]; x != 0; x >>>= 8)
328      len++;
329    byte[] bytes = new byte[len];
330    ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
331    for (int i = 0; i < n - 1; i++)
332      bb.putLong(words[i]);
333    for (long x = words[n - 1]; x != 0; x >>>= 8)
334      bb.put((byte) (x & 0xff));
335    return bytes;
336  }
337
338  /**
339   * Returns a new long array containing all the bits in this bit set.
340   *
341   * <p>
342   * More precisely, if <br>
343   * {@code long[] longs = s.toLongArray();} <br>
344   * then {@code longs.length == (s.length()+63)/64} and <br>
345   * {@code s.get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)} <br>
346   * for all {@code n < 64 * longs.length}.
347   *
348   * @return a long array containing a little-endian representation of all the bits in this bit set
349   * @since 1.7
350   */
351  public long[] toLongArray() {
352    return Arrays.copyOf(words, wordsInUse);
353  }
354
355  /**
356   * Ensures that the BitSet can hold enough words.
357   * 
358   * @param wordsRequired
359   *          the minimum acceptable number of words.
360   */
361  private void ensureCapacity(int wordsRequired) {
362    if (words.length < wordsRequired) {
363      // Allocate larger of doubled size or required size
364      int request = Math.max(2 * words.length, wordsRequired);
365      words = Arrays.copyOf(words, request);
366      sizeIsSticky = false;
367    }
368  }
369
370  /**
371   * Ensures that the BitSet can accommodate a given wordIndex, temporarily violating the invariants. The caller must
372   * restore the invariants before returning to the user, possibly using recalculateWordsInUse().
373   * 
374   * @param wordIndex
375   *          the index to be accommodated.
376   */
377  private void expandTo(int wordIndex) {
378    int wordsRequired = wordIndex + 1;
379    if (wordsInUse < wordsRequired) {
380      ensureCapacity(wordsRequired);
381      wordsInUse = wordsRequired;
382    }
383  }
384
385  /**
386   * Checks that fromIndex ... toIndex is a valid range of bit indices.
387   */
388  private static void checkRange(int fromIndex, int toIndex) {
389    if (fromIndex < 0)
390      throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
391    if (toIndex < 0)
392      throw new IndexOutOfBoundsException("toIndex < 0: " + toIndex);
393    if (fromIndex > toIndex)
394      throw new IndexOutOfBoundsException("fromIndex: " + fromIndex + " > toIndex: " + toIndex);
395  }
396
397  /**
398   * Sets the bit at the specified index to the complement of its current value.
399   *
400   * @param bitIndex
401   *          the index of the bit to flip
402   * @throws IndexOutOfBoundsException
403   *           if the specified index is negative
404   * @since 1.4
405   */
406  public void flip(int bitIndex) {
407    if (bitIndex < 0)
408      throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
409
410    int wordIndex = wordIndex(bitIndex);
411    expandTo(wordIndex);
412
413    words[wordIndex] ^= (1L << bitIndex);
414
415    recalculateWordsInUse();
416    checkInvariants();
417  }
418
419  /**
420   * Sets each bit from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to the
421   * complement of its current value.
422   *
423   * @param fromIndex
424   *          index of the first bit to flip
425   * @param toIndex
426   *          index after the last bit to flip
427   * @throws IndexOutOfBoundsException
428   *           if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than
429   *           {@code toIndex}
430   * @since 1.4
431   */
432  public void flip(int fromIndex, int toIndex) {
433    checkRange(fromIndex, toIndex);
434
435    if (fromIndex == toIndex)
436      return;
437
438    int startWordIndex = wordIndex(fromIndex);
439    int endWordIndex = wordIndex(toIndex - 1);
440    expandTo(endWordIndex);
441
442    long firstWordMask = WORD_MASK << fromIndex;
443    long lastWordMask = WORD_MASK >>> -toIndex;
444    if (startWordIndex == endWordIndex) {
445      // Case 1: One word
446      words[startWordIndex] ^= (firstWordMask & lastWordMask);
447    } else {
448      // Case 2: Multiple words
449      // Handle first word
450      words[startWordIndex] ^= firstWordMask;
451
452      // Handle intermediate words, if any
453      for (int i = startWordIndex + 1; i < endWordIndex; i++)
454        words[i] ^= WORD_MASK;
455
456      // Handle last word
457      words[endWordIndex] ^= lastWordMask;
458    }
459
460    recalculateWordsInUse();
461    checkInvariants();
462  }
463
464  /**
465   * Sets the bit at the specified index to {@code true}.
466   *
467   * @param bitIndex
468   *          a bit index
469   * @throws IndexOutOfBoundsException
470   *           if the specified index is negative
471   * @since JDK1.0
472   */
473  public void set(int bitIndex) {
474    if (bitIndex < 0)
475      throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
476
477    int wordIndex = wordIndex(bitIndex);
478    expandTo(wordIndex);
479
480    words[wordIndex] |= (1L << bitIndex); // Restores invariants
481
482    checkInvariants();
483  }
484
485  /**
486   * Sets the bit at the specified index to the specified value.
487   *
488   * @param bitIndex
489   *          a bit index
490   * @param value
491   *          a boolean value to set
492   * @throws IndexOutOfBoundsException
493   *           if the specified index is negative
494   * @since 1.4
495   */
496  public void set(int bitIndex, boolean value) {
497    if (value)
498      set(bitIndex);
499    else
500      clear(bitIndex);
501  }
502
503  /**
504   * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to
505   * {@code true}.
506   *
507   * @param fromIndex
508   *          index of the first bit to be set
509   * @param toIndex
510   *          index after the last bit to be set
511   * @throws IndexOutOfBoundsException
512   *           if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than
513   *           {@code toIndex}
514   * @since 1.4
515   */
516  public void set(int fromIndex, int toIndex) {
517    checkRange(fromIndex, toIndex);
518
519    if (fromIndex == toIndex)
520      return;
521
522    // Increase capacity if necessary
523    int startWordIndex = wordIndex(fromIndex);
524    int endWordIndex = wordIndex(toIndex - 1);
525    expandTo(endWordIndex);
526
527    long firstWordMask = WORD_MASK << fromIndex;
528    long lastWordMask = WORD_MASK >>> -toIndex;
529    if (startWordIndex == endWordIndex) {
530      // Case 1: One word
531      words[startWordIndex] |= (firstWordMask & lastWordMask);
532    } else {
533      // Case 2: Multiple words
534      // Handle first word
535      words[startWordIndex] |= firstWordMask;
536
537      // Handle intermediate words, if any
538      for (int i = startWordIndex + 1; i < endWordIndex; i++)
539        words[i] = WORD_MASK;
540
541      // Handle last word (restores invariants)
542      words[endWordIndex] |= lastWordMask;
543    }
544
545    checkInvariants();
546  }
547
548  /**
549   * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to the
550   * specified value.
551   *
552   * @param fromIndex
553   *          index of the first bit to be set
554   * @param toIndex
555   *          index after the last bit to be set
556   * @param value
557   *          value to set the selected bits to
558   * @throws IndexOutOfBoundsException
559   *           if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than
560   *           {@code toIndex}
561   * @since 1.4
562   */
563  public void set(int fromIndex, int toIndex, boolean value) {
564    if (value)
565      set(fromIndex, toIndex);
566    else
567      clear(fromIndex, toIndex);
568  }
569
570  /**
571   * Sets the bit specified by the index to {@code false}.
572   *
573   * @param bitIndex
574   *          the index of the bit to be cleared
575   * @throws IndexOutOfBoundsException
576   *           if the specified index is negative
577   * @since JDK1.0
578   */
579  public void clear(int bitIndex) {
580    if (bitIndex < 0)
581      throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
582
583    int wordIndex = wordIndex(bitIndex);
584    if (wordIndex >= wordsInUse)
585      return;
586
587    words[wordIndex] &= ~(1L << bitIndex);
588
589    recalculateWordsInUse();
590    checkInvariants();
591  }
592
593  /**
594   * Sets the bits from the specified {@code fromIndex} (inclusive) to the specified {@code toIndex} (exclusive) to
595   * {@code false}.
596   *
597   * @param fromIndex
598   *          index of the first bit to be cleared
599   * @param toIndex
600   *          index after the last bit to be cleared
601   * @throws IndexOutOfBoundsException
602   *           if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than
603   *           {@code toIndex}
604   * @since 1.4
605   */
606  public void clear(int fromIndex, int toIndex) {
607    checkRange(fromIndex, toIndex);
608
609    if (fromIndex == toIndex)
610      return;
611
612    int startWordIndex = wordIndex(fromIndex);
613    if (startWordIndex >= wordsInUse)
614      return;
615
616    int endWordIndex = wordIndex(toIndex - 1);
617    if (endWordIndex >= wordsInUse) {
618      toIndex = length();
619      endWordIndex = wordsInUse - 1;
620    }
621
622    long firstWordMask = WORD_MASK << fromIndex;
623    long lastWordMask = WORD_MASK >>> -toIndex;
624    if (startWordIndex == endWordIndex) {
625      // Case 1: One word
626      words[startWordIndex] &= ~(firstWordMask & lastWordMask);
627    } else {
628      // Case 2: Multiple words
629      // Handle first word
630      words[startWordIndex] &= ~firstWordMask;
631
632      // Handle intermediate words, if any
633      for (int i = startWordIndex + 1; i < endWordIndex; i++)
634        words[i] = 0;
635
636      // Handle last word
637      words[endWordIndex] &= ~lastWordMask;
638    }
639
640    recalculateWordsInUse();
641    checkInvariants();
642  }
643
644  /**
645   * Sets all of the bits in this BitSet to {@code false}.
646   *
647   * @since 1.4
648   */
649  public void clear() {
650    while (wordsInUse > 0)
651      words[--wordsInUse] = 0;
652  }
653
654  /**
655   * Returns the value of the bit with the specified index. The value is {@code true} if the bit with the index
656   * {@code bitIndex} is currently set in this {@code BitSet}; otherwise, the result is {@code false}.
657   *
658   * @param bitIndex
659   *          the bit index
660   * @return the value of the bit with the specified index
661   * @throws IndexOutOfBoundsException
662   *           if the specified index is negative
663   */
664  public boolean get(int bitIndex) {
665    if (bitIndex < 0)
666      throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
667
668    checkInvariants();
669
670    int wordIndex = wordIndex(bitIndex);
671    return (wordIndex < wordsInUse) && ((words[wordIndex] & (1L << bitIndex)) != 0);
672  }
673
674  /**
675   * Returns a new {@code BitSet} composed of bits from this {@code BitSet} from {@code fromIndex} (inclusive) to
676   * {@code toIndex} (exclusive).
677   *
678   * @param fromIndex
679   *          index of the first bit to include
680   * @param toIndex
681   *          index after the last bit to include
682   * @return a new {@code BitSet} from a range of this {@code BitSet}
683   * @throws IndexOutOfBoundsException
684   *           if {@code fromIndex} is negative, or {@code toIndex} is negative, or {@code fromIndex} is larger than
685   *           {@code toIndex}
686   * @since 1.4
687   */
688  public BitSetFX get(int fromIndex, int toIndex) {
689    checkRange(fromIndex, toIndex);
690
691    checkInvariants();
692
693    int len = length();
694
695    // If no set bits in range return empty bitset
696    if (len <= fromIndex || fromIndex == toIndex)
697      return new BitSetFX(0);
698
699    // An optimization
700    if (toIndex > len)
701      toIndex = len;
702
703    BitSetFX result = new BitSetFX(toIndex - fromIndex);
704    int targetWords = wordIndex(toIndex - fromIndex - 1) + 1;
705    int sourceIndex = wordIndex(fromIndex);
706    boolean wordAligned = ((fromIndex & BIT_INDEX_MASK) == 0);
707
708    // Process all words but the last word
709    for (int i = 0; i < targetWords - 1; i++, sourceIndex++)
710      result.words[i] = wordAligned ? words[sourceIndex]
711          : (words[sourceIndex] >>> fromIndex) | (words[sourceIndex + 1] << -fromIndex);
712
713    // Process the last word
714    long lastWordMask = WORD_MASK >>> -toIndex;
715    result.words[targetWords - 1] =
716        ((toIndex - 1) & BIT_INDEX_MASK) < (fromIndex & BIT_INDEX_MASK) ? /* straddles source words */
717            ((words[sourceIndex] >>> fromIndex) | (words[sourceIndex + 1] & lastWordMask) << -fromIndex)
718            : ((words[sourceIndex] & lastWordMask) >>> fromIndex);
719
720    // Set wordsInUse correctly
721    result.wordsInUse = targetWords;
722    result.recalculateWordsInUse();
723    result.checkInvariants();
724
725    return result;
726  }
727
728  /**
729   * Returns the index of the first bit that is set to {@code true} that occurs on or after the specified starting
730   * index. If no such bit exists then {@code -1} is returned.
731   *
732   * <p>
733   * To iterate over the {@code true} bits in a {@code BitSet}, use the following loop:
734   *
735   * <pre>
736   *  {@code
737   * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
738   *     // operate on index i here
739   *     if (i == Integer.MAX_VALUE) {
740   *         break; // or (i+1) would overflow
741   *     }
742   * }}
743   * </pre>
744   *
745   * @param fromIndex
746   *          the index to start checking from (inclusive)
747   * @return the index of the next set bit, or {@code -1} if there is no such bit
748   * @throws IndexOutOfBoundsException
749   *           if the specified index is negative
750   * @since 1.4
751   */
752  public int nextSetBit(int fromIndex) {
753    if (fromIndex < 0)
754      throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
755
756    checkInvariants();
757
758    int u = wordIndex(fromIndex);
759    if (u >= wordsInUse)
760      return -1;
761
762    long word = words[u] & (WORD_MASK << fromIndex);
763
764    while (true) {
765      if (word != 0)
766        return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
767      if (++u == wordsInUse)
768        return -1;
769      word = words[u];
770    }
771  }
772
773  /**
774   * Returns the index of the first bit that is set to {@code false} that occurs on or after the specified starting
775   * index.
776   *
777   * @param fromIndex
778   *          the index to start checking from (inclusive)
779   * @return the index of the next clear bit
780   * @throws IndexOutOfBoundsException
781   *           if the specified index is negative
782   * @since 1.4
783   */
784  public int nextClearBit(int fromIndex) {
785    // Neither spec nor implementation handle bitsets of maximal length.
786    // See 4816253.
787    if (fromIndex < 0)
788      throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
789
790    checkInvariants();
791
792    int u = wordIndex(fromIndex);
793    if (u >= wordsInUse)
794      return fromIndex;
795
796    long word = ~words[u] & (WORD_MASK << fromIndex);
797
798    while (true) {
799      if (word != 0)
800        return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
801      if (++u == wordsInUse)
802        return wordsInUse * BITS_PER_WORD;
803      word = ~words[u];
804    }
805  }
806
807  /**
808   * Returns the index of the nearest bit that is set to {@code true} that occurs on or before the specified starting
809   * index. If no such bit exists, or if {@code -1} is given as the starting index, then {@code -1} is returned.
810   *
811   * <p>
812   * To iterate over the {@code true} bits in a {@code BitSet}, use the following loop:
813   *
814   * <pre>
815   *  {@code
816   * for (int i = bs.length(); (i = bs.previousSetBit(i-1)) >= 0; ) {
817   *     // operate on index i here
818   * }}
819   * </pre>
820   *
821   * @param fromIndex
822   *          the index to start checking from (inclusive)
823   * @return the index of the previous set bit, or {@code -1} if there is no such bit
824   * @throws IndexOutOfBoundsException
825   *           if the specified index is less than {@code -1}
826   * @since 1.7
827   */
828  public int previousSetBit(int fromIndex) {
829    if (fromIndex < 0) {
830      if (fromIndex == -1)
831        return -1;
832      throw new IndexOutOfBoundsException("fromIndex < -1: " + fromIndex);
833    }
834
835    checkInvariants();
836
837    int u = wordIndex(fromIndex);
838    if (u >= wordsInUse)
839      return length() - 1;
840
841    long word = words[u] & (WORD_MASK >>> -(fromIndex + 1));
842
843    while (true) {
844      if (word != 0)
845        return (u + 1) * BITS_PER_WORD - 1 - Long.numberOfLeadingZeros(word);
846      if (u-- == 0)
847        return -1;
848      word = words[u];
849    }
850  }
851
852  /**
853   * Returns the index of the nearest bit that is set to {@code false} that occurs on or before the specified starting
854   * index. If no such bit exists, or if {@code -1} is given as the starting index, then {@code -1} is returned.
855   *
856   * @param fromIndex
857   *          the index to start checking from (inclusive)
858   * @return the index of the previous clear bit, or {@code -1} if there is no such bit
859   * @throws IndexOutOfBoundsException
860   *           if the specified index is less than {@code -1}
861   * @since 1.7
862   */
863  public int previousClearBit(int fromIndex) {
864    if (fromIndex < 0) {
865      if (fromIndex == -1)
866        return -1;
867      throw new IndexOutOfBoundsException("fromIndex < -1: " + fromIndex);
868    }
869
870    checkInvariants();
871
872    int u = wordIndex(fromIndex);
873    if (u >= wordsInUse)
874      return fromIndex;
875
876    long word = ~words[u] & (WORD_MASK >>> -(fromIndex + 1));
877
878    while (true) {
879      if (word != 0)
880        return (u + 1) * BITS_PER_WORD - 1 - Long.numberOfLeadingZeros(word);
881      if (u-- == 0)
882        return -1;
883      word = ~words[u];
884    }
885  }
886
887  /**
888   * Returns the "logical size" of this {@code BitSet}: the index of the highest set bit in the {@code BitSet} plus one.
889   * Returns zero if the {@code BitSet} contains no set bits.
890   *
891   * @return the logical size of this {@code BitSet}
892   * @since 1.2
893   */
894  public int length() {
895    if (wordsInUse == 0)
896      return 0;
897
898    return BITS_PER_WORD * (wordsInUse - 1) + (BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1]));
899  }
900
901  /**
902   * Returns true if this {@code BitSet} contains no bits that are set to {@code true}.
903   *
904   * @return boolean indicating whether this {@code BitSet} is empty
905   * @since 1.4
906   */
907  public boolean isEmpty() {
908    return wordsInUse == 0;
909  }
910
911  /**
912   * Returns true if the specified {@code BitSet} has any bits set to {@code true} that are also set to {@code true} in
913   * this {@code BitSet}.
914   *
915   * @param set
916   *          {@code BitSet} to intersect with
917   * @return boolean indicating whether this {@code BitSet} intersects the specified {@code BitSet}
918   * @since 1.4
919   */
920  public boolean intersects(BitSetFX set) {
921    for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
922      if ((words[i] & set.words[i]) != 0)
923        return true;
924    return false;
925  }
926
927  /**
928   * Returns the number of bits set to {@code true} in this {@code BitSet}.
929   *
930   * @return the number of bits set to {@code true} in this {@code BitSet}
931   * @since 1.4
932   */
933  public int cardinality() {
934    int sum = 0;
935    for (int i = 0; i < wordsInUse; i++)
936      sum += Long.bitCount(words[i]);
937    return sum;
938  }
939
940  /**
941   * Performs a logical <b>AND</b> of this target bit set with the argument bit set. This bit set is modified so that
942   * each bit in it has the value {@code true} if and only if it both initially had the value {@code true} and the
943   * corresponding bit in the bit set argument also had the value {@code true}.
944   *
945   * @param set
946   *          a bit set
947   */
948  public void and(BitSetFX set) {
949    if (this == set)
950      return;
951
952    while (wordsInUse > set.wordsInUse)
953      words[--wordsInUse] = 0;
954
955    // Perform logical AND on words in common
956    for (int i = 0; i < wordsInUse; i++)
957      words[i] &= set.words[i];
958
959    recalculateWordsInUse();
960    checkInvariants();
961  }
962
963  /**
964   * Performs a logical <b>OR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in
965   * it has the value {@code true} if and only if it either already had the value {@code true} or the corresponding bit
966   * in the bit set argument has the value {@code true}.
967   *
968   * @param set
969   *          a bit set
970   */
971  public void or(BitSetFX set) {
972    if (this == set)
973      return;
974
975    int wordsInCommon = Math.min(wordsInUse, set.wordsInUse);
976
977    if (wordsInUse < set.wordsInUse) {
978      ensureCapacity(set.wordsInUse);
979      wordsInUse = set.wordsInUse;
980    }
981
982    // Perform logical OR on words in common
983    for (int i = 0; i < wordsInCommon; i++)
984      words[i] |= set.words[i];
985
986    // Copy any remaining words
987    if (wordsInCommon < set.wordsInUse)
988      System.arraycopy(set.words, wordsInCommon, words, wordsInCommon, wordsInUse - wordsInCommon);
989
990    // recalculateWordsInUse() is unnecessary
991    checkInvariants();
992  }
993
994  /**
995   * Performs a logical <b>XOR</b> of this bit set with the bit set argument. This bit set is modified so that a bit in
996   * it has the value {@code true} if and only if one of the following statements holds:
997   * <ul>
998   * <li>The bit initially has the value {@code true}, and the corresponding bit in the argument has the value
999   * {@code false}.
1000   * <li>The bit initially has the value {@code false}, and the corresponding bit in the argument has the value
1001   * {@code true}.
1002   * </ul>
1003   *
1004   * @param set
1005   *          a bit set
1006   */
1007  public void xor(BitSetFX set) {
1008    int wordsInCommon = Math.min(wordsInUse, set.wordsInUse);
1009
1010    if (wordsInUse < set.wordsInUse) {
1011      ensureCapacity(set.wordsInUse);
1012      wordsInUse = set.wordsInUse;
1013    }
1014
1015    // Perform logical XOR on words in common
1016    for (int i = 0; i < wordsInCommon; i++)
1017      words[i] ^= set.words[i];
1018
1019    // Copy any remaining words
1020    if (wordsInCommon < set.wordsInUse)
1021      System.arraycopy(set.words, wordsInCommon, words, wordsInCommon, set.wordsInUse - wordsInCommon);
1022
1023    recalculateWordsInUse();
1024    checkInvariants();
1025  }
1026
1027  /**
1028   * Clears all of the bits in this {@code BitSet} whose corresponding bit is set in the specified {@code BitSet}.
1029   *
1030   * @param set
1031   *          the {@code BitSet} with which to mask this {@code BitSet}
1032   * @since 1.2
1033   */
1034  public void andNot(BitSetFX set) {
1035    // Perform logical (a & !b) on words in common
1036    for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
1037      words[i] &= ~set.words[i];
1038
1039    recalculateWordsInUse();
1040    checkInvariants();
1041  }
1042
1043  /**
1044   * Returns the hash code value for this bit set. The hash code depends only on which bits are set within this
1045   * {@code BitSet}.
1046   *
1047   * <p>
1048   * The hash code is defined to be the result of the following calculation:
1049   * 
1050   * <pre>
1051   *  {@code
1052   * public int hashCode() {
1053   *     long h = 1234;
1054   *     long[] words = toLongArray();
1055   *     for (int i = words.length; --i >= 0; )
1056   *         h ^= words[i] * (i + 1);
1057   *     return (int)((h >> 32) ^ h);
1058   * }}
1059   * </pre>
1060   * 
1061   * Note that the hash code changes if the set of bits is altered.
1062   *
1063   * @return the hash code value for this bit set
1064   */
1065  public int hashCode() {
1066    long h = 1234;
1067    for (int i = wordsInUse; --i >= 0;)
1068      h ^= words[i] * (i + 1);
1069
1070    return (int) ((h >> 32) ^ h);
1071  }
1072
1073  /**
1074   * Returns the number of bits of space actually in use by this {@code BitSet} to represent bit values. The maximum
1075   * element in the set is the size - 1st element.
1076   *
1077   * @return the number of bits currently in this bit set
1078   */
1079  public int space() {
1080    return words.length * BITS_PER_WORD;
1081  }
1082
1083  public int size() {
1084    return cardinality();
1085  }
1086
1087  /**
1088   * Compares this object against the specified object. The result is {@code true} if and only if the argument is not
1089   * {@code null} and is a {@code Bitset} object that has exactly the same set of bits set to {@code true} as this bit
1090   * set. That is, for every nonnegative {@code int} index {@code k},
1091   * 
1092   * <pre>
1093   * ((BitSet) obj).get(k) == this.get(k)
1094   * </pre>
1095   * 
1096   * must be true. The current sizes of the two bit sets are not compared.
1097   *
1098   * @param obj
1099   *          the object to compare with
1100   * @return {@code true} if the objects are the same; {@code false} otherwise
1101   * @see #space()
1102   */
1103  public boolean equals(Object obj) {
1104    if (!(obj instanceof BitSetFX))
1105      return false;
1106    if (this == obj)
1107      return true;
1108
1109    BitSetFX set = (BitSetFX) obj;
1110
1111    trimToSize();
1112    set.trimToSize();
1113
1114    checkInvariants();
1115    set.checkInvariants();
1116
1117    if (wordsInUse != set.wordsInUse)
1118      return false;
1119
1120    // Check words in use by both BitSets
1121    for (int i = 0; i < wordsInUse; i++)
1122      if (words[i] != set.words[i])
1123        return false;
1124
1125    return true;
1126  }
1127
1128  /**
1129   * Cloning this {@code BitSet} produces a new {@code BitSet} that is equal to it. The clone of the bit set is another
1130   * bit set that has exactly the same bits set to {@code true} as this bit set.
1131   *
1132   * @return a clone of this bit set
1133   * @see #space()
1134   */
1135  public Object clone() {
1136    if (!sizeIsSticky)
1137      trimToSize();
1138
1139    try {
1140      BitSetFX result = (BitSetFX) super.clone();
1141      result.words = words.clone();
1142      result.checkInvariants();
1143      return result;
1144    } catch (CloneNotSupportedException e) {
1145      throw new InternalError(e);
1146    }
1147  }
1148
1149  /**
1150   * Attempts to reduce internal storage used for the bits in this bit set. Calling this method may, but is not required
1151   * to, affect the value returned by a subsequent call to the {@link #space()} method.
1152   */
1153  private void trimToSize() {
1154    if (wordsInUse != words.length) {
1155      words = Arrays.copyOf(words, wordsInUse);
1156      checkInvariants();
1157    }
1158  }
1159
1160  /**
1161   * Save the state of the {@code BitSet} instance to a stream (i.e., serialize it).
1162   */
1163  private void writeObject(ObjectOutputStream s) throws IOException {
1164
1165    checkInvariants();
1166
1167    if (!sizeIsSticky)
1168      trimToSize();
1169
1170    ObjectOutputStream.PutField fields = s.putFields();
1171    fields.put("bits", words);
1172    s.writeFields();
1173  }
1174
1175  /**
1176   * Reconstitute the {@code BitSet} instance from a stream (i.e., deserialize it).
1177   */
1178  private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
1179
1180    ObjectInputStream.GetField fields = s.readFields();
1181    words = (long[]) fields.get("bits", null);
1182
1183    // Assume maximum length then find real length
1184    // because recalculateWordsInUse assumes maintenance
1185    // or reduction in logical size
1186    wordsInUse = words.length;
1187    recalculateWordsInUse();
1188    sizeIsSticky = (words.length > 0 && words[words.length - 1] == 0L); // heuristic
1189    checkInvariants();
1190  }
1191
1192  /**
1193   * Returns a string representation of this bit set. For every index for which this {@code BitSet} contains a bit in
1194   * the set state, the decimal representation of that index is included in the result. Such indices are listed in order
1195   * from lowest to highest, separated by ",&nbsp;" (a comma and a space) and surrounded by braces, resulting in the
1196   * usual mathematical notation for a set of integers.
1197   *
1198   * <p>
1199   * Example:
1200   * 
1201   * <pre>
1202   * 
1203   * BitSet drPepper = new BitSet();
1204   * </pre>
1205   * 
1206   * Now {@code drPepper.toString()} returns "{@code {}}".
1207   * 
1208   * <pre>
1209   * drPepper.set(2);
1210   * </pre>
1211   * 
1212   * Now {@code drPepper.toString()} returns "{@code {2}}".
1213   * 
1214   * <pre>
1215   * drPepper.set(4);
1216   * drPepper.set(10);
1217   * </pre>
1218   * 
1219   * Now {@code drPepper.toString()} returns "{@code {2, 4, 10}}".
1220   *
1221   * @return a string representation of this bit set
1222   */
1223  public String toString() {
1224    checkInvariants();
1225
1226    int numBits = (wordsInUse > 128) ? cardinality() : wordsInUse * BITS_PER_WORD;
1227    StringBuilder b = new StringBuilder(6 * numBits + 2);
1228    b.append('{');
1229
1230    int i = nextSetBit(0);
1231    if (i != -1) {
1232      b.append(i);
1233      while (true) {
1234        if (++i < 0)
1235          break;
1236        if ((i = nextSetBit(i)) < 0)
1237          break;
1238        int endOfRun = nextClearBit(i);
1239        do {
1240          b.append(", ").append(i);
1241        } while (++i != endOfRun);
1242      }
1243    }
1244
1245    b.append('}');
1246    return b.toString();
1247  }
1248
1249  /**
1250   * Returns a stream of indices for which this {@code BitSet} contains a bit in the set state. The indices are returned
1251   * in order, from lowest to highest. The size of the stream is the number of bits in the set state, equal to the value
1252   * returned by the {@link #cardinality()} method.
1253   *
1254   * <p>
1255   * The bit set must remain constant during the execution of the terminal stream operation. Otherwise, the result of
1256   * the terminal stream operation is undefined.
1257   *
1258   * @return a stream of integers representing set indices
1259   * @since 1.8
1260   */
1261  public Stream<Integer> stream() {
1262    return StreamSupport.stream(
1263        () -> Spliterators
1264            .spliterator(iterator(), cardinality(), Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED),
1265        Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED,
1266        false);
1267  }
1268
1269  public Iterator<Integer> iterator() {
1270    class BitSetIterator implements PrimitiveIterator.OfInt {
1271
1272      int next = nextSetBit(0);
1273
1274      @Override
1275      public boolean hasNext() {
1276        return next != -1;
1277      }
1278
1279      @Override
1280      public int nextInt() {
1281        if (next != -1) {
1282          int ret = next;
1283          next = nextSetBit(next + 1);
1284          return ret;
1285        } else {
1286          throw new NoSuchElementException();
1287        }
1288      }
1289    }
1290    return new BitSetIterator();
1291  }
1292
1293  public void and(final BitSetFX... sets) {
1294    and(Arrays.asList(sets));
1295  }
1296
1297  public void and(final Collection<BitSetFX> sets) {
1298    if (sets.isEmpty())
1299      return;
1300
1301    final Integer minWordsInUse = sets.stream().map(set -> set.wordsInUse).min(Integer::compare).get();
1302    while (wordsInUse > minWordsInUse)
1303      words[--wordsInUse] = 0;
1304
1305    // Perform logical AND on words in common
1306    for (int i = 0; i < wordsInUse; i++)
1307      for (BitSetFX set : sets)
1308        words[i] &= set.words[i];
1309
1310    recalculateWordsInUse();
1311    checkInvariants();
1312  }
1313
1314  public BitSetFX(final BitSetFX b) {
1315    this();
1316    or(b);
1317  }
1318
1319  public BitSetFX(final Collection<? extends Integer> c) {
1320    this();
1321    addAll(c);
1322  }
1323
1324  public boolean geq(final BitSetFX set) {
1325    trimToSize();
1326    set.trimToSize();
1327
1328    checkInvariants();
1329    set.checkInvariants();
1330
1331    if (set.wordsInUse == 0)
1332      return true;
1333    if (set.wordsInUse > wordsInUse)
1334      return false;
1335    for (int i = set.wordsInUse - 1; i >= 0; i--)
1336      if ((set.words[i] & words[i]) != set.words[i])
1337        return false;
1338    return true;
1339  }
1340
1341  public boolean contains(Object o) {
1342    return get((Integer) o);
1343  }
1344
1345  public boolean containsAll(Collection<?> c) {
1346    if (c instanceof BitSetFX) {
1347      final BitSetFX other = (BitSetFX) c;
1348      return this.geq(other);
1349    } else {
1350      for (Object o : c)
1351        if (!get((Integer) o))
1352          return false;
1353      return true;
1354    }
1355  }
1356
1357  public boolean add(final Integer e) {
1358    if (get(e))
1359      return false;
1360    set(e);
1361    return true;
1362  }
1363
1364  public boolean addAll(final Collection<? extends Integer> c) {
1365    if (c instanceof BitSetFX) {
1366      final int cardinality = cardinality();
1367      or((BitSetFX) c);
1368      return cardinality != cardinality();
1369    } else {
1370      boolean changed = false;
1371      for (int e : c)
1372        changed |= add(e);
1373      return changed;
1374    }
1375  }
1376
1377  public void addRange(int start, int end) {
1378    set(start, end);
1379  }
1380
1381  public boolean remove(Object o) {
1382    if (o instanceof Integer) {
1383      final int e = (Integer) o;
1384      if (get(e)) {
1385        clear(e);
1386        return true;
1387      }
1388    }
1389    return false;
1390  }
1391
1392  public boolean removeAll(Collection<?> c) {
1393    if (c instanceof BitSetFX) {
1394      final int cardinality = cardinality();
1395      andNot((BitSetFX) c);
1396      return cardinality != cardinality();
1397    } else {
1398      boolean changed = false;
1399      for (Object e : c)
1400        changed |= remove(e);
1401      return changed;
1402    }
1403  }
1404
1405  @Override
1406  public boolean retainAll(Collection<?> c) {
1407    if (c instanceof BitSetFX) {
1408      final int cardinality = cardinality();
1409      and((BitSetFX) c);
1410      return cardinality != cardinality();
1411    } else {
1412      boolean changed = false;
1413      for (int i = nextSetBit(0); i != -1; i = nextSetBit(i))
1414        if (!c.contains(i)) {
1415          clear(i);
1416          changed = true;
1417        }
1418      return changed;
1419    }
1420  }
1421
1422  public Comparator<? super Integer> comparator() {
1423    return Integer::compare;
1424  }
1425
1426  public SortedSet<Integer> subSet(Integer fromElement, Integer toElement) {
1427    return get(fromElement, toElement);
1428  }
1429
1430  public SortedSet<Integer> headSet(Integer toElement) {
1431    return get(0, toElement);
1432  }
1433
1434  public SortedSet<Integer> tailSet(Integer fromElement) {
1435    return get(fromElement, length());
1436  }
1437
1438  public Integer first() {
1439    return nextSetBit(0);
1440  }
1441
1442  public Integer last() {
1443    return length() - 1;
1444  }
1445
1446}