<commit_before>/*
 * Copyright 2015 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.tomgibara.bits;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.BitSet;
import java.util.Comparator;
import java.util.ListIterator;
import java.util.Random;

import com.tomgibara.bits.BitStore.Matches;
import com.tomgibara.bits.BitStore.Positions;
import com.tomgibara.bits.ImmutableBit.ImmutableOne;
import com.tomgibara.bits.ImmutableBit.ImmutableZero;
import com.tomgibara.hashing.Hasher;
import com.tomgibara.hashing.Hashing;
import com.tomgibara.streams.ReadStream;
import com.tomgibara.streams.StreamSerializer;
import com.tomgibara.streams.WriteStream;

/**
 * <p>
 * Static methods that provide the entry-point for most package functions. This
 * package provides a dense library of bit storage, transformation and streaming
 * functionality, and consequently, this class features a large number of
 * methods; organized into the following categories:
 * 
 * <ul>
 * <li>
 * Helper objects that assist with implementing {@link BitStore} functionality
 * {@link #bitStoreHasher()}, {@link #numericalComparator()} and
 * {@link #lexicalComparator()}.
 * 
 * <li>
 * Methods for creating new {@link BitStore} instances: {@link #store(int)}
 * <code>toStore(...)</code> and <code>asStore(...)</code>.
 * 
 * <li>
 * Methods that return immutable basic {@link BitStore} instances:
 * {@link #noBits()}, {@link #oneBit()}, {@link #zeroBit()}, {@link #ones(int)},
 * {@link #zeros(int)}, {@link #bit(boolean)} and {@link #bits(boolean, int)}.
 * 
 * <li>
 * Methods that adapt common Java I/O primitives into bit readers:
 * <code>readerFrom(...)</code>
 * 
 * <li>
 * Methods that adapt common Java I/O primitives into bit writers:
 * <code>writerTo(...)</code>, {@link #writerToStdout()},
 * {@link #writerToNothing()}.
 * 
 * <li>
 * Methods to assist with growing bit stores: {@link #growableBits()},
 * {@link #growableBits(int)}, {@link #resizedCopyOf(BitStore, int, boolean)}.
 * </ul>
 * 
 * @author <NAME>
 *
 */

public final class Bits {

	private static final Hasher<BitStore> bitStoreHasher = bitStoreHasher((b,s) -> b.writeTo(s));
	
	private static final Comparator<BitStore> numericalComparator = new Comparator<BitStore>() {
		@Override
		public int compare(BitStore a, BitStore b) {
			return a.compareNumericallyTo(b);
		}
	};

	private static final Comparator<BitStore> lexicalComparator = new Comparator<BitStore>() {
		@Override
		public int compare(BitStore a, BitStore b) {
			return a.compareLexicallyTo(b);
		}
	};

	// public
	
	// helpers
	
	public static Hasher<BitStore> bitStoreHasher() {
		return bitStoreHasher;
	}
	
	public static Comparator<BitStore> numericalComparator() {
		return numericalComparator;
	}
	
	public static Comparator<BitStore> lexicalComparator() {
		return lexicalComparator;
	}

	// new bit store
	
	public static BitStore store(int size) {
		if (size < 0) throw new IllegalArgumentException();
		switch (size) {
		case 0 : return VoidBitStore.MUTABLE;
		case 1 : return new Bit();
		case 64: return new LongBitStore();
		default:
			return size < 64 ?
					new LongBitStore().range(0, size) :
					new BitVector(size);
		}
	}

	public static BitStore toStore(CharSequence chars) {
		if (chars == null) throw new IllegalArgumentException("null chars");
		int size = chars.length();
		BitStore store = store(size);
		transferImpl( new CharBitReader(chars), store.openWriter(), size );
		return store;
	}

	public static BitStore toStore(int size, Random random, float probability) {
		return new BitVector(random, probability, size);
	}

	public static BitStore toStore(int size, Random random) {
		return new BitVector(random, size);
	}

	public static BitStore toStore(boolean bit) {
		return new Bit(bit);
	}
	
	public static BitStore toStore(long bits) {
		return new LongBitStore(bits);
	}
	
	public static BitStore toStore(long bits, int count) {
		return new LongBitStore(bits).range(0, count);
	}
	
	// immutable bit stores
	
	public static BitStore noBits() {
		return VoidBitStore.MUTABLE;
	}
	
