static void CheckArgsCopy(ref UnsafeBitArray dstBitArray, int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits)
        {
            if (dstPos + numBits > srcBitArray.Length)
            {
                throw new ArgumentException($"BitArray invalid arguments: Out of bounds - source position {srcPos}, numBits {numBits}, source bit array Length {srcBitArray.Length}.");
            }

            if (dstPos + numBits > dstBitArray.Length)
            {
                throw new ArgumentException($"BitArray invalid arguments: Out of bounds - destination position {dstPos}, numBits {numBits}, destination bit array Length {dstBitArray.Length}.");
            }
        }
 public UnsafeBitArrayDebugView(UnsafeBitArray data)
 {
     Data = data;
 }
        /// <summary>
        /// Copy block of bits from source to destination.
        /// </summary>
        /// <param name="dstPos">Destination position in bit array.</param>
        /// <param name="srcBitArray">Source bit array from which bits will be copied.</param>
        /// <param name="srcPos">Source position in bit array.</param>
        /// <param name="numBits">Number of bits to copy.</param>
        public void Copy(int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits)
        {
            if (numBits == 0)
            {
                return;
            }

            CheckArgsCopy(ref this, dstPos, ref srcBitArray, srcPos, numBits);

            if (numBits <= 64) // 1x CopyUlong
            {
                CopyUlong(dstPos, ref srcBitArray, srcPos, numBits);
            }
            else if (numBits <= 128) // 2x CopyUlong
            {
                CopyUlong(dstPos, ref srcBitArray, srcPos, 64);
                numBits -= 64;

                if (numBits > 0)
                {
                    CopyUlong(dstPos + 64, ref srcBitArray, srcPos + 64, numBits);
                }
            }
            else if ((dstPos & 7) == (srcPos & 7)) // aligned copy
            {
                var dstPosInBytes = CollectionHelper.Align(dstPos, 8) >> 3;
                var srcPosInBytes = CollectionHelper.Align(srcPos, 8) >> 3;
                var numPreBits    = dstPosInBytes * 8 - dstPos;

                if (numPreBits > 0)
                {
                    CopyUlong(dstPos, ref srcBitArray, srcPos, numPreBits);
                }

                var numBitsLeft = numBits - numPreBits;
                var numBytes    = numBitsLeft / 8;

                if (numBytes > 0)
                {
                    unsafe
                    {
                        UnsafeUtility.MemMove((byte *)Ptr + dstPosInBytes, (byte *)srcBitArray.Ptr + srcPosInBytes, numBytes);
                    }
                }

                var numPostBits = numBitsLeft & 7;

                if (numPostBits > 0)
                {
                    CopyUlong((dstPosInBytes + numBytes) * 8, ref srcBitArray, (srcPosInBytes + numBytes) * 8, numPostBits);
                }
            }
            else // unaligned copy
            {
                var dstPosAligned = CollectionHelper.Align(dstPos, 64);
                var numPreBits    = dstPosAligned - dstPos;

                if (numPreBits > 0)
                {
                    CopyUlong(dstPos, ref srcBitArray, srcPos, numPreBits);
                    numBits -= numPreBits;
                    dstPos  += numPreBits;
                    srcPos  += numPreBits;
                }

                for (; numBits >= 64; numBits -= 64, dstPos += 64, srcPos += 64)
                {
                    Ptr[dstPos >> 6] = srcBitArray.GetBits(srcPos, 64);
                }

                if (numBits > 0)
                {
                    CopyUlong(dstPos, ref srcBitArray, srcPos, numBits);
                }
            }
        }
 internal void CopyUlong(int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits) => SetBits(dstPos, srcBitArray.GetBits(srcPos, numBits), numBits);