packages feed

bitvec 1.1.1.0 → 1.1.2.0

raw patch · 24 files changed

+188/−67 lines, 24 filesdep +quickcheck-classes-basedep −ghc-primsetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: quickcheck-classes-base

Dependencies removed: ghc-prim

API changes (from Hackage documentation)

Files

README.md view
@@ -1,4 +1,4 @@-# bitvec [![GitHub Build Status](https://github.com/Bodigrim/bitvec/workflows/ci/badge.svg)](https://github.com/Bodigrim/bitvec/actions?query=workflow%3Aci) [![Travis Build Status](https://travis-ci.com/Bodigrim/bitvec.svg)](https://travis-ci.com/Bodigrim/bitvec) [![Hackage](http://img.shields.io/hackage/v/bitvec.svg)](https://hackage.haskell.org/package/bitvec) [![Hackage CI](https://matrix.hackage.haskell.org/api/v2/packages/bitvec/badge)](https://matrix.hackage.haskell.org/package/bitvec) [![Stackage LTS](http://stackage.org/package/bitvec/badge/lts)](http://stackage.org/lts/package/bitvec) [![Stackage Nightly](http://stackage.org/package/bitvec/badge/nightly)](http://stackage.org/nightly/package/bitvec) [![Coverage Status](https://coveralls.io/repos/github/Bodigrim/bitvec/badge.svg)](https://coveralls.io/github/Bodigrim/bitvec)+# bitvec [![Hackage](http://img.shields.io/hackage/v/bitvec.svg)](https://hackage.haskell.org/package/bitvec) [![Stackage LTS](http://stackage.org/package/bitvec/badge/lts)](http://stackage.org/lts/package/bitvec) [![Stackage Nightly](http://stackage.org/package/bitvec/badge/nightly)](http://stackage.org/nightly/package/bitvec)  A newtype over `Bool` with a better `Vector` instance: 8x less memory, up to 1000x faster. 
− Setup.lhs
@@ -1,5 +0,0 @@-#!/usr/bin/env runhaskell--> import Distribution.Simple-> main = defaultMain-
bench/Bench.hs view
@@ -1,6 +1,6 @@ module Main where -import Gauge.Main+import Test.Tasty.Bench  import Bench.BitIndex import Bench.GCD
bench/Bench/BitIndex.hs view
@@ -7,7 +7,7 @@ import Data.Bits import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main+import Test.Tasty.Bench  randomVec :: MU.Unbox a => (Bool -> a) -> Int -> U.Vector a randomVec f k = U.generate n (\i -> f (i == n - 1))
bench/Bench/GCD.hs view
@@ -7,8 +7,8 @@ import Data.Bits import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools = map (> (0 :: Int)) $ randoms $ mkStdGen 42
bench/Bench/Intersection.hs view
@@ -8,8 +8,8 @@ import qualified Data.IntSet as IS import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools
bench/Bench/Invert.hs view
@@ -7,8 +7,8 @@ import Data.Bits import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools
bench/Bench/Product.hs view
@@ -7,8 +7,8 @@ import Data.Bits import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools
bench/Bench/RandomFlip.hs view
@@ -7,11 +7,11 @@ import Data.Bit import qualified Data.Bit.ThreadSafe as TS import Data.Bits+import Data.Foldable import qualified Data.IntSet as IS-import Data.List import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomFlips :: [Int] randomFlips
bench/Bench/RandomRead.hs view
@@ -10,8 +10,8 @@ -- import Data.List import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomVec :: [Bool] randomVec
bench/Bench/RandomWrite.hs view
@@ -7,11 +7,11 @@ import Data.Bit import qualified Data.Bit.ThreadSafe as TS import Data.Bits+import Data.Foldable import qualified Data.IntSet as IS-import Data.List import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomWrites :: [(Int, Bool)] randomWrites
bench/Bench/Remainder.hs view
@@ -10,7 +10,6 @@ import Data.Bits import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import GHC.Exts #ifdef MIN_VERSION_ghc_bignum import GHC.Num.Integer@@ -18,6 +17,7 @@ import GHC.Integer.Logarithms #endif import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools
bench/Bench/Reverse.hs view
@@ -7,8 +7,8 @@ import Data.Bits import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools
bench/Bench/Sum.hs view
@@ -5,11 +5,11 @@ import Data.Bit import qualified Data.Bit.ThreadSafe as TS import Data.Bits-import Data.List+import Data.Foldable import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools
bench/Bench/Union.hs view
@@ -8,8 +8,8 @@ import qualified Data.IntSet as IS import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as MU-import Gauge.Main import System.Random+import Test.Tasty.Bench  randomBools :: [Bool] randomBools
bitvec.cabal view
@@ -1,10 +1,10 @@ name: bitvec-version: 1.1.1.0-cabal-version: 2.0+version: 1.1.2.0+cabal-version: >=1.10 build-type: Simple license: BSD3 license-file: LICENSE-copyright: 2019-2020 Andrew Lelechenko, 2012-2016 James Cook+copyright: 2019-2021 Andrew Lelechenko, 2012-2016 James Cook maintainer: Andrew Lelechenko <andrew.lelechenko@gmail.com> homepage: https://github.com/Bodigrim/bitvec synopsis: Space-efficient bit vectors@@ -46,7 +46,7 @@ author: Andrew Lelechenko <andrew.lelechenko@gmail.com>,         James Cook <mokus@deepbondi.net> -tested-with: GHC ==8.0.2 GHC ==8.2.2 GHC ==8.4.4 GHC ==8.6.5 GHC ==8.8.1 GHC ==8.8.2 GHC ==8.8.4 GHC ==8.10.2+tested-with: GHC ==8.0.2 GHC ==8.2.2 GHC ==8.4.4 GHC ==8.6.5 GHC ==8.8.1 GHC ==8.8.2 GHC ==8.8.4 GHC ==8.10.7 GHC ==9.0.1 GHC ==9.2.1 extra-source-files:   changelog.md   README.md@@ -61,6 +61,7 @@     `zipBits`, `invertBits` and `countBits`. Users are strongly encouraged     to enable this flag whenever possible.   default: False+  manual: True  library   exposed-modules:@@ -70,7 +71,6 @@     base >=4.9 && <5,     bytestring >=0.10,     deepseq,-    ghc-prim,     primitive >=0.5,     vector >=0.11   default-language: Haskell2010@@ -87,10 +87,7 @@     Data.Bit.MutableTS     Data.Bit.PdepPext     Data.Bit.Utils-  if flag(libgmp)-    other-modules:-      Data.Bit.Gmp-  ghc-options: -O2 -Wall+  ghc-options: -O2 -Wall -Wcompat   include-dirs: src    if impl(ghc <9.0)@@ -109,6 +106,7 @@     base,     bitvec,     primitive >=0.5,+    quickcheck-classes-base,     quickcheck-classes >=0.6.1,     vector >=0.11,     tasty,@@ -125,7 +123,7 @@     Tests.SetOps     Tests.SetOpsTS     Tests.Vector-  ghc-options: -Wall -threaded -rtsopts+  ghc-options: -Wall -threaded -rtsopts -Wcompat   include-dirs: test    if impl(ghc <9.0)@@ -139,11 +137,8 @@     bitvec,     containers,     random,+    tasty-bench,     vector-  build-depends:-    tasty-bench-  mixins:-    tasty-bench (Test.Tasty.Bench as Gauge.Main)   type: exitcode-stdio-1.0   main-is: Bench.hs   default-language: Haskell2010@@ -161,7 +156,7 @@     Bench.Reverse     Bench.Sum     Bench.Union-  ghc-options: -O2 -Wall+  ghc-options: -O2 -Wall -Wcompat    if impl(ghc <9.0)     build-depends: integer-gmp
changelog.md view
@@ -1,3 +1,9 @@+# 1.1.2.0++* Fix `setBit`, `clearBit`, `complementBit` to preserve vector's length.+* Fix various issues on big-endian architectures.+* Fix Cabal 3.7+ incompatibility.+ # 1.1.1.0  * Export `BitVec` and `BitMVec` constructors.
src/Data/Bit/Immutable.hs view
@@ -2,8 +2,10 @@  {-# LANGUAGE BangPatterns         #-} {-# LANGUAGE FlexibleContexts     #-}+{-# LANGUAGE MagicHash            #-} {-# LANGUAGE RankNTypes           #-} {-# LANGUAGE FlexibleInstances    #-}+{-# LANGUAGE TupleSections        #-} {-# LANGUAGE UndecidableInstances #-}  {-# OPTIONS_GHC -fno-warn-orphans #-}@@ -37,6 +39,8 @@   , listBits   ) where +#include "MachDeps.h"+ import Control.Monad import Control.Monad.ST import Data.Bits@@ -61,6 +65,10 @@ import Data.Word import Unsafe.Coerce +#ifdef WORDS_BIGENDIAN+import GHC.Exts+#endif+ #if UseLibGmp gmpLimbShift :: Int gmpLimbShift = case wordSize of@@ -84,6 +92,27 @@     | n < 0 || n >= U.length v = False     | otherwise = unBit (U.unsafeIndex v n) +  setBit v n+    | n < 0 || n >= U.length v = v+    | otherwise = runST $ do+      u <- U.thaw v+      MU.unsafeWrite u n (Bit True)+      U.unsafeFreeze u++  clearBit v n+    | n < 0 || n >= U.length v = v+    | otherwise = runST $ do+      u <- U.thaw v+      MU.unsafeWrite u n (Bit False)+      U.unsafeFreeze u++  complementBit v n+    | n < 0 || n >= U.length v = v+    | otherwise = runST $ do+      u <- U.thaw v+      unsafeFlipBit u n+      U.unsafeFreeze u+   bit n     | n < 0 = U.empty     | otherwise = runST $ do@@ -163,13 +192,31 @@ -- | Cast a unboxed vector of 'Word8' -- to an unboxed vector of bits. --+-- On big-endian architectures 'castFromWords8'+-- resorts to copying instead of aliasing underlying arrays.+-- -- >>> :set -XOverloadedLists -- >>> castFromWords8 [123] -- [1,1,0,1,1,1,1,0] castFromWords8 :: U.Vector Word8 -> U.Vector Bit castFromWords8 ws = BitVec (off `shiftL` 3) (len `shiftL` 3) arr   where+#ifdef WORDS_BIGENDIAN+    P.Vector off' len arr' = unsafeCoerce ws+    off = 0+    arr = runST $ do+      let lenWords = nWords $ len `shiftL` 3+          len' = wordsToBytes lenWords+      marr <- newByteArray len'+      copyByteArray marr 0 arr' off' len+      fillByteArray marr len (len' - len) 0+      forM_ [0..lenWords - 1] $ \i -> do+        W# w <- readByteArray marr i+        writeByteArray marr i (W# (byteSwap# w))+      unsafeFreezeByteArray marr+#else     P.Vector off len arr = unsafeCoerce ws+#endif  -- | Try to cast an unboxed vector of bits -- to an unboxed vector of 'Word8'.@@ -178,10 +225,14 @@ -- -- > castToWords8 (castFromWords8 v) == Just v castToWords8 :: U.Vector Bit -> Maybe (U.Vector Word8)+#ifdef WORDS_BIGENDIAN+castToWords8 = const Nothing+#else castToWords8 (BitVec s n ws)-  | s .&. 7 == 0, n .&. 7 == 0 =-    Just $ unsafeCoerce $ P.Vector (s `shiftR` 3) (n `shiftR` 3) ws+  | s .&. 7 == 0, n .&. 7 == 0+  = Just $ unsafeCoerce $ P.Vector (s `shiftR` 3) (n `shiftR` 3) ws   | otherwise = Nothing+#endif  -- | Clone an unboxed vector of bits -- to a new unboxed vector of 'Word8'.
src/Data/Bit/Mutable.hs view
@@ -2,6 +2,7 @@  {-# LANGUAGE BangPatterns        #-} {-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE MagicHash           #-} {-# LANGUAGE RankNTypes          #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -26,6 +27,8 @@   , reverseInPlace   ) where +#include "MachDeps.h"+ import Control.Monad import Control.Monad.Primitive import Control.Monad.ST@@ -42,6 +45,10 @@ import qualified Data.Vector.Unboxed.Mutable as MU import Data.Word +#ifdef WORDS_BIGENDIAN+import GHC.Exts+#endif+ -- | Cast a vector of words to a vector of bits. -- Cf. 'Data.Bit.castFromWords'. castFromWordsM :: MVector s Word -> MVector s Bit@@ -83,11 +90,20 @@   -> m (MVector (PrimState m) Word8) cloneToWords8M v = do   let lenBits  = MU.length v-      lenWords = (lenBits + 7) `shiftR` 3-  w@(BitMVec _ _ arr) <- MU.unsafeNew (lenWords `shiftL` 3)-  MU.unsafeCopy (MU.slice 0 lenBits w) v-  MU.set (MU.slice lenBits (lenWords `shiftL` 3 - lenBits) w) (Bit False)-  pure $ MU.MV_Word8 $ P.MVector 0 lenWords arr+      -- Take care about big-endian architectures: allocate full words!+      actualLenBytes = (lenBits + 7) `shiftR` 3+      roundedLenBytes = wordsToBytes (nWords lenBits)+  ws@(BitMVec _ _ arr) <- MU.unsafeNew (roundedLenBytes `shiftL` 3)+  MU.unsafeCopy (MU.slice 0 lenBits ws) v+  MU.set (MU.slice lenBits (roundedLenBytes `shiftL` 3 - lenBits) ws) (Bit False)++#ifdef WORDS_BIGENDIAN+  forM_ [0..nWords lenBits - 1] $ \i -> do+    W# w <- readByteArray arr i+    writeByteArray arr i (W# (byteSwap# w))+#endif++  pure $ MU.MV_Word8 $ P.MVector 0 actualLenBytes arr {-# INLINE cloneToWords8M #-}  -- | Zip two vectors with the given function.
test/Main.hs view
@@ -5,12 +5,15 @@  import Control.Exception import Data.Bit-import Data.Proxy-import Test.QuickCheck.Classes import Test.Tasty import Test.Tasty.QuickCheck +#ifdef MIN_VERSION_quickcheck_classes_base+import Data.Proxy+import Test.QuickCheck.Classes.Base import Support+#endif+ import Tests.Conc (concTests) import Tests.F2Poly (f2polyTests) import Tests.MVector (mvectorTests)@@ -34,6 +37,7 @@ lawsTests :: TestTree lawsTests = adjustOption (const $ QuickCheckTests 100)   $ testGroup "Bit"+#ifdef MIN_VERSION_quickcheck_classes_base   $ map lawsToTest   [ bitsLaws        (Proxy :: Proxy Bit)   , eqLaws          (Proxy :: Proxy Bit)@@ -41,11 +45,10 @@   , boundedEnumLaws (Proxy :: Proxy Bit)   , showLaws        (Proxy :: Proxy Bit)   , showReadLaws    (Proxy :: Proxy Bit)-#if MIN_VERSION_quickcheck_classes(0,6,3)   , numLaws         (Proxy :: Proxy Bit)-#endif   , integralLaws    (Proxy :: Proxy Bit)   ] +++#endif   [ testProperty "divideByZero" prop_bitDivideByZero   , testProperty "toRational"   prop_bitToRational   ]
test/Support.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                 #-} {-# LANGUAGE FlexibleContexts    #-} {-# LANGUAGE FlexibleInstances   #-} {-# LANGUAGE RankNTypes          #-}@@ -15,10 +16,16 @@ import qualified Data.Vector.Generic.Mutable as M import qualified Data.Vector.Generic.New as N import qualified Data.Vector.Unboxed as U-import Test.QuickCheck.Classes import Test.Tasty import Test.Tasty.QuickCheck +#ifdef MIN_VERSION_quickcheck_classes_base+import Test.QuickCheck.Classes.Base+#endif+#ifdef MIN_VERSION_quickcheck_classes+import qualified Test.QuickCheck.Classes as QCC+#endif+ instance Arbitrary Bit where   arbitrary = Bit <$> arbitrary   shrink    = fmap Bit . shrink . unBit@@ -156,6 +163,14 @@ twoTimesMore = adjustOption $   \(QuickCheckTests n) -> QuickCheckTests (n * 2) +#ifdef MIN_VERSION_quickcheck_classes_base lawsToTest :: Laws -> TestTree lawsToTest (Laws name props) =   testGroup name $ map (uncurry testProperty) props+#endif++#ifdef MIN_VERSION_quickcheck_classes+lawsToTest' :: QCC.Laws -> TestTree+lawsToTest' (QCC.Laws name props) =+  testGroup name $ map (uncurry testProperty) props+#endif
test/Tests/F2Poly.hs view
@@ -8,7 +8,6 @@ import Control.Exception import Data.Bit import Data.Bits-import Data.Proxy import Data.Ratio import GHC.Exts #ifdef MIN_VERSION_ghc_bignum@@ -16,10 +15,14 @@ #else import GHC.Integer.Logarithms #endif-import Test.QuickCheck.Classes import Test.Tasty import Test.Tasty.QuickCheck +#ifdef MIN_VERSION_quickcheck_classes_base+import Data.Proxy+import Test.QuickCheck.Classes.Base+#endif+ import Support  f2polyTests :: TestTree@@ -36,14 +39,14 @@   , testProperty "GCD"                 prop_f2polyGCD   , testProperty "Enum" $     \n -> let x = toEnum n in toEnum (fromEnum x) === (x :: F2Poly)+#ifdef MIN_VERSION_quickcheck_classes_base   , tenTimesLess $ lawsToTest $     showLaws (Proxy :: Proxy F2Poly)-#if MIN_VERSION_quickcheck_classes(0,6,3)   , lawsToTest $     numLaws (Proxy :: Proxy F2Poly)-#endif   , lawsToTest $     integralLaws (Proxy :: Proxy F2Poly)+#endif   , testProperty "fromNegative" prop_f2polyFromNegative   , testProperty "divideByZero" prop_f2polyDivideByZero   , testProperty "toRational" prop_f2polyToRational
test/Tests/MVector.hs view
@@ -16,17 +16,20 @@ import Data.Bit.ThreadSafe #endif import Data.Bits-import Data.Proxy import qualified Data.Vector.Generic as V import qualified Data.Vector.Generic.Mutable as MG import qualified Data.Vector.Generic.New as N import qualified Data.Vector.Unboxed as U import qualified Data.Vector.Unboxed.Mutable as M-import Test.QuickCheck.Classes import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck +#ifdef MIN_VERSION_quickcheck_classes+import Data.Proxy+import Test.QuickCheck.Classes+#endif+ mvectorTests :: TestTree mvectorTests = testGroup "Data.Vector.Unboxed.Mutable.Bit"   [ testGroup "Data.Vector.Unboxed.Mutable functions"@@ -43,7 +46,9 @@     , tenTimesLess $       testProperty "castToWords_2"  prop_castToWords_2     ]-  , lawsToTest $ muvectorLaws (Proxy :: Proxy Bit)+#ifdef MIN_VERSION_quickcheck_classes+  , lawsToTest' $ muvectorLaws (Proxy :: Proxy Bit)+#endif   , testCase "basicInitialize 1" case_write_init_read1   , testCase "basicInitialize 2" case_write_init_read2   , testCase "basicInitialize 3" case_write_init_read3
test/Tests/Vector.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE CPP #-}+ module Tests.Vector   ( vectorTests   ) where@@ -9,11 +11,15 @@ import Data.Bit import Data.Bits import Data.List (findIndex)+import qualified Data.Vector.Primitive as P import qualified Data.Vector.Unboxed as U import Data.Word import Test.Tasty-import Test.Tasty.QuickCheck+import Test.Tasty.QuickCheck (Property, NonNegative(..), Positive(..), testProperty, Large(..), (===), property, once, (==>), ioProperty, (.&&.), counterexample)+import Unsafe.Coerce +#include "MachDeps.h"+ vectorTests :: TestTree vectorTests = testGroup "Data.Vector.Unboxed.Bit"   [ testGroup "Data.Vector.Unboxed functions"@@ -82,6 +88,9 @@     , testProperty "zeroBits"             prop_zeroBits     , testProperty "bitSize"              prop_bitSize     , testProperty "isSigned"             prop_isSigned+    , testProperty "setBit"               prop_setBit+    , testProperty "clearBit"             prop_clearBit+    , testProperty "complementBit"        prop_complementBit     ]   ] @@ -133,19 +142,31 @@   Just ws -> castFromWords ws === xs  prop_cloneFromWords8_def :: U.Vector Word8 -> Property-prop_cloneFromWords8_def ws =-  U.toList (castFromWords8 ws) === concatMap wordToBitList (U.toList ws)+prop_cloneFromWords8_def ws+  = counterexample ("offset = " ++ show off ++ " len = " ++ show len)+  $ U.toList (castFromWords8 ws) === concatMap wordToBitList (U.toList ws)+  where+    P.Vector off len _ = unsafeCoerce ws  prop_cloneToWords8_def :: U.Vector Bit -> Property-prop_cloneToWords8_def xs = U.toList (cloneToWords8 xs) === loop (U.toList xs)- where-  loop [] = []-  loop bs = case packBitsToWord bs of-    (w, bs') -> w : loop bs'+prop_cloneToWords8_def xs@(BitVec off len _)+  = counterexample ("offset = " ++ show off ++ " len = " ++ show len)+  $ U.toList (cloneToWords8 xs) === loop (U.toList xs)+  where+    loop [] = []+    loop bs = case packBitsToWord bs of+      (w, bs') -> w : loop bs'  prop_castToWords8_1 :: U.Vector Word8 -> Property-prop_castToWords8_1 ws =-  Just ws === castToWords8 (castFromWords8 ws)+#ifdef WORDS_BIGENDIAN+prop_castToWords8_1 ws = Nothing === castToWords8 (castFromWords8 ws)+#else+prop_castToWords8_1 ws+  = counterexample ("offset = " ++ show off ++ " len = " ++ show len)+  $ Just ws === castToWords8 (castFromWords8 ws)+  where+    P.Vector off len _ = unsafeCoerce ws+#endif  prop_castToWords8_2 :: U.Vector Bit -> Property prop_castToWords8_2 xs = case castToWords8 xs of@@ -323,7 +344,18 @@ prop_isSigned :: U.Vector Bit -> Property prop_isSigned v = isSigned v === False +prop_setBit :: Int -> U.Vector Bit -> Property+prop_setBit n v = v `setBit` n === U.imap ((.|.) . Bit . (== n)) v++prop_clearBit :: Int -> U.Vector Bit -> Property+prop_clearBit n v = v `clearBit` n === U.imap ((.&.) . Bit . (/= n)) v++prop_complementBit :: Int -> U.Vector Bit -> Property+prop_complementBit n v = v `complementBit` n === U.imap (xor . Bit . (== n)) v+ prop_cloneToByteString :: U.Vector Bit -> Property-prop_cloneToByteString v = cloneToByteString (cloneFromByteString bs) === bs+prop_cloneToByteString v@(BitVec off len _)+  = counterexample ("offset = " ++ show off ++ " len = " ++ show len)+  $ cloneToByteString (cloneFromByteString bs) === bs   where     bs = cloneToByteString v