	public static BitStore oneBit() {
		return ImmutableOne.INSTANCE;<commit_msg>Documents helpers and toStore methods.<commit_after>/*
 * Copyright 2015 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.tomgibara.bits;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.BitSet;
import java.util.Comparator;
import java.util.ListIterator;
import java.util.Random;

import com.tomgibara.bits.BitStore.Matches;
import com.tomgibara.bits.BitStore.Positions;
import com.tomgibara.bits.ImmutableBit.ImmutableOne;
import com.tomgibara.bits.ImmutableBit.ImmutableZero;
import com.tomgibara.hashing.Hasher;
import com.tomgibara.hashing.Hashing;
import com.tomgibara.streams.ReadStream;
import com.tomgibara.streams.StreamSerializer;
import com.tomgibara.streams.WriteStream;

/**
 * <p>
 * Static methods that provide the entry-point for most package functions. This
 * package provides a dense library of bit storage, transformation and streaming
 * functionality, and consequently, this class features a large number of
 * methods; organized into the following categories:
 * 
 * <ul>
 * <li>
 * Helper objects that assist with implementing {@link BitStore} functionality
 * {@link #bitStoreHasher()}, {@link #numericalComparator()} and
 * {@link #lexicalComparator()}.
 * 
 * <li>
 * Methods for creating new {@link BitStore} instances: {@link #store(int)}
 * <code>toStore(...)</code> and <code>asStore(...)</code>.
 * 
 * <li>
 * Methods that return immutable basic {@link BitStore} instances:
 * {@link #noBits()}, {@link #oneBit()}, {@link #zeroBit()}, {@link #ones(int)},
 * {@link #zeros(int)}, {@link #bit(boolean)} and {@link #bits(boolean, int)}.
 * 
 * <li>
 * Methods that adapt common Java I/O primitives into bit readers:
 * <code>readerFrom(...)</code>
 * 
 * <li>
 * Methods that adapt common Java I/O primitives into bit writers:
 * <code>writerTo(...)</code>, {@link #writerToStdout()},
 * {@link #writerToNothing()}.
 * 
 * <li>
 * Methods to assist with growing bit stores: {@link #growableBits()},
 * {@link #growableBits(int)}, {@link #resizedCopyOf(BitStore, int, boolean)}.
 * </ul>
 * 
 * @author <NAME>
 *
 */

public final class Bits {

	private static final Hasher<BitStore> bitStoreHasher = bitStoreHasher((b,s) -> b.writeTo(s));
	
	private static final Comparator<BitStore> numericalComparator = new Comparator<BitStore>() {
		@Override
		public int compare(BitStore a, BitStore b) {
			return a.compareNumericallyTo(b);
		}
	};

	private static final Comparator<BitStore> lexicalComparator = new Comparator<BitStore>() {
		@Override
		public int compare(BitStore a, BitStore b) {
			return a.compareLexicallyTo(b);
		}
	};

	// public
	
	// helpers

	/**
	 * A hasher that generates hash codes that are consistent with the stated
	 * contract for {@link BitStore}. The resulting hasher may be used for this
	 * purpose as follows:
	 * <code>Bits.bitStoreHasher().intHashValue(store)</code>.
	 * 
	 * @return a hasher of {@link BitStore}
	 */

	public static Hasher<BitStore> bitStoreHasher() {
		bitStoreHasher.hash(zeroBit()).intValue();
		return bitStoreHasher;
	}

	/**
	 * A comparator that orders bit stores consistently with
	 * {@link BitStore#compareNumericallyTo(BitStore)}.
	 * 
	 * @return a numerical comparator of {@link BitStore}
	 */

	public static Comparator<BitStore> numericalComparator() {
		return numericalComparator;
	}
	
	/**
	 * A comparator that orders bit stores consistently with
	 * {@link BitStore#compareLexicallyTo(BitStore)}.
	 * 
	 * @return a lexical comparator of {@link BitStore}
	 */

	public static Comparator<BitStore> lexicalComparator() {
		return lexicalComparator;
	}

	// new bit store
	
	/**
	 * Creates a new mutable {@link BitStore} instance with the specified size.
	 * The implementing class is likely to vary with the requested size.
	 * 
	 * @param size
	 *            the capacity, in bits, of the new {@link BitStore}
	 * 
	 * @return a new mutable {@link BitStore} of the specified size.
	 */

	public static BitStore store(int size) {
		if (size < 0) throw new IllegalArgumentException();
		switch (size) {
		case 0 : return VoidBitStore.MUTABLE;
		case 1 : return new Bit();
		case 64: return new LongBitStore();
		default:
			return size < 64 ?
					new LongBitStore().range(0, size) :
					new BitVector(size);
		}
	}

	/**
	 * Creates a mutable {@link BitStore} initialized with a binary string of
	 * characters. The size of store will equal the number of characters. The
	 * string is treated as an arbitrary length binary number, so (by way of
	 * example) the value the zeroth character in the string determines the
	 * value of the highest indexed bit in the store.
	 * 
	 * @param chars
	 *            a character sequence of the binary characters <code>'0'</code>
	 *            and <code>'1'</code>
	 * @return a new mutable {@link BitStore} initialized with the specified
	 *         binary string
	 * @see #asStore(CharSequence)
	 */

	public static BitStore toStore(CharSequence chars) {
		if (chars == null) throw new IllegalArgumentException("null chars");
		int size = chars.length();
		BitStore store = store(size);
		transferImpl( new CharBitReader(chars), store.openWriter(), size );
		return store;
	}

	/**
	 * Creates a mutable {@link BitStore} initialized with random bit values.
	 * 
	 * @param size
	 *            the capacity, in bits, of the new {@link BitStore}
	 * @param random
	 *            a source of randomness
	 * @param probability
	 *            a number between 0 and 1 inclusive, being the independent
	 *            probability that a bit is set
	 * @return a new mutable {@link BitStore} initialized with random bit values
	 */

	public static BitStore toStore(int size, Random random, float probability) {
		return new BitVector(random, probability, size);
	}

	/**
	 * Creates a mutable {@link BitStore} initialized with random bit values;
	 * the independent probability of each bit having a value of 1 being equal
	 * to 0.5.
	 * 
	 * @param size
	 *            the capacity, in bits, of the new {@link BitStore}
	 * @param random
	 *            a source of randomness
	 * @return a new mutable {@link BitStore} initialized with random bit values
	 */

	public static BitStore toStore(int size, Random random) {
		return new BitVector(random, size);
	}

	/**
	 * Creates a mutable {@link BitStore} instance of size one (ie. containing a
	 * single bit).
	 * 
	 * @param bit
	 *            the value of the single bit in the new {@link BitStore}
	 * 
	 * @return a new mutable {@link BitStore} initialized with the specified bit
	 *         value
	 */

	public static BitStore toStore(boolean bit) {
		return new Bit(bit);
	}
	
	/**
	 * Creates a mutable {@link BitStore} instance of size 64, initialized with
	 * the bit values of the supplied long. The long is treated as a big-endian
	 * value, so (by way of example) its least significant bit determines the
	 * value of the store's zero indexed bit.
	 * 
	 * @param bits
	 *            the values of the bits in the new {@link BitStore}
	 * 
	 * @return a new mutable {@link BitStore} of size 64 initialized with the
	 *         bits of the supplied long
	 */

	public static BitStore toStore(long bits) {
		return new LongBitStore(bits);
	}
	
	/**
	 * Creates a mutable {@link BitStore} instance initialized with the bit
	 * values from a supplied long. The long is treated as a big-endian value,
	 * so (by way of example) its least significant bit determines the value of
	 * the store's zero indexed bit. The count parameter determines the number
	 * of bits read from the long value that are used to construct the new
	 * {@link BitStore}, and consequently, the size of the returned bit store.
	 * Where the count is less that 64, the least signficant bits of the long
	 * value are used.
	 * 
	 * @param bits
	 *            the values of the bits in the new {@link BitStore}
	 * @param count
	 *            between 0 and 64 inclusive, the number of bits used to
	 *            populate the new {@link BitStore}
	 * 
	 * @return a new mutable {@link BitStore} initialized with the bits of the
	 *         supplied long
	 */

	public static BitStore toStore(long bits, int count) {
		return new LongBitStore(bits).range(0, count);
	}
	
	// immutable bit stores
	
	public static BitStore noBits() {
		return VoidBitStore.MUTABLE;
	}
	
	public static BitStore oneBit() {
		return ImmutableOne.INSTANCE;
{'fraction_non_alphanumeric': 0.10753389891958523, 'fraction_numerical': 0.0036255528968167647, 'mean_word_length': 3.773970231914157, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3422397', 'n_tokens_mistral': 4286, 'n_tokens_neox': 3939, 'n_words': 1467}