packages feed

memory 0.14.14 → 0.14.15

raw patch · 10 files changed

+570/−119 lines, 10 filesdep −tastydep −tasty-hunitdep −tasty-quickcheckdep ~basedep ~ghc-primPVP ok

version bump matches the API change (PVP)

Dependencies removed: tasty, tasty-hunit, tasty-quickcheck

Dependency ranges changed: base, ghc-prim

API changes (from Hackage documentation)

+ Data.ByteArray.Sized: alloc :: forall n ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> IO ba
+ Data.ByteArray.Sized: allocAndFreeze :: forall n ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> ba
+ Data.ByteArray.Sized: allocRet :: forall p a. ByteArrayN n c => Proxy n -> (Ptr p -> IO a) -> IO (a, c)
+ Data.ByteArray.Sized: append :: forall nblhs nbrhs nbout blhs brhs bout. (ByteArrayN nblhs blhs, ByteArrayN nbrhs brhs, ByteArrayN nbout bout, ByteArrayAccess blhs, ByteArrayAccess brhs, KnownNat nblhs, KnownNat nbrhs, KnownNat nbout, (nbrhs + nblhs) ~ nbout) => blhs -> brhs -> bout
+ Data.ByteArray.Sized: class (ByteArrayAccess c, KnownNat n) => ByteArrayN (n :: Nat) c | c -> n
+ Data.ByteArray.Sized: cons :: forall ni no bi bo. (ByteArrayN ni bi, ByteArrayN no bo, ByteArrayAccess bi, KnownNat ni, KnownNat no, (ni + 1) ~ no) => Word8 -> bi -> bo
+ Data.ByteArray.Sized: convert :: forall n bin bout. (ByteArrayN n bin, ByteArrayN n bout, KnownNat n) => bin -> bout
+ Data.ByteArray.Sized: copy :: forall n bs1 bs2 p. (ByteArrayN n bs1, ByteArrayN n bs2, ByteArrayAccess bs1, KnownNat n) => bs1 -> (Ptr p -> IO ()) -> IO bs2
+ Data.ByteArray.Sized: copyAndFreeze :: forall n bs1 bs2 p. (ByteArrayN n bs1, ByteArrayN n bs2, ByteArrayAccess bs1, KnownNat n) => bs1 -> (Ptr p -> IO ()) -> bs2
+ Data.ByteArray.Sized: copyRet :: forall n bs1 bs2 p a. (ByteArrayN n bs1, ByteArrayN n bs2, ByteArrayAccess bs1, KnownNat n) => bs1 -> (Ptr p -> IO a) -> IO (a, bs2)
+ Data.ByteArray.Sized: create :: forall n ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> IO ba
+ Data.ByteArray.Sized: data SizedByteArray (n :: Nat) ba
+ Data.ByteArray.Sized: drop :: forall n nbi nbo bi bo. (ByteArrayN nbi bi, ByteArrayN nbo bo, ByteArrayAccess bi, KnownNat n, KnownNat nbi, KnownNat nbo, (nbo + n) ~ nbi) => Proxy n -> bi -> bo
+ Data.ByteArray.Sized: empty :: forall ba. ByteArrayN 0 ba => ba
+ Data.ByteArray.Sized: fromByteArrayAccess :: forall n bin bout. (ByteArrayAccess bin, ByteArrayN n bout, KnownNat n) => bin -> Maybe bout
+ Data.ByteArray.Sized: index :: forall n na ba. (ByteArrayN na ba, ByteArrayAccess ba, KnownNat na, KnownNat n, n <= na) => ba -> Proxy n -> Word8
+ Data.ByteArray.Sized: inlineUnsafeCreate :: forall n ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> ba
+ Data.ByteArray.Sized: instance (Data.ByteArray.Types.ByteArrayAccess (Basement.Sized.Block.BlockN n ty), Basement.PrimType.PrimType ty, GHC.TypeNats.KnownNat n, Basement.Types.OffsetSize.Countable ty n, GHC.TypeNats.KnownNat nbytes, nbytes ~ (Basement.PrimType.PrimSize ty GHC.TypeNats.* n)) => Data.ByteArray.Sized.ByteArrayN nbytes (Basement.Sized.Block.BlockN n ty)
+ Data.ByteArray.Sized: instance (Data.ByteArray.Types.ByteArrayAccess ba, GHC.TypeNats.KnownNat n) => Data.ByteArray.Types.ByteArrayAccess (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: instance (GHC.TypeNats.KnownNat n, Data.ByteArray.Types.ByteArray ba) => Data.ByteArray.Sized.ByteArrayN n (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: instance Basement.NormalForm.NormalForm ba => Basement.NormalForm.NormalForm (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: instance Data.Semigroup.Semigroup ba => Data.Semigroup.Semigroup (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: instance GHC.Base.Monoid ba => GHC.Base.Monoid (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: instance GHC.Classes.Eq ba => GHC.Classes.Eq (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: instance GHC.Classes.Ord ba => GHC.Classes.Ord (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: instance GHC.Show.Show ba => GHC.Show.Show (Data.ByteArray.Sized.SizedByteArray n ba)
+ Data.ByteArray.Sized: pack :: forall n ba. (ByteArrayN n ba, KnownNat n) => ListN n Word8 -> ba
+ Data.ByteArray.Sized: replicate :: forall n ba. (ByteArrayN n ba, KnownNat n) => Word8 -> ba
+ Data.ByteArray.Sized: sizedByteArray :: forall n ba. (KnownNat n, ByteArrayAccess ba) => ba -> Maybe (SizedByteArray n ba)
+ Data.ByteArray.Sized: snoc :: forall bi bo ni no. (ByteArrayN ni bi, ByteArrayN no bo, ByteArrayAccess bi, KnownNat ni, KnownNat no, (ni + 1) ~ no) => bi -> Word8 -> bo
+ Data.ByteArray.Sized: splitAt :: forall nblhs nbi nbrhs bi blhs brhs. (ByteArrayN nbi bi, ByteArrayN nblhs blhs, ByteArrayN nbrhs brhs, ByteArrayAccess bi, KnownNat nbi, KnownNat nblhs, KnownNat nbrhs, nblhs <= nbi, (nbrhs + nblhs) ~ nbi) => bi -> (blhs, brhs)
+ Data.ByteArray.Sized: take :: forall nbo nbi bi bo. (ByteArrayN nbi bi, ByteArrayN nbo bo, ByteArrayAccess bi, KnownNat nbi, KnownNat nbo, nbo <= nbi) => bi -> bo
+ Data.ByteArray.Sized: unSizedByteArray :: SizedByteArray n ba -> ba
+ Data.ByteArray.Sized: unpack :: forall n ba. (ByteArrayN n ba, KnownNat n, NatWithinBound Int n, ByteArrayAccess ba) => ba -> ListN n Word8
+ Data.ByteArray.Sized: unsafeCreate :: forall n ba p. (ByteArrayN n ba, KnownNat n) => (Ptr p -> IO ()) -> ba
+ Data.ByteArray.Sized: unsafeFromByteArrayAccess :: forall n bin bout. (ByteArrayAccess bin, ByteArrayN n bout, KnownNat n) => bin -> bout
+ Data.ByteArray.Sized: unsafeSizedByteArray :: forall n ba. (ByteArrayAccess ba, KnownNat n) => ba -> SizedByteArray n ba
+ Data.ByteArray.Sized: xor :: forall n a b c. (ByteArrayN n a, ByteArrayN n b, ByteArrayN n c, ByteArrayAccess a, ByteArrayAccess b, KnownNat n) => a -> b -> c
+ Data.ByteArray.Sized: zero :: forall n ba. (ByteArrayN n ba, KnownNat n) => ba

Files

CHANGELOG.md view
@@ -1,3 +1,11 @@+## 0.14.15++* Convert tests to foundation checks+* Convert CI to haskell-ci+* Fix compilation without foundation+* Introduce ByteArrayL and associated method, as a type level sized version of ByteArray+* Add NormalForm for Bytes and ScrubbedBytes+ ## 0.14.14  * Fix bounds issues with empty strings in base64 and base32
Data/ByteArray/Bytes.hs view
@@ -11,6 +11,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-}+{-# LANGUAGE DeriveDataTypeable #-} module Data.ByteArray.Bytes     ( Bytes     ) where@@ -29,9 +30,15 @@ import           Data.Memory.Internal.CompatPrim import           Data.Memory.Internal.Compat      (unsafeDoIO) import           Data.ByteArray.Types+import           Data.Typeable +#ifdef MIN_VERSION_basement+import           Basement.NormalForm+#endif+ -- | Simplest Byte Array data Bytes = Bytes (MutableByteArray# RealWorld)+  deriving (Typeable)  instance Show Bytes where     showsPrec p b r = showsPrec p (bytesUnpackChars b []) r@@ -52,6 +59,10 @@ #endif instance NFData Bytes where     rnf b = b `seq` ()+#ifdef MIN_VERSION_basement+instance NormalForm Bytes where+    toNormalForm b = b `seq` ()+#endif instance ByteArrayAccess Bytes where     length        = bytesLength     withByteArray = withBytes
Data/ByteArray/ScrubbedBytes.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-} module Data.ByteArray.ScrubbedBytes     ( ScrubbedBytes     ) where@@ -23,6 +24,7 @@ import           Data.Monoid #endif import           Data.String (IsString(..))+import           Data.Typeable import           Data.Memory.PtrMethods          (memCopy, memConstEqual) import           Data.Memory.Internal.CompatPrim import           Data.Memory.Internal.Compat     (unsafeDoIO)@@ -30,6 +32,9 @@ import           Data.Memory.Internal.Scrubber   (getScrubber) import           Data.ByteArray.Types import           Foreign.Storable+#ifdef MIN_VERSION_basement+import           Basement.NormalForm+#endif  -- | ScrubbedBytes is a memory chunk which have the properties of: --@@ -40,6 +45,7 @@ -- * A Eq instance that is constant time -- data ScrubbedBytes = ScrubbedBytes (MutableByteArray# RealWorld)+  deriving (Typeable)  instance Show ScrubbedBytes where     show _ = "<scrubbed-bytes>"@@ -61,6 +67,10 @@ #endif instance NFData ScrubbedBytes where     rnf b = b `seq` ()+#ifdef MIN_VERSION_basement+instance NormalForm ScrubbedBytes where+    toNormalForm b = b `seq` ()+#endif instance IsString ScrubbedBytes where     fromString = scrubbedFromChar8 
+ Data/ByteArray/Sized.hs view
@@ -0,0 +1,395 @@+-- |+-- Module      : Data.ByteArray.Sized+-- License     : BSD-style+-- Maintainer  : Nicolas Di Prima <nicolas@primetype.co.uk>+-- Stability   : stable+-- Portability : Good+--++{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE UndecidableInstances #-}++module Data.ByteArray.Sized+    ( ByteArrayN(..)+    , SizedByteArray+    , unSizedByteArray+    , sizedByteArray+    , unsafeSizedByteArray++    , -- * ByteArrayN operators+      alloc+    , create+    , allocAndFreeze+    , unsafeCreate+    , inlineUnsafeCreate+    , empty+    , pack+    , unpack+    , cons+    , snoc+    , xor+    , index+    , splitAt+    , take+    , drop+    , append+    , copy+    , copyRet+    , copyAndFreeze+    , replicate+    , zero+    , convert+    , fromByteArrayAccess+    , unsafeFromByteArrayAccess+    ) where++import Basement.Imports+import Basement.NormalForm+import Basement.Nat+import Basement.Numerical.Additive ((+))+import Basement.Numerical.Subtractive ((-))++import Basement.Sized.List (ListN, unListN, toListN)++import           Foreign.Storable+import           Foreign.Ptr+import           Data.Maybe (fromMaybe)++import           Data.Memory.Internal.Compat+import           Data.Memory.PtrMethods++import Data.Proxy (Proxy(..))++import Data.ByteArray.Types (ByteArrayAccess(..), ByteArray)+import qualified Data.ByteArray.Types as ByteArray (allocRet)++#if MIN_VERSION_basement(0,0,7)+import           Basement.BlockN (BlockN)+import qualified Basement.BlockN as BlockN+import qualified Basement.PrimType as Base+import           Basement.Types.OffsetSize (Countable)+#endif++-- | Type class to emulate exactly the behaviour of 'ByteArray' but with+-- a known length at compile time+--+class (ByteArrayAccess c, KnownNat n) => ByteArrayN (n :: Nat) c | c -> n where+    -- | just like 'allocRet' but with the size at the type level+    allocRet :: forall p a+              . Proxy n+             -> (Ptr p -> IO a)+             -> IO (a, c)++-- | Wrapper around any collection type with the size as type parameter+--+newtype SizedByteArray (n :: Nat) ba = SizedByteArray { unSizedByteArray :: ba }+  deriving (Eq, Show, Typeable, Ord, NormalForm, Semigroup, Monoid)++-- | create a 'SizedByteArray' from the given 'ByteArrayAccess' if the+-- size is the same as the target size.+--+sizedByteArray :: forall n ba . (KnownNat n, ByteArrayAccess ba)+               => ba+               -> Maybe (SizedByteArray n ba)+sizedByteArray ba+    | length ba == n = Just $ SizedByteArray ba+    | otherwise      = Nothing+  where+    n = fromInteger $ natVal (Proxy @n)++-- | just like the 'sizedByteArray' function but throw an exception if+-- the size is invalid.+unsafeSizedByteArray :: forall n ba . (ByteArrayAccess ba, KnownNat n) => ba -> SizedByteArray n ba+unsafeSizedByteArray = fromMaybe (error "The size is invalid") . sizedByteArray++instance (ByteArrayAccess ba, KnownNat n) => ByteArrayAccess (SizedByteArray n ba) where+    length _ = fromInteger $ natVal (Proxy @n)+    withByteArray (SizedByteArray ba) = withByteArray ba++instance (KnownNat n, ByteArray ba) => ByteArrayN n (SizedByteArray n ba) where+    allocRet p f = do+        (a, ba) <- ByteArray.allocRet n f+        pure (a, SizedByteArray ba)+      where+        n = fromInteger $ natVal p++#if MIN_VERSION_basement(0,0,7)+instance ( ByteArrayAccess (BlockN n ty)+         , PrimType ty+         , KnownNat n+         , Countable ty n+         , KnownNat nbytes+         , nbytes ~ (Base.PrimSize ty * n)+         ) => ByteArrayN nbytes (BlockN n ty) where+    allocRet _ f = do+        mba <- BlockN.new @n+        a   <- BlockN.withMutablePtrHint True False mba (f . castPtr)+        ba  <- BlockN.freeze mba+        return (a, ba)+#endif+++-- | Allocate a new bytearray of specific size, and run the initializer on this memory+alloc :: forall n ba p . (ByteArrayN n ba, KnownNat n)+      => (Ptr p -> IO ())+      -> IO ba+alloc f = snd <$> allocRet (Proxy @n) f++-- | Allocate a new bytearray of specific size, and run the initializer on this memory+create :: forall n ba p . (ByteArrayN n ba, KnownNat n)+       => (Ptr p -> IO ())+       -> IO ba+create = alloc @n+{-# NOINLINE create #-}++-- | similar to 'allocN' but hide the allocation and initializer in a pure context+allocAndFreeze :: forall n ba p . (ByteArrayN n ba, KnownNat n)+               => (Ptr p -> IO ()) -> ba+allocAndFreeze f = unsafeDoIO (alloc @n f)+{-# NOINLINE allocAndFreeze #-}++-- | similar to 'createN' but hide the allocation and initializer in a pure context+unsafeCreate :: forall n ba p . (ByteArrayN n ba, KnownNat n)+             => (Ptr p -> IO ()) -> ba+unsafeCreate f = unsafeDoIO (alloc @n f)+{-# NOINLINE unsafeCreate #-}++inlineUnsafeCreate :: forall n ba p . (ByteArrayN n ba, KnownNat n)+                   => (Ptr p -> IO ()) -> ba+inlineUnsafeCreate f = unsafeDoIO (alloc @n f)+{-# INLINE inlineUnsafeCreate #-}++-- | Create an empty byte array+empty :: forall ba . ByteArrayN 0 ba => ba+empty = unsafeDoIO (alloc @0 $ \_ -> return ())++-- | Pack a list of bytes into a bytearray+pack :: forall n ba . (ByteArrayN n ba, KnownNat n) => ListN n Word8 -> ba+pack l = inlineUnsafeCreate @n (fill $ unListN l)+  where fill []     _  = return ()+        fill (x:xs) !p = poke p x >> fill xs (p `plusPtr` 1)+        {-# INLINE fill #-}+{-# NOINLINE pack #-}++-- | Un-pack a bytearray into a list of bytes+unpack :: forall n ba+        . (ByteArrayN n ba, KnownNat n, NatWithinBound Int n, ByteArrayAccess ba)+       => ba -> ListN n Word8+unpack bs =  fromMaybe (error "the impossible appened") $ toListN @n $ loop 0+  where !len = length bs+        loop i+            | i == len  = []+            | otherwise =+                let !v = unsafeDoIO $ withByteArray bs (`peekByteOff` i)+                 in v : loop (i+1)++-- | prepend a single byte to a byte array+cons :: forall ni no bi bo+      . ( ByteArrayN ni bi, ByteArrayN no bo, ByteArrayAccess bi+        , KnownNat ni, KnownNat no+        , (ni + 1) ~ no+        )+     => Word8 -> bi -> bo+cons b ba = unsafeCreate @no $ \d -> withByteArray ba $ \s -> do+    pokeByteOff d 0 b+    memCopy (d `plusPtr` 1) s len+  where+    !len = fromInteger $ natVal (Proxy @ni)++-- | append a single byte to a byte array+snoc :: forall bi bo ni no+      . ( ByteArrayN ni bi, ByteArrayN no bo, ByteArrayAccess bi+        , KnownNat ni, KnownNat no+        , (ni + 1) ~ no+        )+     => bi -> Word8 -> bo+snoc ba b = unsafeCreate @no $ \d -> withByteArray ba $ \s -> do+    memCopy d s len+    pokeByteOff d len b+  where+    !len = fromInteger $ natVal (Proxy @ni)++-- | Create a xor of bytes between a and b.+--+-- the returns byte array is the size of the smallest input.+xor :: forall n a b c+     . ( ByteArrayN n a, ByteArrayN n b, ByteArrayN n c+       , ByteArrayAccess a, ByteArrayAccess b+       , KnownNat n+       )+    => a -> b -> c+xor a b =+    unsafeCreate @n $ \pc ->+    withByteArray a  $ \pa ->+    withByteArray b  $ \pb ->+        memXor pc pa pb n+  where+    n  = fromInteger (natVal (Proxy @n))++-- | return a specific byte indexed by a number from 0 in a bytearray+--+-- unsafe, no bound checking are done+index :: forall n na ba+       . ( ByteArrayN na ba, ByteArrayAccess ba+         , KnownNat na, KnownNat n+         , n <= na+         )+      => ba -> Proxy n -> Word8+index b pi = unsafeDoIO $ withByteArray b $ \p -> peek (p `plusPtr` i)+  where+    i = fromInteger $ natVal pi++-- | Split a bytearray at a specific length in two bytearray+splitAt :: forall nblhs nbi nbrhs bi blhs brhs+         . ( ByteArrayN nbi bi, ByteArrayN nblhs blhs, ByteArrayN nbrhs brhs+           , ByteArrayAccess bi+           , KnownNat nbi, KnownNat nblhs, KnownNat nbrhs+           , nblhs <= nbi, (nbrhs + nblhs) ~ nbi+           )+        => bi -> (blhs, brhs)+splitAt bs = unsafeDoIO $+    withByteArray bs $ \p -> do+        b1 <- alloc @nblhs $ \r -> memCopy r p n+        b2 <- alloc @nbrhs $ \r -> memCopy r (p `plusPtr` n) (len - n)+        return (b1, b2)+  where+    n = fromInteger $ natVal (Proxy @nblhs)+    len = length bs++-- | Take the first @n@ byte of a bytearray+take :: forall nbo nbi bi bo+      . ( ByteArrayN nbi bi, ByteArrayN nbo bo+        , ByteArrayAccess bi+        , KnownNat nbi, KnownNat nbo+        , nbo <= nbi+        )+     => bi -> bo+take bs = unsafeCreate @nbo $ \d -> withByteArray bs $ \s -> memCopy d s m+  where+    !m   = min len n+    !len = length bs+    !n   = fromInteger $ natVal (Proxy @nbo)++-- | drop the first @n@ byte of a bytearray+drop :: forall n nbi nbo bi bo+      . ( ByteArrayN nbi bi, ByteArrayN nbo bo+        , ByteArrayAccess bi+        , KnownNat n, KnownNat nbi, KnownNat nbo+        , (nbo + n) ~ nbi+        )+     => Proxy n -> bi -> bo+drop pn bs = unsafeCreate @nbo $ \d ->+    withByteArray bs $ \s ->+    memCopy d (s `plusPtr` ofs) nb+  where+    ofs = min len n+    nb  = len - ofs+    len = length bs+    n   = fromInteger $ natVal pn++-- | append one bytearray to the other+append :: forall nblhs nbrhs nbout blhs brhs bout+        . ( ByteArrayN nblhs blhs, ByteArrayN nbrhs brhs, ByteArrayN nbout bout+          , ByteArrayAccess blhs, ByteArrayAccess brhs+          , KnownNat nblhs, KnownNat nbrhs, KnownNat nbout+          , (nbrhs + nblhs) ~ nbout+          )+       => blhs -> brhs -> bout+append blhs brhs = unsafeCreate @nbout $ \p ->+    withByteArray blhs $ \plhs ->+    withByteArray brhs $ \prhs -> do+        memCopy p plhs (length blhs)+        memCopy (p `plusPtr` length blhs) prhs (length brhs)++-- | Duplicate a bytearray into another bytearray, and run an initializer on it+copy :: forall n bs1 bs2 p+      . ( ByteArrayN n bs1, ByteArrayN n bs2+        , ByteArrayAccess bs1+        , KnownNat n+        )+     => bs1 -> (Ptr p -> IO ()) -> IO bs2+copy bs f = alloc @n $ \d -> do+    withByteArray bs $ \s -> memCopy d s (length bs)+    f (castPtr d)++-- | Similar to 'copy' but also provide a way to return a value from the initializer+copyRet :: forall n bs1 bs2 p a+         . ( ByteArrayN n bs1, ByteArrayN n bs2+           , ByteArrayAccess bs1+           , KnownNat n+           )+        => bs1 -> (Ptr p -> IO a) -> IO (a, bs2)+copyRet bs f =+    allocRet (Proxy @n) $ \d -> do+        withByteArray bs $ \s -> memCopy d s (length bs)+        f (castPtr d)++-- | Similiar to 'copy' but expect the resulting bytearray in a pure context+copyAndFreeze :: forall n bs1 bs2 p+               . ( ByteArrayN n bs1, ByteArrayN n bs2+                 , ByteArrayAccess bs1+                 , KnownNat n+                 )+              => bs1 -> (Ptr p -> IO ()) -> bs2+copyAndFreeze bs f =+    inlineUnsafeCreate @n $ \d -> do+        copyByteArrayToPtr bs d+        f (castPtr d)+{-# NOINLINE copyAndFreeze #-}++-- | Create a bytearray of a specific size containing a repeated byte value+replicate :: forall n ba . (ByteArrayN n ba, KnownNat n)+          => Word8 -> ba+replicate b = inlineUnsafeCreate @n $ \ptr -> memSet ptr b (fromInteger $ natVal $ Proxy @n)+{-# NOINLINE replicate #-}++-- | Create a bytearray of a specific size initialized to 0+zero :: forall n ba . (ByteArrayN n ba, KnownNat n) => ba+zero = unsafeCreate @n $ \ptr -> memSet ptr 0 (fromInteger $ natVal $ Proxy @n)+{-# NOINLINE zero #-}++-- | Convert a bytearray to another type of bytearray+convert :: forall n bin bout+         . ( ByteArrayN n bin, ByteArrayN n bout+           , KnownNat n+           )+        => bin -> bout+convert bs = inlineUnsafeCreate @n (copyByteArrayToPtr bs)++-- | Convert a ByteArrayAccess to another type of bytearray+--+-- This function returns nothing if the size is not compatible+fromByteArrayAccess :: forall n bin bout+                     . ( ByteArrayAccess bin, ByteArrayN n bout+                       , KnownNat n+                       )+                    => bin -> Maybe bout+fromByteArrayAccess bs+    | l == n    = Just $ inlineUnsafeCreate @n (copyByteArrayToPtr bs)+    | otherwise = Nothing+  where+    l = length bs+    n = fromInteger $ natVal (Proxy @n)++-- | Convert a ByteArrayAccess to another type of bytearray+unsafeFromByteArrayAccess :: forall n bin bout+                           . ( ByteArrayAccess bin, ByteArrayN n bout+                             , KnownNat n+                           )+                          => bin -> bout+unsafeFromByteArrayAccess bs = case fromByteArrayAccess @n @bin @bout bs of+    Nothing -> error "Invalid Size"+    Just v  -> v
Data/ByteArray/Types.hs view
@@ -7,6 +7,10 @@ -- {-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE Rank2Types    #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies  #-}+{-# LANGUAGE UndecidableInstances #-} module Data.ByteArray.Types     ( ByteArrayAccess(..)     , ByteArray(..)@@ -21,6 +25,9 @@ import           Foreign.ForeignPtr (withForeignPtr) #endif +import           Data.Memory.PtrMethods (memCopy)++ #ifdef WITH_FOUNDATION_SUPPORT  #if MIN_VERSION_foundation(0,0,14) && MIN_VERSION_basement(0,0,0)@@ -37,13 +44,15 @@ import qualified Basement.String as Base (String, toBytes, Encoding(UTF8)) import qualified Basement.PrimType as Base (primSizeInBytes) -import           Data.Memory.PtrMethods (memCopy)- #if MIN_VERSION_basement(0,0,5) import qualified Basement.UArray.Mutable as BaseMutable (withMutablePtrHint, copyToPtr) import qualified Basement.Block as Block import qualified Basement.Block.Mutable as Block #endif+#if MIN_VERSION_basement(0,0,7)+import           Basement.Nat+import qualified Basement.BlockN as BlockN+#endif  #ifdef LEGACY_FOUNDATION_SUPPORT @@ -102,6 +111,13 @@     copyByteArrayToPtr ba dst = do         mb <- Block.unsafeThaw (baseBlockRecastW8 ba)         Block.copyToPtr mb 0 (castPtr dst) (Block.length $ baseBlockRecastW8 ba)+#endif++#if MIN_VERSION_basement(0,0,7)+instance (KnownNat n, Base.PrimType ty, Base.Countable ty n) => ByteArrayAccess (BlockN.BlockN n ty) where+    length a = let Base.CountOf i = BlockN.lengthBytes a in i+    withByteArray a f = BlockN.withPtr a (f . castPtr)+    copyByteArrayToPtr bna = copyByteArrayToPtr (BlockN.toBlock bna) #endif  baseUarrayRecastW8 :: Base.PrimType ty => Base.UArray ty -> Base.UArray Word8
Data/Memory/Hash/SipHash.hs view
@@ -9,6 +9,7 @@ -- reference: <http://131002.net/siphash/siphash.pdf> -- {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveDataTypeable #-} module Data.Memory.Hash.SipHash     ( SipKey(..)     , SipHash(..)@@ -20,6 +21,7 @@ import           Data.Memory.Internal.Compat import           Data.Word import           Data.Bits+import           Data.Typeable (Typeable) import           Control.Monad import           Foreign.Ptr import           Foreign.Storable@@ -29,7 +31,7 @@  -- | Siphash tag value newtype SipHash = SipHash Word64-    deriving (Show,Eq,Ord)+    deriving (Show,Eq,Ord,Typeable)  data InternalState = InternalState {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64 {-# UNPACK #-} !Word64 
memory.cabal view
@@ -1,5 +1,5 @@ Name:                memory-version:             0.14.14+version:             0.14.15 Synopsis:            memory and related abstraction stuff Description:     Chunk of memory, polymorphic byte array management and manipulation@@ -98,6 +98,8 @@     CPP-options:     -DWITH_FOUNDATION_SUPPORT     Build-depends:   basement,                      foundation >= 0.0.8+    if impl(ghc >= 8.0)+      Exposed-modules: Data.ByteArray.Sized    ghc-options:       -Wall -fwarn-tabs   default-language:  Haskell2010@@ -111,12 +113,10 @@                      Utils   Build-Depends:     base >= 3 && < 5                    , bytestring-                   , tasty-                   , tasty-quickcheck-                   , tasty-hunit                    , memory+                   , basement+                   , foundation >= 0.0.8   ghc-options:       -Wall -fno-warn-orphans -fno-warn-missing-signatures -threaded   default-language:  Haskell2010   if flag(support_foundation)     CPP-options:     -DWITH_FOUNDATION_SUPPORT-    Build-depends:   basement, foundation >= 0.0.8
tests/Imports.hs view
@@ -2,11 +2,10 @@     ( module X     ) where -import Control.Applicative as X-import Control.Monad as X-import Data.Foldable as X (foldl')-import Data.Monoid as X+import Prelude as X (zip)+import Control.Monad as X (replicateM)+import Data.List as X (concatMap) -import Test.Tasty as X-import Test.Tasty.HUnit as X-import Test.Tasty.QuickCheck as X hiding (vector)+import Foundation as X+import Foundation.Collection as X (nonEmpty_)+import Foundation.Check as X
tests/SipHash.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ViewPatterns #-}+{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE OverloadedStrings #-} module SipHash (tests) where @@ -268,9 +269,9 @@       )     ] -katTests witnessID v = map makeTest $ numberedList v-    where makeTest (i, (key,msg,tag)) = testCase ("kat " ++ show i) $ tag @=? sipHash key (witnessID $ B.pack $ unS msg)+katTests witnessID v = makeTest <$> numberedList v+    where makeTest (i, (key,msg,tag)) = Property ("kat " <> show i) $ tag === sipHash key (witnessID $ B.pack $ unS msg)  tests witnessID =-    [ testGroup "KAT" $ katTests witnessID vectors+    [ Group "KAT" $ katTests witnessID vectors     ]
tests/Tests.hs view
@@ -1,9 +1,13 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE Rank2Types #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE OverloadedStrings #-} module Main where  import           Imports+import           Foundation.Check.Main import           Utils import           Data.Char                    (chr) import           Data.Word@@ -23,6 +27,11 @@ import           Basement.UArray (UArray) #endif +newtype Positive = Positive Word+  deriving (Show, Eq, Ord)+instance Arbitrary Positive where+    arbitrary = Positive <$> between (0, 255)+ data Backend = BackendByte | BackendScrubbedBytes #ifdef WITH_FOUNDATION_SUPPORT #if MIN_VERSION_basement(0,0,5)@@ -32,32 +41,32 @@ #endif     deriving (Show,Eq,Bounded,Enum) -allBackends :: [Backend]-allBackends = enumFrom BackendByte+allBackends :: NonEmpty [Backend]+allBackends = nonEmpty_ $ enumFrom BackendByte  data ArbitraryBS = forall a . ByteArray a => ArbitraryBS a -arbitraryBS :: Int -> Gen ArbitraryBS+arbitraryBS :: Word -> Gen ArbitraryBS arbitraryBS n = do     backend <- elements allBackends     case backend of-        BackendByte          -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM n arbitrary) :: Gen Bytes)-        BackendScrubbedBytes -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM n arbitrary) :: Gen ScrubbedBytes)+        BackendByte          -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM (fromIntegral n) arbitrary) :: Gen Bytes)+        BackendScrubbedBytes -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM (fromIntegral n) arbitrary) :: Gen ScrubbedBytes) #ifdef WITH_FOUNDATION_SUPPORT #if MIN_VERSION_basement(0,0,5)-        BackendBlock         -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM n arbitrary) :: Gen (Block Word8))+        BackendBlock         -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM (fromIntegral n) arbitrary) :: Gen (Block Word8)) #endif-        BackendUArray        -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM n arbitrary) :: Gen (UArray Word8))+        BackendUArray        -> ArbitraryBS `fmap` ((B.pack `fmap` replicateM (fromIntegral n) arbitrary) :: Gen (UArray Word8)) #endif -arbitraryBSof :: Int -> Int -> Gen ArbitraryBS-arbitraryBSof minBytes maxBytes = choose (minBytes, maxBytes) >>= arbitraryBS+arbitraryBSof :: Word -> Word -> Gen ArbitraryBS+arbitraryBSof minBytes maxBytes = between (minBytes, maxBytes) >>= arbitraryBS  newtype SmallList a = SmallList [a]     deriving (Show,Eq)  instance Arbitrary a => Arbitrary (SmallList a) where-    arbitrary = choose (0,8) >>= \n -> SmallList `fmap` replicateM n arbitrary+    arbitrary = between (0,8) >>= \n -> SmallList `fmap` replicateM (fromIntegral n) arbitrary  instance Arbitrary ArbitraryBS where     arbitrary = arbitraryBSof 0 259@@ -66,32 +75,32 @@     deriving (Show,Eq)  instance Arbitrary Words8 where-    arbitrary = choose (0, 259) >>= \n -> Words8 <$> replicateM n arbitrary+    arbitrary = between (0, 259) >>= \n -> Words8 <$> replicateM (fromIntegral n) arbitrary -testGroupBackends :: String -> (forall ba . (Show ba, Eq ba, ByteArray ba) => (ba -> ba) -> [TestTree]) -> TestTree+testGroupBackends :: String -> (forall ba . (Show ba, Eq ba, Typeable ba, ByteArray ba) => (ba -> ba) -> [Test]) -> Test testGroupBackends x l =-    testGroup x-        [ testGroup "Bytes" (l withBytesWitness)-        , testGroup "ScrubbedBytes" (l withScrubbedBytesWitness)+    Group x+        [ Group "Bytes" (l withBytesWitness)+        , Group "ScrubbedBytes" (l withScrubbedBytesWitness) #ifdef WITH_FOUNDATION_SUPPORT #if MIN_VERSION_basement(0,0,5)-        , testGroup "Block" (l withBlockWitness)+        , Group "Block" (l withBlockWitness) #endif-        , testGroup "UArray" (l withUArrayWitness)+        , Group "UArray" (l withUArrayWitness) #endif         ] -testShowProperty :: Testable a+testShowProperty :: IsProperty a                  => String-                 -> (forall ba . (Show ba, Eq ba, ByteArray ba) => (ba -> ba) -> ([Word8] -> String) -> a)-                 -> TestTree+                 -> (forall ba . (Show ba, Eq ba, Typeable ba, ByteArray ba) => (ba -> ba) -> ([Word8] -> String) -> a)+                 -> Test testShowProperty x p =-    testGroup x-        [ testProperty "Bytes" (p withBytesWitness showLikeString)-        , testProperty "ScrubbedBytes" (p withScrubbedBytesWitness showLikeEmptySB)+    Group x+        [ Property "Bytes" (p withBytesWitness showLikeString)+        , Property "ScrubbedBytes" (p withScrubbedBytesWitness showLikeEmptySB)         ]   where-    showLikeString  l = show $ map (chr . fromIntegral) l+    showLikeString  l = show $ (chr . fromIntegral) <$> l     showLikeEmptySB _ = show (withScrubbedBytesWitness B.empty)  base64Kats =@@ -132,84 +141,84 @@     ]  encodingTests witnessID =-    [ testGroup "BASE64"-        [ testGroup "encode-KAT" encodeKats64-        , testGroup "decode-KAT" decodeKats64+    [ Group "BASE64"+        [ Group "encode-KAT" encodeKats64+        , Group "decode-KAT" decodeKats64         ]-    , testGroup "BASE64URL"-        [ testGroup "encode-KAT" encodeKats64URLUnpadded-        , testGroup "decode-KAT" decodeKats64URLUnpadded+    , Group "BASE64URL"+        [ Group "encode-KAT" encodeKats64URLUnpadded+        , Group "decode-KAT" decodeKats64URLUnpadded         ]-    , testGroup "BASE32"-        [ testGroup "encode-KAT" encodeKats32-        , testGroup "decode-KAT" decodeKats32+    , Group "BASE32"+        [ Group "encode-KAT" encodeKats32+        , Group "decode-KAT" decodeKats32         ]-    , testGroup "BASE16"-        [ testGroup "encode-KAT" encodeKats16-        , testGroup "decode-KAT" decodeKats16+    , Group "BASE16"+        [ Group "encode-KAT" encodeKats16+        , Group "decode-KAT" decodeKats16         ]     ]   where-        encodeKats64 = map (toTest B.Base64) $ zip [1..] base64Kats-        decodeKats64 = map (toBackTest B.Base64) $ zip [1..] base64Kats-        encodeKats32 = map (toTest B.Base32) $ zip [1..] base32Kats-        decodeKats32 = map (toBackTest B.Base32) $ zip [1..] base32Kats-        encodeKats16 = map (toTest B.Base16) $ zip [1..] base16Kats-        decodeKats16 = map (toBackTest B.Base16) $ zip [1..] base16Kats-        encodeKats64URLUnpadded = map (toTest B.Base64URLUnpadded) $ zip [1..] base64URLKats-        decodeKats64URLUnpadded = map (toBackTest B.Base64URLUnpadded) $ zip [1..] base64URLKats+        encodeKats64 = fmap (toTest B.Base64) $ zip [1..] base64Kats+        decodeKats64 = fmap (toBackTest B.Base64) $ zip [1..] base64Kats+        encodeKats32 = fmap (toTest B.Base32) $ zip [1..] base32Kats+        decodeKats32 = fmap (toBackTest B.Base32) $ zip [1..] base32Kats+        encodeKats16 = fmap (toTest B.Base16) $ zip [1..] base16Kats+        decodeKats16 = fmap (toBackTest B.Base16) $ zip [1..] base16Kats+        encodeKats64URLUnpadded = fmap (toTest B.Base64URLUnpadded) $ zip [1..] base64URLKats+        decodeKats64URLUnpadded = fmap (toBackTest B.Base64URLUnpadded) $ zip [1..] base64URLKats -        toTest :: B.Base -> (Int, (String, String)) -> TestTree-        toTest base (i, (inp, out)) = testCase (show i) $+        toTest :: B.Base -> (Int, (LString, LString)) -> Test+        toTest base (i, (inp, out)) = Property (show i) $             let inpbs = witnessID $ B.convertToBase base $ witnessID $ B.pack $ unS inp                 outbs = witnessID $ B.pack $ unS out-             in outbs @=? inpbs-        toBackTest :: B.Base -> (Int, (String, String)) -> TestTree-        toBackTest base (i, (inp, out)) = testCase (show i) $+             in outbs === inpbs+        toBackTest :: B.Base -> (Int, (LString, LString)) -> Test+        toBackTest base (i, (inp, out)) = Property (show i) $             let inpbs = witnessID $ B.pack $ unS inp                 outbs = B.convertFromBase base $ witnessID $ B.pack $ unS out-             in Right inpbs @=? outbs+             in Right inpbs === outbs  -- check not to touch internal null pointer of the empty ByteString bsNullEncodingTest =-    testGroup "BS-null"-      [ testGroup "BASE64"-        [ testCase "encode-KAT" $ toTest B.Base64-        , testCase "decode-KAT" $ toBackTest B.Base64+    Group "BS-null"+      [ Group "BASE64"+        [ Property "encode-KAT" $ toTest B.Base64+        , Property "decode-KAT" $ toBackTest B.Base64         ]-      , testGroup "BASE32"-        [ testCase "encode-KAT" $ toTest B.Base32-        , testCase "decode-KAT" $ toBackTest B.Base32+      , Group "BASE32"+        [ Property "encode-KAT" $ toTest B.Base32+        , Property "decode-KAT" $ toBackTest B.Base32         ]-      , testGroup "BASE16"-        [ testCase "encode-KAT" $ toTest B.Base16-        , testCase "decode-KAT" $ toBackTest B.Base16+      , Group "BASE16"+        [ Property "encode-KAT" $ toTest B.Base16+        , Property "decode-KAT" $ toBackTest B.Base16         ]       ]   where     toTest base =-      B.convertToBase base BS.empty @=? BS.empty+      B.convertToBase base BS.empty === BS.empty     toBackTest base =-      B.convertFromBase base BS.empty @=? Right BS.empty+      B.convertFromBase base BS.empty === Right BS.empty  parsingTests witnessID =-    [ testCase "parse" $+    [ CheckPlan "parse" $         let input = witnessID $ B.pack $ unS "xx abctest"             abc   = witnessID $ B.pack $ unS "abc"             est   = witnessID $ B.pack $ unS "est"             result = Parse.parse ((,,) <$> Parse.take 2 <*> Parse.byte 0x20 <*> (Parse.bytes abc *> Parse.anyByte)) input          in case result of-                Parse.ParseOK remaining (_,_,_) -> est @=? remaining-                _                               -> assertFailure ""+                Parse.ParseOK remaining (_,_,_) -> validate "remaining" $ est === remaining+                _                               -> validate "unexpected result" False     ] -main = defaultMain $ testGroup "memory"-    [ localOption (QuickCheckTests 5000) $ testGroupBackends "basic" basicProperties+main = defaultMain $ Group "memory"+    [ testGroupBackends "basic" basicProperties     , bsNullEncodingTest     , testGroupBackends "encoding" encodingTests     , testGroupBackends "parsing" parsingTests     , testGroupBackends "hashing" $ \witnessID ->-        [ testGroup "SipHash" $ SipHash.tests witnessID+        [ Group "SipHash" $ SipHash.tests witnessID         ]     , testShowProperty "showing" $ \witnessID expectedShow (Words8 l) ->           (show . witnessID . B.pack $ l) == expectedShow l@@ -219,69 +228,69 @@     ]   where     basicProperties witnessID =-        [ testProperty "unpack . pack == id" $ \(Words8 l) -> l == (B.unpack . witnessID . B.pack $ l)-        , testProperty "self-eq" $ \(Words8 l) -> let b = witnessID . B.pack $ l in b == b-        , testProperty "add-empty-eq" $ \(Words8 l) ->+        [ Property "unpack . pack == id" $ \(Words8 l) -> l == (B.unpack . witnessID . B.pack $ l)+        , Property "self-eq" $ \(Words8 l) -> let b = witnessID . B.pack $ l in b == b+        , Property "add-empty-eq" $ \(Words8 l) ->             let b = witnessID $ B.pack l              in B.append b B.empty == b-        , testProperty "zero" $ \(Positive n) ->-            let expected = witnessID $ B.pack $ replicate n 0-             in expected == B.zero n-        , testProperty "Ord" $ \(Words8 l1) (Words8 l2) ->+        , Property "zero" $ \(Positive n) ->+            let expected = witnessID $ B.pack $ replicate (fromIntegral n) 0+             in expected == B.zero (fromIntegral n)+        , Property "Ord" $ \(Words8 l1) (Words8 l2) ->             compare l1 l2 == compare (witnessID $ B.pack l1) (B.pack l2)-        , testProperty "Monoid(mappend)" $ \(Words8 l1) (Words8 l2) ->+        , Property "Monoid(mappend)" $ \(Words8 l1) (Words8 l2) ->             mappend l1 l2 == (B.unpack $ mappend (witnessID $ B.pack l1) (B.pack l2))-        , testProperty "Monoid(mconcat)" $ \(SmallList l) ->-            mconcat (map unWords8 l) == (B.unpack $ mconcat $ map (witnessID . B.pack . unWords8) l)-        , testProperty "append (append a b) c == append a (append b c)" $ \(Words8 la) (Words8 lb) (Words8 lc) ->+        , Property "Monoid(mconcat)" $ \(SmallList l) ->+            mconcat (fmap unWords8 l) == (B.unpack $ mconcat $ fmap (witnessID . B.pack . unWords8) l)+        , Property "append (append a b) c == append a (append b c)" $ \(Words8 la) (Words8 lb) (Words8 lc) ->             let a = witnessID $ B.pack la                 b = witnessID $ B.pack lb                 c = witnessID $ B.pack lc              in B.append (B.append a b) c == B.append a (B.append b c)-        , testProperty "concat l" $ \(SmallList l) ->-            let chunks   = map (witnessID . B.pack . unWords8) l+        , Property "concat l" $ \(SmallList l) ->+            let chunks   = fmap (witnessID . B.pack . unWords8) l                 expected = concatMap unWords8 l              in B.pack expected == witnessID (B.concat chunks)-        , testProperty "cons b bs == reverse (snoc (reverse bs) b)" $ \(Words8 l) b ->+        , Property "cons b bs == reverse (snoc (reverse bs) b)" $ \(Words8 l) b ->             let b1 = witnessID (B.pack l)                 b2 = witnessID (B.pack (reverse l))                 expected = B.pack (reverse (B.unpack (B.snoc b2 b)))              in B.cons b b1 == expected-        , testProperty "all == Prelude.all" $ \(Words8 l) b ->+        , Property "all == Prelude.all" $ \(Words8 l) b ->             let b1 = witnessID (B.pack l)                 p  = (/= b)              in B.all p b1 == all p l-        , testProperty "any == Prelude.any" $ \(Words8 l) b ->+        , Property "any == Prelude.any" $ \(Words8 l) b ->             let b1 = witnessID (B.pack l)                 p  = (== b)              in B.any p b1 == any p l-        , testProperty "singleton b == pack [b]" $ \b ->+        , Property "singleton b == pack [b]" $ \b ->             witnessID (B.singleton b) == B.pack [b]-        , testProperty "span" $ \x (Words8 l) ->+        , Property "span" $ \x (Words8 l) ->             let c = witnessID (B.pack l)                 (a, b) = B.span (== x) c              in c == B.append a b-        , testProperty "span (const True)" $ \(Words8 l) ->+        , Property "span (const True)" $ \(Words8 l) ->             let a = witnessID (B.pack l)              in B.span (const True) a == (a, B.empty)-        , testProperty "span (const False)" $ \(Words8 l) ->+        , Property "span (const False)" $ \(Words8 l) ->             let b = witnessID (B.pack l)              in B.span (const False) b == (B.empty, b)         ]  #ifdef WITH_FOUNDATION_SUPPORT-testFoundationTypes = testGroup "Foundation"-  [ testCase "allocRet 4 _ :: F.UArray Int8 === 4" $ do-      x <- (B.length :: F.UArray F.Int8 -> Int) . snd <$> B.allocRet 4 (const $ return ())-      assertEqual "" 4 x-  , testCase "allocRet 4 _ :: F.UArray Int16 === 4" $ do-      x <- (B.length :: F.UArray F.Int16 -> Int) . snd <$> B.allocRet 4 (const $ return ())-      assertEqual "" 4 x-  , testCase "allocRet 4 _ :: F.UArray Int32 === 4" $ do-      x <- (B.length :: F.UArray F.Int32 -> Int) . snd <$> B.allocRet 4 (const $ return ())-      assertEqual "" 4 x-  , testCase "allocRet 4 _ :: F.UArray Int64 === 8" $ do-      x <- (B.length :: F.UArray F.Int64 -> Int) . snd <$> B.allocRet 4 (const $ return ())-      assertEqual "" 8 x+testFoundationTypes = Group "Foundation"+  [ CheckPlan "allocRet 4 _ :: F.UArray Int8 === 4" $ do+      x <- pick "allocateRet 4 _" $ (B.length :: F.UArray F.Int8 -> Int) . snd <$> B.allocRet 4 (const $ return ())+      validate "4 === x" $ x === 4+  , CheckPlan "allocRet 4 _ :: F.UArray Int16 === 4" $ do+      x <- pick "allocateRet 4 _" $ (B.length :: F.UArray F.Int16 -> Int) . snd <$> B.allocRet 4 (const $ return ())+      validate "4 === x" $ x === 4+  , CheckPlan "allocRet 4 _ :: F.UArray Int32 === 4" $ do+      x <- pick "allocateRet 4 _" $ (B.length :: F.UArray F.Int32 -> Int) . snd <$> B.allocRet 4 (const $ return ())+      validate "4 === x" $ x === 4+  , CheckPlan "allocRet 4 _ :: F.UArray Int64 === 8" $ do+      x <- pick "allocateRet 4 _" $ (B.length :: F.UArray F.Int64 -> Int) . snd <$> B.allocRet 4 (const $ return ())+      validate "8 === x" $ x === 8   ] #endif