1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.collection.BitSet;
13 
14 // import java.nio.ByteBuffer;
15 // import java.nio.ByteOrder;
16 // import java.nio.LongBuffer;
17 // import java.util.function.IntConsumer;
18 // import java.util.stream.IntStream;
19 // import java.util.stream.StreamSupport;
20 
21 import hunt.Exceptions;
22 import hunt.Long;
23 
24 import std.algorithm;
25 import std.conv;
26 
27 /**
28  * This class implements a vector of bits that grows as needed. Each
29  * component of the bit set has a {@code bool} value. The
30  * bits of a {@code BitSet} are indexed by nonnegative integers.
31  * Individual indexed bits can be examined, set, or cleared. One
32  * {@code BitSet} may be used to modify the contents of another
33  * {@code BitSet} through logical AND, logical inclusive OR, and
34  * logical exclusive OR operations.
35  *
36  * <p>By default, all bits in the set initially have the value
37  * {@code false}.
38  *
39  * <p>Every bit set has a current size, which is the number of bits
40  * of space currently in use by the bit set. Note that the size is
41  * related to the implementation of a bit set, so it may change with
42  * implementation. The length of a bit set relates to logical length
43  * of a bit set and is defined independently of implementation.
44  *
45  * <p>Unless otherwise noted, passing a null parameter to any of the
46  * methods in a {@code BitSet} will result in a
47  * {@code NullPointerException}.
48  *
49  * <p>A {@code BitSet} is not safe for multithreaded use without
50  * external synchronization.
51  *
52  * @author  Arthur van Hoff
53  * @author  Michael McCloskey
54  * @author  Martin Buchholz
55  * @since   1.0
56  */
57 class BitSet  { // : Cloneable, java.io.Serializable
58     /*
59      * BitSets are packed into arrays of "words."  Currently a word is
60      * a long, which consists of 64 bits, requiring 6 address bits.
61      * The choice of word size is determined purely by performance concerns.
62      */
63     private enum int ADDRESS_BITS_PER_WORD = 6;
64     private enum int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
65     private enum int BIT_INDEX_MASK = BITS_PER_WORD - 1;
66 
67     /* Used to shift left or right for a partial word mask */
68     private enum long WORD_MASK = 0xffffffffffffffffL;
69 
70     /**
71      * @serialField bits long[]
72      *
73      * The bits in this BitSet.  The ith bit is stored in bits[i/64] at
74      * bit position i % 64 (where bit position 0 refers to the least
75      * significant bit and 63 refers to the most significant bit).
76      */
77     // private static final ObjectStreamField[] serialPersistentFields = {
78     //     new ObjectStreamField("bits", long[].class),
79     // };
80 
81     /**
82      * The internal field corresponding to the serialField "bits".
83      */
84     private long[] words;
85 
86     /**
87      * The number of words in the logical size of this BitSet.
88      */
89     private size_t wordsInUse = 0;
90 
91     /**
92      * Whether the size of "words" is user-specified.  If so, we assume
93      * the user knows what he's doing and try harder to preserve it.
94      */
95     private bool sizeIsSticky = false;
96 
97     /**
98      * Given a bit index, return word index containing it.
99      */
100     private static size_t wordIndex(size_t bitIndex) {
101         return bitIndex >> ADDRESS_BITS_PER_WORD;
102     }
103 
104     /**
105      * Every method must preserve these invariants.
106      */
107     private void checkInvariants() {
108         assert(wordsInUse == 0 || words[wordsInUse - 1] != 0);
109         assert(wordsInUse >= 0 && wordsInUse <= words.length);
110         assert(wordsInUse == words.length || words[wordsInUse] == 0);
111     }
112 
113     /**
114      * Sets the field wordsInUse to the logical size in words of the bit set.
115      * WARNING:This method assumes that the number of words actually in use is
116      * less than or equal to the current value of wordsInUse!
117      */
118     private void recalculateWordsInUse() {
119         // Traverse the bitset until a used word is found
120         size_t i;
121         for (i = wordsInUse-1; i >= 0; i--)
122             if (words[i] != 0)
123                 break;
124 
125         wordsInUse = i+1; // The new logical size
126     }
127 
128     /**
129      * Creates a new bit set. All bits are initially {@code false}.
130      */
131     this() {
132         initWords(BITS_PER_WORD);
133         sizeIsSticky = false;
134     }
135 
136     /**
137      * Creates a bit set whose initial size is large enough to explicitly
138      * represent bits with indices in the range {@code 0} through
139      * {@code nbits-1}. All bits are initially {@code false}.
140      *
141      * @param  nbits the initial size of the bit set
142      * @throws NegativeArraySizeException if the specified initial size
143      *         is negative
144      */
145     this(size_t nbits) {
146         // nbits can't be negative; size 0 is OK
147         if (nbits < 0)
148             throw new NegativeArraySizeException("nbits < 0: " ~ nbits.to!string());
149 
150         initWords(nbits);
151         sizeIsSticky = true;
152     }
153 
154     private void initWords(size_t nbits) {
155         words = new long[wordIndex(nbits-1) + 1];
156     }
157 
158     /**
159      * Creates a bit set using words as the internal representation.
160      * The last word (if there is one) must be non-zero.
161      */
162     private this(long[] words) {
163         this.words = words;
164         this.wordsInUse = words.length;
165         checkInvariants();
166     }
167 
168     /**
169      * Returns a new bit set containing all the bits in the given long array.
170      *
171      * <p>More precisely,
172      * <br>{@code BitSet.valueOf(longs).get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)}
173      * <br>for all {@code n < 64 * longs.length}.
174      *
175      * <p>This method is equivalent to
176      * {@code BitSet.valueOf(LongBuffer.wrap(longs))}.
177      *
178      * @param longs a long array containing a little-endian representation
179      *        of a sequence of bits to be used as the initial bits of the
180      *        new bit set
181      * @return a {@code BitSet} containing all the bits in the long array
182      * @since 1.7
183      */
184     // static BitSet valueOf(long[] longs) {
185     //     int n;
186     //     for (n = longs.length; n > 0 && longs[n - 1] == 0; n--){
187     //     }
188     //     return new BitSet(Arrays.copyOf(longs, n));
189     // }
190 
191     /**
192      * Returns a new bit set containing all the bits in the given long
193      * buffer between its position and limit.
194      *
195      * <p>More precisely,
196      * <br>{@code BitSet.valueOf(lb).get(n) == ((lb.get(lb.position()+n/64) & (1L<<(n%64))) != 0)}
197      * <br>for all {@code n < 64 * lb.remaining()}.
198      *
199      * <p>The long buffer is not modified by this method, and no
200      * reference to the buffer is retained by the bit set.
201      *
202      * @param lb a long buffer containing a little-endian representation
203      *        of a sequence of bits between its position and limit, to be
204      *        used as the initial bits of the new bit set
205      * @return a {@code BitSet} containing all the bits in the buffer in the
206      *         specified range
207      * @since 1.7
208      */
209     // static BitSet valueOf(LongBuffer lb) {
210     //     lb = lb.slice();
211     //     int n;
212     //     for (n = lb.remaining(); n > 0 && lb.get(n - 1) == 0; n--){
213     //     }
214     //     long[] words = new long[n];
215     //     lb.get(words);
216     //     return new BitSet(words);
217     // }
218 
219     /**
220      * Returns a new bit set containing all the bits in the given byte array.
221      *
222      * <p>More precisely,
223      * <br>{@code BitSet.valueOf(bytes).get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)}
224      * <br>for all {@code n <  8 * bytes.length}.
225      *
226      * <p>This method is equivalent to
227      * {@code BitSet.valueOf(ByteBuffer.wrap(bytes))}.
228      *
229      * @param bytes a byte array containing a little-endian
230      *        representation of a sequence of bits to be used as the
231      *        initial bits of the new bit set
232      * @return a {@code BitSet} containing all the bits in the byte array
233      * @since 1.7
234      */
235     // static BitSet valueOf(byte[] bytes) {
236     //     return BitSet.valueOf(ByteBuffer.wrap(bytes));
237     // }
238 
239     /**
240      * Returns a new bit set containing all the bits in the given byte
241      * buffer between its position and limit.
242      *
243      * <p>More precisely,
244      * <br>{@code BitSet.valueOf(bb).get(n) == ((bb.get(bb.position()+n/8) & (1<<(n%8))) != 0)}
245      * <br>for all {@code n < 8 * bb.remaining()}.
246      *
247      * <p>The byte buffer is not modified by this method, and no
248      * reference to the buffer is retained by the bit set.
249      *
250      * @param bb a byte buffer containing a little-endian representation
251      *        of a sequence of bits between its position and limit, to be
252      *        used as the initial bits of the new bit set
253      * @return a {@code BitSet} containing all the bits in the buffer in the
254      *         specified range
255      * @since 1.7
256      */
257     // static BitSet valueOf(ByteBuffer bb) {
258     //     bb = bb.slice().order(ByteOrder.LITTLE_ENDIAN);
259     //     int n;
260     //     for (n = bb.remaining(); n > 0 && bb.get(n - 1) == 0; n--)
261     //         ;
262     //     long[] words = new long[(n + 7) / 8];
263     //     bb.limit(n);
264     //     int i = 0;
265     //     while (bb.remaining() >= 8)
266     //         words[i++] = bb.getLong();
267     //     for (int remaining = bb.remaining(), j = 0; j < remaining; j++)
268     //         words[i] |= (bb.get() & 0xffL) << (8 * j);
269     //     return new BitSet(words);
270     // }
271 
272     /**
273      * Returns a new byte array containing all the bits in this bit set.
274      *
275      * <p>More precisely, if
276      * <br>{@code byte[] bytes = s.toByteArray();}
277      * <br>then {@code bytes.length == (s.length()+7)/8} and
278      * <br>{@code s.get(n) == ((bytes[n/8] & (1<<(n%8))) != 0)}
279      * <br>for all {@code n < 8 * bytes.length}.
280      *
281      * @return a byte array containing a little-endian representation
282      *         of all the bits in this bit set
283      * @since 1.7
284     */
285     // byte[] toByteArray() {
286     //     int n = wordsInUse;
287     //     if (n == 0)
288     //         return new byte[0];
289     //     int len = 8 * (n-1);
290     //     for (long x = words[n - 1]; x != 0; x >>>= 8)
291     //         len++;
292     //     byte[] bytes = new byte[len];
293     //     ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
294     //     for (int i = 0; i < n - 1; i++)
295     //         bb.putLong(words[i]);
296     //     for (long x = words[n - 1]; x != 0; x >>>= 8)
297     //         bb.put((byte) (x & 0xff));
298     //     return bytes;
299     // }
300 
301     /**
302      * Returns a new long array containing all the bits in this bit set.
303      *
304      * <p>More precisely, if
305      * <br>{@code long[] longs = s.toLongArray();}
306      * <br>then {@code longs.length == (s.length()+63)/64} and
307      * <br>{@code s.get(n) == ((longs[n/64] & (1L<<(n%64))) != 0)}
308      * <br>for all {@code n < 64 * longs.length}.
309      *
310      * @return a long array containing a little-endian representation
311      *         of all the bits in this bit set
312      * @since 1.7
313     */
314     long[] toLongArray() {
315         return words[0..wordsInUse].dup; // Arrays.copyOf(words, wordsInUse);
316     }
317 
318     /**
319      * Ensures that the BitSet can hold enough words.
320      * @param wordsRequired the minimum acceptable number of words.
321      */
322     private void ensureCapacity(size_t wordsRequired) {
323         size_t len = words.length;
324         if (len < wordsRequired) {
325             // Allocate larger of doubled size or required size
326             size_t request = max(2 * len, wordsRequired);
327             long[] newWords = new long[request];
328             newWords[0..len] = words[0..$];
329             words = newWords;
330             sizeIsSticky = false;
331         }
332     }
333 
334     /**
335      * Ensures that the BitSet can accommodate a given wordIndex,
336      * temporarily violating the invariants.  The caller must
337      * restore the invariants before returning to the user,
338      * possibly using recalculateWordsInUse().
339      * @param wordIndex the index to be accommodated.
340      */
341     private void expandTo(size_t wordIndex) {
342         size_t wordsRequired = wordIndex+1;
343         if (wordsInUse < wordsRequired) {
344             ensureCapacity(wordsRequired);
345             wordsInUse = wordsRequired;
346         }
347     }
348 
349     /**
350      * Checks that fromIndex ... toIndex is a valid range of bit indices.
351      */
352     private static void checkRange(size_t fromIndex, size_t toIndex) {
353         if (fromIndex < 0)
354             throw new IndexOutOfBoundsException("fromIndex < 0: " ~ fromIndex.to!string());
355         if (toIndex < 0)
356             throw new IndexOutOfBoundsException("toIndex < 0: " ~ toIndex.to!string());
357         if (fromIndex > toIndex)
358             throw new IndexOutOfBoundsException("fromIndex: " ~ fromIndex.to!string() ~
359                                                 " > toIndex: " ~ toIndex.to!string());
360     }
361 
362     /**
363      * Sets the bit at the specified index to the complement of its
364      * current value.
365      *
366      * @param  bitIndex the index of the bit to flip
367      * @throws IndexOutOfBoundsException if the specified index is negative
368      * @since  1.4
369      */
370     void flip(size_t bitIndex) {
371         if (bitIndex < 0)
372             throw new IndexOutOfBoundsException("bitIndex < 0: " ~ bitIndex.to!string());
373 
374         size_t wordIndex = wordIndex(bitIndex);
375         expandTo(wordIndex);
376 
377         words[wordIndex] ^= (1L << bitIndex);
378 
379         recalculateWordsInUse();
380         checkInvariants();
381     }
382 
383     // /**
384     //  * Sets each bit from the specified {@code fromIndex} (inclusive) to the
385     //  * specified {@code toIndex} (exclusive) to the complement of its current
386     //  * value.
387     //  *
388     //  * @param  fromIndex index of the first bit to flip
389     //  * @param  toIndex index after the last bit to flip
390     //  * @throws IndexOutOfBoundsException if {@code fromIndex} is negative,
391     //  *         or {@code toIndex} is negative, or {@code fromIndex} is
392     //  *         larger than {@code toIndex}
393     //  * @since  1.4
394     //  */
395     // void flip(int fromIndex, int toIndex) {
396     //     checkRange(fromIndex, toIndex);
397 
398     //     if (fromIndex == toIndex)
399     //         return;
400 
401     //     int startWordIndex = wordIndex(fromIndex);
402     //     int endWordIndex   = wordIndex(toIndex - 1);
403     //     expandTo(endWordIndex);
404 
405     //     long firstWordMask = WORD_MASK << fromIndex;
406     //     long lastWordMask  = WORD_MASK >>> -toIndex;
407     //     if (startWordIndex == endWordIndex) {
408     //         // Case 1: One word
409     //         words[startWordIndex] ^= (firstWordMask & lastWordMask);
410     //     } else {
411     //         // Case 2: Multiple words
412     //         // Handle first word
413     //         words[startWordIndex] ^= firstWordMask;
414 
415     //         // Handle intermediate words, if any
416     //         for (int i = startWordIndex+1; i < endWordIndex; i++)
417     //             words[i] ^= WORD_MASK;
418 
419     //         // Handle last word
420     //         words[endWordIndex] ^= lastWordMask;
421     //     }
422 
423     //     recalculateWordsInUse();
424     //     checkInvariants();
425     // }
426 
427     /**
428      * Sets the bit at the specified index to {@code true}.
429      *
430      * @param  bitIndex a bit index
431      * @throws IndexOutOfBoundsException if the specified index is negative
432      * @since  1.0
433      */
434     void set(size_t bitIndex) {
435         if (bitIndex < 0)
436             throw new IndexOutOfBoundsException("bitIndex < 0: " ~ bitIndex.to!string());
437 
438         size_t wordIndex = wordIndex(bitIndex);
439         expandTo(wordIndex);
440        
441         words[wordIndex] |= (1L << bitIndex); // Restores invariants
442 
443         checkInvariants();
444     }
445 
446     /**
447      * Sets the bit at the specified index to the specified value.
448      *
449      * @param  bitIndex a bit index
450      * @param  value a bool value to set
451      * @throws IndexOutOfBoundsException if the specified index is negative
452      * @since  1.4
453      */
454     void set(int bitIndex, bool value) {
455         if (value)
456             set(bitIndex);
457         else
458             clear(bitIndex);
459     }
460 
461     /**
462      * Sets the bits from the specified {@code fromIndex} (inclusive) to the
463      * specified {@code toIndex} (exclusive) to {@code true}.
464      *
465      * @param  fromIndex index of the first bit to be set
466      * @param  toIndex index after the last bit to be set
467      * @throws IndexOutOfBoundsException if {@code fromIndex} is negative,
468      *         or {@code toIndex} is negative, or {@code fromIndex} is
469      *         larger than {@code toIndex}
470      * @since  1.4
471      */
472     void set(int fromIndex, int toIndex) {
473         checkRange(fromIndex, toIndex);
474 
475         if (fromIndex == toIndex)
476             return;
477 
478         // Increase capacity if necessary
479         size_t startWordIndex = wordIndex(fromIndex);
480         size_t endWordIndex   = wordIndex(toIndex - 1);
481         expandTo(endWordIndex);
482 
483         long firstWordMask = WORD_MASK << fromIndex;
484         long lastWordMask  = WORD_MASK >>> -toIndex;
485         if (startWordIndex == endWordIndex) {
486             // Case 1: One word
487             words[startWordIndex] |= (firstWordMask & lastWordMask);
488         } else {
489             // Case 2: Multiple words
490             // Handle first word
491             words[startWordIndex] |= firstWordMask;
492 
493             // Handle intermediate words, if any
494             for (size_t i = startWordIndex+1; i < endWordIndex; i++)
495                 words[i] = WORD_MASK;
496 
497             // Handle last word (restores invariants)
498             words[endWordIndex] |= lastWordMask;
499         }
500 
501         checkInvariants();
502     }
503 
504     /**
505      * Sets the bits from the specified {@code fromIndex} (inclusive) to the
506      * specified {@code toIndex} (exclusive) to the specified value.
507      *
508      * @param  fromIndex index of the first bit to be set
509      * @param  toIndex index after the last bit to be set
510      * @param  value value to set the selected bits to
511      * @throws IndexOutOfBoundsException if {@code fromIndex} is negative,
512      *         or {@code toIndex} is negative, or {@code fromIndex} is
513      *         larger than {@code toIndex}
514      * @since  1.4
515      */
516     void set(int fromIndex, int toIndex, bool value) {
517         if (value)
518             set(fromIndex, toIndex);
519         else
520             clear(fromIndex, toIndex);
521     }
522 
523     /**
524      * Sets the bit specified by the index to {@code false}.
525      *
526      * @param  bitIndex the index of the bit to be cleared
527      * @throws IndexOutOfBoundsException if the specified index is negative
528      * @since  1.0
529      */
530     void clear(size_t bitIndex) {
531         if (bitIndex < 0)
532             throw new IndexOutOfBoundsException("bitIndex < 0: " ~ bitIndex.to!string());
533 
534         size_t wordIndex = wordIndex(bitIndex);
535         if (wordIndex >= wordsInUse)
536             return;
537 
538         words[wordIndex] &= ~(1L << bitIndex);
539 
540         recalculateWordsInUse();
541         checkInvariants();
542     }
543 
544     /**
545      * Sets the bits from the specified {@code fromIndex} (inclusive) to the
546      * specified {@code toIndex} (exclusive) to {@code false}.
547      *
548      * @param  fromIndex index of the first bit to be cleared
549      * @param  toIndex index after the last bit to be cleared
550      * @throws IndexOutOfBoundsException if {@code fromIndex} is negative,
551      *         or {@code toIndex} is negative, or {@code fromIndex} is
552      *         larger than {@code toIndex}
553      * @since  1.4
554      */
555     void clear(size_t fromIndex, size_t toIndex) {
556         checkRange(fromIndex, toIndex);
557 
558         if (fromIndex == toIndex)
559             return;
560 
561         size_t startWordIndex = wordIndex(fromIndex);
562         if (startWordIndex >= wordsInUse)
563             return;
564 
565         size_t endWordIndex = wordIndex(toIndex - 1);
566         if (endWordIndex >= wordsInUse) {
567             toIndex = length();
568             endWordIndex = wordsInUse - 1;
569         }
570 
571         long firstWordMask = WORD_MASK << fromIndex;
572         long lastWordMask  = WORD_MASK >>> -toIndex;
573         if (startWordIndex == endWordIndex) {
574             // Case 1: One word
575             words[startWordIndex] &= ~(firstWordMask & lastWordMask);
576         } else {
577             // Case 2: Multiple words
578             // Handle first word
579             words[startWordIndex] &= ~firstWordMask;
580 
581             // Handle intermediate words, if any
582             for (size_t i = startWordIndex+1; i < endWordIndex; i++)
583                 words[i] = 0;
584 
585             // Handle last word
586             words[endWordIndex] &= ~lastWordMask;
587         }
588 
589         recalculateWordsInUse();
590         checkInvariants();
591     }
592 
593     /**
594      * Sets all of the bits in this BitSet to {@code false}.
595      *
596      * @since 1.4
597      */
598     void clear() {
599         while (wordsInUse > 0)
600             words[--wordsInUse] = 0;
601     }
602 
603     /**
604      * Returns the value of the bit with the specified index. The value
605      * is {@code true} if the bit with the index {@code bitIndex}
606      * is currently set in this {@code BitSet}; otherwise, the result
607      * is {@code false}.
608      *
609      * @param  bitIndex   the bit index
610      * @return the value of the bit with the specified index
611      * @throws IndexOutOfBoundsException if the specified index is negative
612      */
613     bool get(size_t bitIndex) {
614         if (bitIndex < 0)
615             throw new IndexOutOfBoundsException("bitIndex < 0: " ~ bitIndex.to!string());
616 
617         checkInvariants();
618 
619         size_t wordIndex = wordIndex(bitIndex);
620         return (wordIndex < wordsInUse)
621             && ((words[wordIndex] & (1L << bitIndex)) != 0);
622     }
623 
624     /**
625      * Returns a new {@code BitSet} composed of bits from this {@code BitSet}
626      * from {@code fromIndex} (inclusive) to {@code toIndex} (exclusive).
627      *
628      * @param  fromIndex index of the first bit to include
629      * @param  toIndex index after the last bit to include
630      * @return a new {@code BitSet} from a range of this {@code BitSet}
631      * @throws IndexOutOfBoundsException if {@code fromIndex} is negative,
632      *         or {@code toIndex} is negative, or {@code fromIndex} is
633      *         larger than {@code toIndex}
634      * @since  1.4
635      */
636     BitSet get(size_t fromIndex, size_t toIndex) {
637         checkRange(fromIndex, toIndex);
638 
639         checkInvariants();
640 
641         size_t len = length();
642 
643         // If no set bits in range return empty bitset
644         if (len <= fromIndex || fromIndex == toIndex)
645             return new BitSet(0);
646 
647         // An optimization
648         if (toIndex > len)
649             toIndex = len;
650 
651         BitSet result = new BitSet(toIndex - fromIndex);
652         size_t targetWords = wordIndex(toIndex - fromIndex - 1) + 1;
653         size_t sourceIndex = wordIndex(fromIndex);
654         bool wordAligned = ((fromIndex & BIT_INDEX_MASK) == 0);
655 
656         // Process all words but the last word
657         for (size_t i = 0; i < targetWords - 1; i++, sourceIndex++)
658             result.words[i] = wordAligned ? words[sourceIndex] :
659                 (words[sourceIndex] >>> fromIndex) |
660                 (words[sourceIndex+1] << -fromIndex);
661 
662         // Process the last word
663         long lastWordMask = WORD_MASK >>> -toIndex;
664         result.words[targetWords - 1] =
665             ((toIndex-1) & BIT_INDEX_MASK) < (fromIndex & BIT_INDEX_MASK)
666             ? /* straddles source words */
667             ((words[sourceIndex] >>> fromIndex) |
668              (words[sourceIndex+1] & lastWordMask) << -fromIndex)
669             :
670             ((words[sourceIndex] & lastWordMask) >>> fromIndex);
671 
672         // Set wordsInUse correctly
673         result.wordsInUse = targetWords;
674         result.recalculateWordsInUse();
675         result.checkInvariants();
676 
677         return result;
678     }
679 
680     /**
681      * Returns the index of the first bit that is set to {@code true}
682      * that occurs on or after the specified starting index. If no such
683      * bit exists then {@code -1} is returned.
684      *
685      * <p>To iterate over the {@code true} bits in a {@code BitSet},
686      * use the following loop:
687      *
688      *  <pre> {@code
689      * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
690      *     // operate on index i here
691      *     if (i == Integer.MAX_VALUE) {
692      *         break; // or (i+1) would overflow
693      *     }
694      * }}</pre>
695      *
696      * @param  fromIndex the index to start checking from (inclusive)
697      * @return the index of the next set bit, or {@code -1} if there
698      *         is no such bit
699      * @throws IndexOutOfBoundsException if the specified index is negative
700      * @since  1.4
701      */
702     size_t nextSetBit(size_t fromIndex) {
703         if (fromIndex < 0)
704             throw new IndexOutOfBoundsException("fromIndex < 0: " ~ fromIndex.to!string());
705 
706         checkInvariants();
707 
708         size_t u = wordIndex(fromIndex);
709         if (u >= wordsInUse)
710             return -1;
711 
712         long word = words[u] & (WORD_MASK << fromIndex);
713 
714         while (true) {
715             if (word != 0)
716                 return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
717             if (++u == wordsInUse)
718                 return -1;
719             word = words[u];
720         }
721     }
722 
723     /**
724      * Returns the index of the first bit that is set to {@code false}
725      * that occurs on or after the specified starting index.
726      *
727      * @param  fromIndex the index to start checking from (inclusive)
728      * @return the index of the next clear bit
729      * @throws IndexOutOfBoundsException if the specified index is negative
730      * @since  1.4
731      */
732     size_t nextClearBit(int fromIndex) {
733         // Neither spec nor implementation handle bitsets of maximal length.
734         // See 4816253.
735         if (fromIndex < 0)
736             throw new IndexOutOfBoundsException("fromIndex < 0: " ~ fromIndex.to!string());
737 
738         checkInvariants();
739 
740         size_t u = wordIndex(fromIndex);
741         if (u >= wordsInUse)
742             return fromIndex;
743 
744         long word = ~words[u] & (WORD_MASK << fromIndex);
745 
746         while (true) {
747             if (word != 0)
748                 return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
749             if (++u == wordsInUse)
750                 return cast(int)wordsInUse * BITS_PER_WORD;
751             word = ~words[u];
752         }
753     }
754 
755     /**
756      * Returns the index of the nearest bit that is set to {@code true}
757      * that occurs on or before the specified starting index.
758      * If no such bit exists, or if {@code -1} is given as the
759      * starting index, then {@code -1} is returned.
760      *
761      * <p>To iterate over the {@code true} bits in a {@code BitSet},
762      * use the following loop:
763      *
764      *  <pre> {@code
765      * for (int i = bs.length(); (i = bs.previousSetBit(i-1)) >= 0; ) {
766      *     // operate on index i here
767      * }}</pre>
768      *
769      * @param  fromIndex the index to start checking from (inclusive)
770      * @return the index of the previous set bit, or {@code -1} if there
771      *         is no such bit
772      * @throws IndexOutOfBoundsException if the specified index is less
773      *         than {@code -1}
774      * @since  1.7
775      */
776     size_t previousSetBit(size_t fromIndex) {
777         if (fromIndex < 0) {
778             if (fromIndex == -1)
779                 return -1;
780             throw new IndexOutOfBoundsException(
781                 "fromIndex < -1: " ~ fromIndex.to!string());
782         }
783 
784         checkInvariants();
785 
786         size_t u = wordIndex(fromIndex);
787         if (u >= wordsInUse)
788             return length() - 1;
789 
790         long word = words[u] & (WORD_MASK >>> -(fromIndex+1));
791 
792         while (true) {
793             if (word != 0)
794                 return (u+1) * BITS_PER_WORD - 1 - Long.numberOfLeadingZeros(word);
795             if (u-- == 0)
796                 return -1;
797             word = words[u];
798         }
799     }
800 
801     /**
802      * Returns the index of the nearest bit that is set to {@code false}
803      * that occurs on or before the specified starting index.
804      * If no such bit exists, or if {@code -1} is given as the
805      * starting index, then {@code -1} is returned.
806      *
807      * @param  fromIndex the index to start checking from (inclusive)
808      * @return the index of the previous clear bit, or {@code -1} if there
809      *         is no such bit
810      * @throws IndexOutOfBoundsException if the specified index is less
811      *         than {@code -1}
812      * @since  1.7
813      */
814     size_t previousClearBit(size_t fromIndex) {
815         if (fromIndex < 0) {
816             if (fromIndex == -1)
817                 return -1;
818             throw new IndexOutOfBoundsException(
819                 "fromIndex < -1: " ~ fromIndex.to!string());
820         }
821 
822         checkInvariants();
823 
824         size_t u = wordIndex(fromIndex);
825         if (u >= wordsInUse)
826             return fromIndex;
827 
828         long word = ~words[u] & (WORD_MASK >>> -(fromIndex+1));
829 
830         while (true) {
831             if (word != 0)
832                 return (u+1) * BITS_PER_WORD -1 - Long.numberOfLeadingZeros(word);
833             if (u-- == 0)
834                 return -1;
835             word = ~words[u];
836         }
837     }
838 
839     /**
840      * Returns the "logical size" of this {@code BitSet}: the index of
841      * the highest set bit in the {@code BitSet} plus one. Returns zero
842      * if the {@code BitSet} contains no set bits.
843      *
844      * @return the logical size of this {@code BitSet}
845      * @since  1.2
846      */
847     size_t length() {
848         if (wordsInUse == 0)
849             return 0;
850 
851         return BITS_PER_WORD * (wordsInUse - 1) +
852             (BITS_PER_WORD - Long.numberOfLeadingZeros(words[wordsInUse - 1]));
853     }
854 
855     /**
856      * Returns true if this {@code BitSet} contains no bits that are set
857      * to {@code true}.
858      *
859      * @return bool indicating whether this {@code BitSet} is empty
860      * @since  1.4
861      */
862     bool isEmpty() {
863         return wordsInUse == 0;
864     }
865 
866     /**
867      * Returns true if the specified {@code BitSet} has any bits set to
868      * {@code true} that are also set to {@code true} in this {@code BitSet}.
869      *
870      * @param  set {@code BitSet} to intersect with
871      * @return bool indicating whether this {@code BitSet} intersects
872      *         the specified {@code BitSet}
873      * @since  1.4
874      */
875     bool intersects(BitSet set) {
876         for (size_t i = min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
877             if ((words[i] & set.words[i]) != 0)
878                 return true;
879         return false;
880     }
881 
882     /**
883      * Returns the number of bits set to {@code true} in this {@code BitSet}.
884      *
885      * @return the number of bits set to {@code true} in this {@code BitSet}
886      * @since  1.4
887      */
888     size_t cardinality() {
889         size_t sum = 0;
890         for (size_t i = 0; i < wordsInUse; i++)
891             sum += Long.bitCount(words[i]);
892         return sum;
893     }
894 
895     /**
896      * Performs a logical <b>AND</b> of this target bit set with the
897      * argument bit set. This bit set is modified so that each bit in it
898      * has the value {@code true} if and only if it both initially
899      * had the value {@code true} and the corresponding bit in the
900      * bit set argument also had the value {@code true}.
901      *
902      * @param set a bit set
903      */
904     void and(BitSet set) {
905         if (this == set)
906             return;
907 
908         while (wordsInUse > set.wordsInUse)
909             words[--wordsInUse] = 0;
910 
911         // Perform logical AND on words in common
912         for (size_t i = 0; i < wordsInUse; i++)
913             words[i] &= set.words[i];
914 
915         recalculateWordsInUse();
916         checkInvariants();
917     }
918 
919     /**
920      * Performs a logical <b>OR</b> of this bit set with the bit set
921      * argument. This bit set is modified so that a bit in it has the
922      * value {@code true} if and only if it either already had the
923      * value {@code true} or the corresponding bit in the bit set
924      * argument has the value {@code true}.
925      *
926      * @param set a bit set
927      */
928     void or(BitSet set) {
929         if (this == set)
930             return;
931 
932         size_t wordsInCommon = min(wordsInUse, set.wordsInUse);
933 
934         if (wordsInUse < set.wordsInUse) {
935             ensureCapacity(set.wordsInUse);
936             wordsInUse = set.wordsInUse;
937         }
938 
939         // Perform logical OR on words in common
940         for (size_t i = 0; i < wordsInCommon; i++)
941             words[i] |= set.words[i];
942 
943         // Copy any remaining words
944         if (wordsInCommon < set.wordsInUse) {
945             words[wordsInCommon .. wordsInUse] = set.words[wordsInCommon .. wordsInUse];
946         }
947             // System.arraycopy(set.words, wordsInCommon,
948             //                  words, wordsInCommon,
949             //                  wordsInUse - wordsInCommon);
950 
951         // recalculateWordsInUse() is unnecessary
952         checkInvariants();
953     }
954 
955     /**
956      * Performs a logical <b>XOR</b> of this bit set with the bit set
957      * argument. This bit set is modified so that a bit in it has the
958      * value {@code true} if and only if one of the following
959      * statements holds:
960      * <ul>
961      * <li>The bit initially has the value {@code true}, and the
962      *     corresponding bit in the argument has the value {@code false}.
963      * <li>The bit initially has the value {@code false}, and the
964      *     corresponding bit in the argument has the value {@code true}.
965      * </ul>
966      *
967      * @param  set a bit set
968      */
969     void xor(BitSet set) {
970         size_t wordsInCommon = min(wordsInUse, set.wordsInUse);
971 
972         if (wordsInUse < set.wordsInUse) {
973             ensureCapacity(set.wordsInUse);
974             wordsInUse = set.wordsInUse;
975         }
976 
977         // Perform logical XOR on words in common
978         for (size_t i = 0; i < wordsInCommon; i++)
979             words[i] ^= set.words[i];
980 
981         // Copy any remaining words
982         if (wordsInCommon < set.wordsInUse) {
983             words[wordsInCommon .. wordsInUse] = set.words[wordsInCommon .. wordsInUse];
984         }
985             // System.arraycopy(set.words, wordsInCommon,
986             //                  words, wordsInCommon,
987             //                  set.wordsInUse - wordsInCommon);
988 
989         recalculateWordsInUse();
990         checkInvariants();
991     }
992 
993     /**
994      * Clears all of the bits in this {@code BitSet} whose corresponding
995      * bit is set in the specified {@code BitSet}.
996      *
997      * @param  set the {@code BitSet} with which to mask this
998      *         {@code BitSet}
999      * @since  1.2
1000      */
1001     void andNot(BitSet set) {
1002         // Perform logical (a & !b) on words in common
1003         for (size_t i = min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
1004             words[i] &= ~set.words[i];
1005 
1006         recalculateWordsInUse();
1007         checkInvariants();
1008     }
1009 
1010     /**
1011      * Returns the hash code value for this bit set. The hash code depends
1012      * only on which bits are set within this {@code BitSet}.
1013      *
1014      * <p>The hash code is defined to be the result of the following
1015      * calculation:
1016      *  <pre> {@code
1017      * int hashCode() {
1018      *     long h = 1234;
1019      *     long[] words = toLongArray();
1020      *     for (int i = words.length; --i >= 0; )
1021      *         h ^= words[i] * (i + 1);
1022      *     return (int)((h >> 32) ^ h);
1023      * }}</pre>
1024      * Note that the hash code changes if the set of bits is altered.
1025      *
1026      * @return the hash code value for this bit set
1027      */
1028     override size_t toHash() @trusted nothrow {
1029         long h = 1234;
1030         for (size_t i = wordsInUse; --i >= 0; )
1031             h ^= words[i] * (i + 1);
1032 
1033         return cast(size_t)((h >> 32) ^ h);
1034     }
1035 
1036     /**
1037      * Returns the number of bits of space actually in use by this
1038      * {@code BitSet} to represent bit values.
1039      * The maximum element in the set is the size - 1st element.
1040      *
1041      * @return the number of bits currently in this bit set
1042      */
1043     size_t size() {
1044         return words.length * BITS_PER_WORD;
1045     }
1046 
1047     /**
1048      * Compares this object against the specified object.
1049      * The result is {@code true} if and only if the argument is
1050      * not {@code null} and is a {@code Bitset} object that has
1051      * exactly the same set of bits set to {@code true} as this bit
1052      * set. That is, for every nonnegative {@code int} index {@code k},
1053      * <pre>((BitSet)obj).get(k) == this.get(k)</pre>
1054      * must be true. The current sizes of the two bit sets are not compared.
1055      *
1056      * @param  obj the object to compare with
1057      * @return {@code true} if the objects are the same;
1058      *         {@code false} otherwise
1059      * @see    #size()
1060      */
1061     bool equals(Object obj) {
1062         if (this is obj)
1063             return true;
1064 
1065         BitSet set = cast(BitSet) obj;
1066         if (set is null)
1067             return false;
1068 
1069         checkInvariants();
1070         set.checkInvariants();
1071 
1072         if (wordsInUse != set.wordsInUse)
1073             return false;
1074 
1075         // Check words in use by both BitSets
1076         for (int i = 0; i < wordsInUse; i++)
1077             if (words[i] != set.words[i])
1078                 return false;
1079 
1080         return true;
1081     }
1082 
1083     // /**
1084     //  * Cloning this {@code BitSet} produces a new {@code BitSet}
1085     //  * that is equal to it.
1086     //  * The clone of the bit set is another bit set that has exactly the
1087     //  * same bits set to {@code true} as this bit set.
1088     //  *
1089     //  * @return a clone of this bit set
1090     //  * @see    #size()
1091     //  */
1092     // Object clone() {
1093     //     if (! sizeIsSticky)
1094     //         trimToSize();
1095 
1096     //     try {
1097     //         BitSet result = (BitSet) super.clone();
1098     //         result.words = words.clone();
1099     //         result.checkInvariants();
1100     //         return result;
1101     //     } catch (CloneNotSupportedException e) {
1102     //         throw new InternalError(e);
1103     //     }
1104     // }
1105 
1106     // /**
1107     //  * Attempts to reduce internal storage used for the bits in this bit set.
1108     //  * Calling this method may, but is not required to, affect the value
1109     //  * returned by a subsequent call to the {@link #size()} method.
1110     //  */
1111     // private void trimToSize() {
1112     //     if (wordsInUse != words.length) {
1113     //         words = Arrays.copyOf(words, wordsInUse);
1114     //         checkInvariants();
1115     //     }
1116     // }
1117 
1118     // /**
1119     //  * Save the state of the {@code BitSet} instance to a stream (i.e.,
1120     //  * serialize it).
1121     //  */
1122     // private void writeObject(ObjectOutputStream s)
1123     //     throws IOException {
1124 
1125     //     checkInvariants();
1126 
1127     //     if (! sizeIsSticky)
1128     //         trimToSize();
1129 
1130     //     ObjectOutputStream.PutField fields = s.putFields();
1131     //     fields.put("bits", words);
1132     //     s.writeFields();
1133     // }
1134 
1135     // /**
1136     //  * Reconstitute the {@code BitSet} instance from a stream (i.e.,
1137     //  * deserialize it).
1138     //  */
1139     // private void readObject(ObjectInputStream s)
1140     //     throws IOException, ClassNotFoundException {
1141 
1142     //     ObjectInputStream.GetField fields = s.readFields();
1143     //     words = (long[]) fields.get("bits", null);
1144 
1145     //     // Assume maximum length then find real length
1146     //     // because recalculateWordsInUse assumes maintenance
1147     //     // or reduction in logical size
1148     //     wordsInUse = words.length;
1149     //     recalculateWordsInUse();
1150     //     sizeIsSticky = (words.length > 0 && words[words.length-1] == 0L); // heuristic
1151     //     checkInvariants();
1152     // }
1153 
1154     // /**
1155     //  * Returns a string representation of this bit set. For every index
1156     //  * for which this {@code BitSet} contains a bit in the set
1157     //  * state, the decimal representation of that index is included in
1158     //  * the result. Such indices are listed in order from lowest to
1159     //  * highest, separated by ",&nbsp;" (a comma and a space) and
1160     //  * surrounded by braces, resulting in the usual mathematical
1161     //  * notation for a set of integers.
1162     //  *
1163     //  * <p>Example:
1164     //  * <pre>
1165     //  * BitSet drPepper = new BitSet();</pre>
1166     //  * Now {@code drPepper.toString()} returns "{@code {}}".
1167     //  * <pre>
1168     //  * drPepper.set(2);</pre>
1169     //  * Now {@code drPepper.toString()} returns "{@code {2}}".
1170     //  * <pre>
1171     //  * drPepper.set(4);
1172     //  * drPepper.set(10);</pre>
1173     //  * Now {@code drPepper.toString()} returns "{@code {2, 4, 10}}".
1174     //  *
1175     //  * @return a string representation of this bit set
1176     //  */
1177     // String toString() {
1178     //     checkInvariants();
1179 
1180     //     int numBits = (wordsInUse > 128) ?
1181     //         cardinality() : wordsInUse * BITS_PER_WORD;
1182     //     StringBuilder b = new StringBuilder(6*numBits + 2);
1183     //     b.append('{');
1184 
1185     //     int i = nextSetBit(0);
1186     //     if (i != -1) {
1187     //         b.append(i);
1188     //         while (true) {
1189     //             if (++i < 0) break;
1190     //             if ((i = nextSetBit(i)) < 0) break;
1191     //             int endOfRun = nextClearBit(i);
1192     //             do { b.append(", ").append(i); }
1193     //             while (++i != endOfRun);
1194     //         }
1195     //     }
1196 
1197     //     b.append('}');
1198     //     return b.toString();
1199     // }
1200 
1201     // /**
1202     //  * Returns a stream of indices for which this {@code BitSet}
1203     //  * contains a bit in the set state. The indices are returned
1204     //  * in order, from lowest to highest. The size of the stream
1205     //  * is the number of bits in the set state, equal to the value
1206     //  * returned by the {@link #cardinality()} method.
1207     //  *
1208     //  * <p>The stream binds to this bit set when the terminal stream operation
1209     //  * commences (specifically, the spliterator for the stream is
1210     //  * <a href="Spliterator.html#binding"><em>late-binding</em></a>).  If the
1211     //  * bit set is modified during that operation then the result is undefined.
1212     //  *
1213     //  * @return a stream of integers representing set indices
1214     //  * @since 1.8
1215     //  */
1216     // IntStream stream() {
1217     //     class BitSetSpliterator implements Spliterator.OfInt {
1218     //         private int index; // current bit index for a set bit
1219     //         private int fence; // -1 until used; then one past last bit index
1220     //         private int est;   // size estimate
1221     //         private bool root; // true if root and not split
1222     //         // root == true then size estimate is accurate
1223     //         // index == -1 or index >= fence if fully traversed
1224     //         // Special case when the max bit set is Integer.MAX_VALUE
1225 
1226     //         BitSetSpliterator(int origin, int fence, int est, bool root) {
1227     //             this.index = origin;
1228     //             this.fence = fence;
1229     //             this.est = est;
1230     //             this.root = root;
1231     //         }
1232 
1233     //         private int getFence() {
1234     //             int hi;
1235     //             if ((hi = fence) < 0) {
1236     //                 // Round up fence to maximum cardinality for allocated words
1237     //                 // This is sufficient and cheap for sequential access
1238     //                 // When splitting this value is lowered
1239     //                 hi = fence = (wordsInUse >= wordIndex(Integer.MAX_VALUE))
1240     //                              ? Integer.MAX_VALUE
1241     //                              : wordsInUse << ADDRESS_BITS_PER_WORD;
1242     //                 est = cardinality();
1243     //                 index = nextSetBit(0);
1244     //             }
1245     //             return hi;
1246     //         }
1247 
1248     //         @Override
1249     //         bool tryAdvance(IntConsumer action) {
1250     //             Objects.requireNonNull(action);
1251 
1252     //             int hi = getFence();
1253     //             int i = index;
1254     //             if (i < 0 || i >= hi) {
1255     //                 // Check if there is a final bit set for Integer.MAX_VALUE
1256     //                 if (i == Integer.MAX_VALUE && hi == Integer.MAX_VALUE) {
1257     //                     index = -1;
1258     //                     action.accept(Integer.MAX_VALUE);
1259     //                     return true;
1260     //                 }
1261     //                 return false;
1262     //             }
1263 
1264     //             index = nextSetBit(i + 1, wordIndex(hi - 1));
1265     //             action.accept(i);
1266     //             return true;
1267     //         }
1268 
1269     //         @Override
1270     //         void forEachRemaining(IntConsumer action) {
1271     //             Objects.requireNonNull(action);
1272 
1273     //             int hi = getFence();
1274     //             int i = index;
1275     //             index = -1;
1276 
1277     //             if (i >= 0 && i < hi) {
1278     //                 action.accept(i++);
1279 
1280     //                 int u = wordIndex(i);      // next lower word bound
1281     //                 int v = wordIndex(hi - 1); // upper word bound
1282 
1283     //                 words_loop:
1284     //                 for (; u <= v && i <= hi; u++, i = u << ADDRESS_BITS_PER_WORD) {
1285     //                     long word = words[u] & (WORD_MASK << i);
1286     //                     while (word != 0) {
1287     //                         i = (u << ADDRESS_BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
1288     //                         if (i >= hi) {
1289     //                             // Break out of outer loop to ensure check of
1290     //                             // Integer.MAX_VALUE bit set
1291     //                             break words_loop;
1292     //                         }
1293 
1294     //                         // Flip the set bit
1295     //                         word &= ~(1L << i);
1296 
1297     //                         action.accept(i);
1298     //                     }
1299     //                 }
1300     //             }
1301 
1302     //             // Check if there is a final bit set for Integer.MAX_VALUE
1303     //             if (i == Integer.MAX_VALUE && hi == Integer.MAX_VALUE) {
1304     //                 action.accept(Integer.MAX_VALUE);
1305     //             }
1306     //         }
1307 
1308     //         @Override
1309     //         OfInt trySplit() {
1310     //             int hi = getFence();
1311     //             int lo = index;
1312     //             if (lo < 0) {
1313     //                 return null;
1314     //             }
1315 
1316     //             // Lower the fence to be the upper bound of last bit set
1317     //             // The index is the first bit set, thus this spliterator
1318     //             // covers one bit and cannot be split, or two or more
1319     //             // bits
1320     //             hi = fence = (hi < Integer.MAX_VALUE || !get(Integer.MAX_VALUE))
1321     //                     ? previousSetBit(hi - 1) + 1
1322     //                     : Integer.MAX_VALUE;
1323 
1324     //             // Find the mid point
1325     //             int mid = (lo + hi) >>> 1;
1326     //             if (lo >= mid) {
1327     //                 return null;
1328     //             }
1329 
1330     //             // Raise the index of this spliterator to be the next set bit
1331     //             // from the mid point
1332     //             index = nextSetBit(mid, wordIndex(hi - 1));
1333     //             root = false;
1334 
1335     //             // Don't lower the fence (mid point) of the returned spliterator,
1336     //             // traversal or further splitting will do that work
1337     //             return new BitSetSpliterator(lo, mid, est >>>= 1, false);
1338     //         }
1339 
1340     //         @Override
1341     //         long estimateSize() {
1342     //             getFence(); // force init
1343     //             return est;
1344     //         }
1345 
1346     //         @Override
1347     //         int characteristics() {
1348     //             // Only sized when root and not split
1349     //             return (root ? Spliterator.SIZED : 0) |
1350     //                 Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED;
1351     //         }
1352 
1353     //         @Override
1354     //         Comparator<? super Integer> getComparator() {
1355     //             return null;
1356     //         }
1357     //     }
1358     //     return StreamSupport.intStream(new BitSetSpliterator(0, -1, 0, true), false);
1359     // }
1360 
1361     // /**
1362     //  * Returns the index of the first bit that is set to {@code true}
1363     //  * that occurs on or after the specified starting index and up to and
1364     //  * including the specified word index
1365     //  * If no such bit exists then {@code -1} is returned.
1366     //  *
1367     //  * @param  fromIndex the index to start checking from (inclusive)
1368     //  * @param  toWordIndex the last word index to check (inclusive)
1369     //  * @return the index of the next set bit, or {@code -1} if there
1370     //  *         is no such bit
1371     //  */
1372     // private int nextSetBit(int fromIndex, int toWordIndex) {
1373     //     int u = wordIndex(fromIndex);
1374     //     // Check if out of bounds
1375     //     if (u > toWordIndex)
1376     //         return -1;
1377 
1378     //     long word = words[u] & (WORD_MASK << fromIndex);
1379 
1380     //     while (true) {
1381     //         if (word != 0)
1382     //             return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
1383     //         // Check if out of bounds
1384     //         if (++u > toWordIndex)
1385     //             return -1;
1386     //         word = words[u];
1387     //     }
1388     // }
1389 
1390 }