packages feed

primitive-checked (empty) → 0.6.3.0

raw patch · 8 files changed

+610/−0 lines, 8 filesdep +basedep +primitivesetup-changed

Dependencies added: base, primitive

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Andrew Martin (c) 2018++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Andrew Martin nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,4 @@+# primitive-checked++A drop-in replacement for the `primitive` library that adds bounds-checking+to prevent segfaults. This is only intended to be used in test environments.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ primitive-checked.cabal view
@@ -0,0 +1,54 @@+name: primitive-checked+version: 0.6.3.0+synopsis: primitive functions with bounds-checking+homepage: https://github.com/andrewthad/primitive-checked#readme+bug-reports: https://github.com/andrewthad/primitive-checked/issues+author: Andrew Martin+maintainer: andrew.thaddeus@gmail.com+copyright: 2018 Andrew Martin+license: BSD3+license-file: LICENSE+build-type: Simple+cabal-version: >= 1.21+description:+  .+  This library is intended to be used as a drop-in replacement for+  the `primitive` library in test environments. It adds bounds-checking+  to all functions in `primitive` that are able to cause segfaults.+  It is not recommended to use this library in production. However,+  if you are testing a library or application you wrote that uses+  `primitive`, you can temporarily replace your `primitive` dependency+  with `primitive-checked`, and your segfaults will become normal+  haskell exceptions that you can hunt down with GHC's stack trace+  facilities.+  .+  The versioning for this library matches the version of primitive+  that is targeted. The first three digits of the version match the+  version of `primitive`. The fourth digit is used for bug fixes.++extra-source-files:+  README.md++source-repository head+  type: git+  location: https://github.com/andrewthad/primitive-checked++library+  hs-source-dirs:+      src+  build-depends:+      base >=4.7 && <5+    , primitive == 0.6.3.*+  exposed-modules:+    Data.Primitive.Array+    Data.Primitive.SmallArray+    Data.Primitive.ByteArray+    Data.Primitive.UnliftedArray+  reexported-modules:+      Control.Monad.Primitive+    , Data.Primitive.Addr+    , Data.Primitive.MachDeps+    , Data.Primitive.MutVar+    , Data.Primitive.Types+  default-language: Haskell2010+
+ src/Data/Primitive/Array.hs view
@@ -0,0 +1,124 @@+{-# LANGUAGE PackageImports #-}++module Data.Primitive.Array+  ( Array(..)+  , MutableArray(..)+  , newArray+  , readArray+  , writeArray+  , indexArray+  , indexArrayM+  , freezeArray+  , thawArray+  , A.unsafeFreezeArray+  , A.unsafeThawArray+  , A.sameMutableArray+  , copyArray+  , copyMutableArray+  , cloneArray+  , cloneMutableArray+  , A.sizeofArray+  , A.sizeofMutableArray+  ) where++import Control.Monad.Primitive (PrimMonad,PrimState)+import Control.Exception (throw, ArrayException(..))+import "primitive" Data.Primitive.Array (Array,MutableArray)+import qualified "primitive" Data.Primitive.Array as A++check :: String -> Bool -> a -> a+check _      True  x = x+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.Array.Checked." ++ errMsg)++newArray :: PrimMonad m => Int -> a -> m (MutableArray (PrimState m) a)+newArray n x = check "newArray: negative size" (n>=0) (A.newArray n x)++readArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> m a+readArray marr i = do+  let siz = A.sizeofMutableArray marr+  check "readArray: index of out bounds" (i>=0 && i<siz) (A.readArray marr i)++writeArray :: PrimMonad m => MutableArray (PrimState m) a -> Int -> a -> m ()+writeArray marr i x = do+  let siz = A.sizeofMutableArray marr+  check "writeArray: index of out bounds" (i>=0 && i<siz) (A.writeArray marr i x)++indexArray :: Array a -> Int -> a+indexArray arr i = check "indexArray: index of out bounds"+  (i>=0 && i<A.sizeofArray arr)+  (A.indexArray arr i)++indexArrayM :: Monad m => Array a -> Int -> m a+indexArrayM arr i = check "indexArrayM: index of out bounds"+    (i>=0 && i<A.sizeofArray arr)+    (A.indexArrayM arr i)++freezeArray+  :: PrimMonad m+  => MutableArray (PrimState m) a -- ^ source+  -> Int                          -- ^ offset+  -> Int                          -- ^ length+  -> m (Array a)+freezeArray marr s l = do+  let siz = A.sizeofMutableArray marr+  check "freezeArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=siz)+    (A.freezeArray marr s l)++thawArray+  :: PrimMonad m+  => Array a -- ^ source+  -> Int     -- ^ offset+  -> Int     -- ^ length+  -> m (MutableArray (PrimState m) a)+thawArray arr s l = check "thawArr: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=A.sizeofArray arr)+    (A.thawArray arr s l)++copyArray :: PrimMonad m+          => MutableArray (PrimState m) a    -- ^ destination array+          -> Int                             -- ^ offset into destination array+          -> Array a                         -- ^ source array+          -> Int                             -- ^ offset into source array+          -> Int                             -- ^ number of elements to copy+          -> m ()+copyArray marr s1 arr s2 l = do+  let siz = A.sizeofMutableArray marr+  check "copyArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=A.sizeofArray arr && (s1+l)<=siz)+    (A.copyArray marr s1 arr s2 l)+++copyMutableArray :: PrimMonad m+          => MutableArray (PrimState m) a    -- ^ destination array+          -> Int                             -- ^ offset into destination array+          -> MutableArray (PrimState m) a    -- ^ source array+          -> Int                             -- ^ offset into source array+          -> Int                             -- ^ number of elements to copy+          -> m ()+copyMutableArray marr1 s1 marr2 s2 l = do+  let siz1 = A.sizeofMutableArray marr1+  let siz2 = A.sizeofMutableArray marr2+  check "copyMutableArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)+    (A.copyMutableArray marr1 s1 marr2 s2 l)+++cloneArray :: Array a -- ^ source array+           -> Int     -- ^ offset into destination array+           -> Int     -- ^ number of elements to copy+           -> Array a+cloneArray arr s l = check "cloneArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=A.sizeofArray arr)+    (A.cloneArray arr s l)++cloneMutableArray :: PrimMonad m+        => MutableArray (PrimState m) a -- ^ source array+        -> Int                          -- ^ offset into destination array+        -> Int                          -- ^ number of elements to copy+        -> m (MutableArray (PrimState m) a)+cloneMutableArray marr s l = do+  let siz = A.sizeofMutableArray marr+  check "cloneMutableArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=siz)+    (A.cloneMutableArray marr s l)
+ src/Data/Primitive/ByteArray.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE PackageImports #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Data.Primitive.ByteArray+  ( -- * Types+    A.ByteArray(..)+  , A.MutableByteArray(..)+  , A.ByteArray#+  , A.MutableByteArray#+    -- * Allocation+  , newByteArray+  , newPinnedByteArray+  , newAlignedPinnedByteArray+    -- * Element access+  , readByteArray+  , writeByteArray+  , indexByteArray+    -- * Folding+  , A.foldrByteArray+    -- * Freezing and thawing+  , A.unsafeFreezeByteArray+  , A.unsafeThawByteArray+    -- * Block operations+  , copyByteArray+  , copyMutableByteArray+  , moveByteArray+  , setByteArray+  , fillByteArray+  -- * Information+  , A.sizeofByteArray+  , A.sizeofMutableByteArray+  , A.sameMutableByteArray+  , A.byteArrayContents+  , A.mutableByteArrayContents+  ) where++import Control.Monad.Primitive (PrimMonad,PrimState)+import Control.Exception (throw, ArrayException(..))+import Data.Primitive.Types (Prim,sizeOf)+import Data.Proxy (Proxy(..))+import Data.Word (Word8)+import "primitive" Data.Primitive.ByteArray (ByteArray,MutableByteArray)+import qualified "primitive" Data.Primitive.ByteArray as A++check :: String -> Bool -> a -> a+check _      True  x = x+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.SmallArray.Checked." ++ errMsg)++elementSizeofByteArray :: forall a. Prim a => Proxy a -> ByteArray -> Int+elementSizeofByteArray _ arr = div (A.sizeofByteArray arr) (sizeOf (undefined :: a))++elementSizeofMutableByteArray :: forall s a. Prim a => Proxy a -> MutableByteArray s -> Int+elementSizeofMutableByteArray _ arr = div (A.sizeofMutableByteArray arr) (sizeOf (undefined :: a))++newByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m))+newByteArray n = check "newByteArray: negative size" (n>=0) (A.newByteArray n)++newPinnedByteArray :: PrimMonad m => Int -> m (MutableByteArray (PrimState m))+newPinnedByteArray n = check "newPinnedByteArray: negative size" (n>=0) (A.newPinnedByteArray n)++newAlignedPinnedByteArray :: PrimMonad m => Int -> Int -> m (MutableByteArray (PrimState m))+newAlignedPinnedByteArray n k = check "newAlignedPinnedByteArray: negative size" (n>=0) (A.newAlignedPinnedByteArray n k)++readByteArray :: forall m a. (Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> m a+readByteArray marr i = do+  let siz = elementSizeofMutableByteArray (Proxy :: Proxy a) marr+  check "readByteArray: index of out bounds" (i>=0 && i<siz) (A.readByteArray marr i)++writeByteArray :: forall m a. (Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> a -> m ()+writeByteArray marr i x = do+  let siz = elementSizeofMutableByteArray (Proxy :: Proxy a) marr+  check "writeByteArray: index of out bounds" (i>=0 && i<siz) (A.writeByteArray marr i x)++indexByteArray :: forall a. Prim a => ByteArray -> Int -> a+indexByteArray arr i = check "indexSmallArray: index of out bounds"+  (i>=0 && i< elementSizeofByteArray (Proxy :: Proxy a) arr)+  (A.indexByteArray arr i)++copyByteArray :: forall m. PrimMonad m+  => MutableByteArray (PrimState m) -- ^ destination array+  -> Int -- ^ offset into destination array+  -> ByteArray -- ^ source array+  -> Int -- ^ offset into source array+  -> Int -- ^ number of elements to copy+  -> m ()+copyByteArray marr s1 arr s2 l = do+  let siz = A.sizeofMutableByteArray marr+  check "copyByteArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<= A.sizeofByteArray arr && (s1+l)<=siz)+    (A.copyByteArray marr s1 arr s2 l)+++copyMutableByteArray :: forall m. PrimMonad m+  => MutableByteArray (PrimState m) -- ^ destination array+  -> Int -- ^ offset into destination array+  -> MutableByteArray (PrimState m) -- ^ source array+  -> Int -- ^ offset into source array+  -> Int -- ^ number of elements to copy+  -> m ()+copyMutableByteArray marr1 s1 marr2 s2 l = do+  let siz1 = A.sizeofMutableByteArray marr1+  let siz2 = A.sizeofMutableByteArray marr2+  check "copyMutableByteArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)+    (A.copyMutableByteArray marr1 s1 marr2 s2 l)++moveByteArray :: forall m. PrimMonad m+  => MutableByteArray (PrimState m) -- ^ destination array+  -> Int -- ^ offset into destination array+  -> MutableByteArray (PrimState m) -- ^ source array+  -> Int -- ^ offset into source array+  -> Int -- ^ number of elements to copy+  -> m ()+moveByteArray marr1 s1 marr2 s2 l = do+  let siz1 = A.sizeofMutableByteArray marr1+  let siz2 = A.sizeofMutableByteArray marr2+  check "moveByteArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)+    (A.moveByteArray marr1 s1 marr2 s2 l)++fillByteArray :: PrimMonad m+  => MutableByteArray (PrimState m) -- ^ array to fill+  -> Int -- ^ offset into array+  -> Int -- ^ number of bytes to fill+  -> Word8 -- ^ byte to fill with+  -> m ()+fillByteArray = setByteArray++setByteArray :: forall m a. (Prim a, PrimMonad m)+  => MutableByteArray (PrimState m) -- ^ array to fill+  -> Int -- ^ offset into array+  -> Int -- ^ number of values to fill+  -> a -- ^ value to fill with+  -> m ()+{-# INLINE setByteArray #-}+setByteArray dst doff sz x  = +  check "copyMutableByteArray: index range of out bounds"+    (doff>=0 && (doff+sz)<=elementSizeofMutableByteArray (Proxy :: Proxy a) dst)+    (A.setByteArray dst doff sz x)+
+ src/Data/Primitive/SmallArray.hs view
@@ -0,0 +1,123 @@+{-# LANGUAGE PackageImports #-}++module Data.Primitive.SmallArray+  ( SmallArray(..)+  , SmallMutableArray(..)+  , newSmallArray+  , readSmallArray+  , writeSmallArray+  , indexSmallArray+  , indexSmallArrayM+  , freezeSmallArray+  , thawSmallArray+  , A.unsafeFreezeSmallArray+  , A.unsafeThawSmallArray+  , copySmallArray+  , copySmallMutableArray+  , cloneSmallArray+  , cloneSmallMutableArray+  , A.sizeofSmallArray+  , A.sizeofSmallMutableArray+  ) where++import Control.Monad.Primitive (PrimMonad,PrimState)+import Control.Exception (throw, ArrayException(..))+import "primitive" Data.Primitive.SmallArray (SmallArray,SmallMutableArray)+import qualified "primitive" Data.Primitive.SmallArray as A++check :: String -> Bool -> a -> a+check _      True  x = x+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.SmallArray.Checked." ++ errMsg)++newSmallArray :: PrimMonad m => Int -> a -> m (SmallMutableArray (PrimState m) a)+newSmallArray n x = check "newSmallArray: negative size" (n>=0) (A.newSmallArray n x)++readSmallArray :: PrimMonad m => SmallMutableArray (PrimState m) a -> Int -> m a+readSmallArray marr i = do+  let siz = A.sizeofSmallMutableArray marr+  check "readSmallArray: index of out bounds" (i>=0 && i<siz) (A.readSmallArray marr i)++writeSmallArray :: PrimMonad m => SmallMutableArray (PrimState m) a -> Int -> a -> m ()+writeSmallArray marr i x = do+  let siz = A.sizeofSmallMutableArray marr+  check "writeSmallArray: index of out bounds" (i>=0 && i<siz) (A.writeSmallArray marr i x)++indexSmallArray :: SmallArray a -> Int -> a+indexSmallArray arr i = check "indexSmallArray: index of out bounds"+  (i>=0 && i<A.sizeofSmallArray arr)+  (A.indexSmallArray arr i)++indexSmallArrayM :: Monad m => SmallArray a -> Int -> m a+indexSmallArrayM arr i = check "indexSmallArrayM: index of out bounds"+    (i>=0 && i<A.sizeofSmallArray arr)+    (A.indexSmallArrayM arr i)++freezeSmallArray+  :: PrimMonad m+  => SmallMutableArray (PrimState m) a -- ^ source+  -> Int                          -- ^ offset+  -> Int                          -- ^ length+  -> m (SmallArray a)+freezeSmallArray marr s l = do+  let siz = A.sizeofSmallMutableArray marr+  check "freezeSmallArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=siz)+    (A.freezeSmallArray marr s l)++thawSmallArray+  :: PrimMonad m+  => SmallArray a -- ^ source+  -> Int     -- ^ offset+  -> Int     -- ^ length+  -> m (SmallMutableArray (PrimState m) a)+thawSmallArray arr s l = check "thawArr: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=A.sizeofSmallArray arr)+    (A.thawSmallArray arr s l)++copySmallArray :: PrimMonad m+          => SmallMutableArray (PrimState m) a    -- ^ destination array+          -> Int                             -- ^ offset into destination array+          -> SmallArray a                         -- ^ source array+          -> Int                             -- ^ offset into source array+          -> Int                             -- ^ number of elements to copy+          -> m ()+copySmallArray marr s1 arr s2 l = do+  let siz = A.sizeofSmallMutableArray marr+  check "copySmallArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=A.sizeofSmallArray arr && (s1+l)<=siz)+    (A.copySmallArray marr s1 arr s2 l)+++copySmallMutableArray :: PrimMonad m+          => SmallMutableArray (PrimState m) a    -- ^ destination array+          -> Int                             -- ^ offset into destination array+          -> SmallMutableArray (PrimState m) a    -- ^ source array+          -> Int                             -- ^ offset into source array+          -> Int                             -- ^ number of elements to copy+          -> m ()+copySmallMutableArray marr1 s1 marr2 s2 l = do+  let siz1 = A.sizeofSmallMutableArray marr1+  let siz2 = A.sizeofSmallMutableArray marr2+  check "copySmallMutableArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)+    (A.copySmallMutableArray marr1 s1 marr2 s2 l)+++cloneSmallArray :: SmallArray a -- ^ source array+           -> Int     -- ^ offset into destination array+           -> Int     -- ^ number of elements to copy+           -> SmallArray a+cloneSmallArray arr s l = check "cloneSmallArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=A.sizeofSmallArray arr)+    (A.cloneSmallArray arr s l)++cloneSmallMutableArray :: PrimMonad m+        => SmallMutableArray (PrimState m) a -- ^ source array+        -> Int                          -- ^ offset into destination array+        -> Int                          -- ^ number of elements to copy+        -> m (SmallMutableArray (PrimState m) a)+cloneSmallMutableArray marr s l = do+  let siz = A.sizeofSmallMutableArray marr+  check "cloneSmallMutableArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=siz)+    (A.cloneSmallMutableArray marr s l)
+ src/Data/Primitive/UnliftedArray.hs view
@@ -0,0 +1,131 @@+{-# LANGUAGE PackageImports #-}++module Data.Primitive.UnliftedArray+  ( UnliftedArray(..)+  , MutableUnliftedArray(..)+  , PrimUnlifted(..)+  , unsafeNewUnliftedArray+  , newUnliftedArray+  , A.setUnliftedArray+  , A.sizeofUnliftedArray+  , A.sizeofMutableUnliftedArray+  , readUnliftedArray+  , writeUnliftedArray+  , indexUnliftedArray+  , indexUnliftedArrayM+  , A.unsafeFreezeUnliftedArray+  , freezeUnliftedArray+  , thawUnliftedArray+  , A.sameMutableUnliftedArray+  , copyUnliftedArray+  , copyMutableUnliftedArray+  , cloneUnliftedArray+  , cloneMutableUnliftedArray+  ) where++import Control.Monad.Primitive (PrimMonad,PrimState)+import Control.Exception (throw, ArrayException(..))+import "primitive" Data.Primitive.UnliftedArray (UnliftedArray,MutableUnliftedArray,PrimUnlifted)+import qualified "primitive" Data.Primitive.UnliftedArray as A++check :: String -> Bool -> a -> a+check _      True  x = x+check errMsg False _ = throw (IndexOutOfBounds $ "Data.Primitive.UnliftedArray.Checked." ++ errMsg)++newUnliftedArray :: (PrimMonad m, PrimUnlifted a) => Int -> a -> m (MutableUnliftedArray (PrimState m) a)+newUnliftedArray n x = check "newUnliftedArray: negative size" (n>=0) (A.newUnliftedArray n x)++unsafeNewUnliftedArray :: PrimMonad m => Int -> m (MutableUnliftedArray (PrimState m) a)+unsafeNewUnliftedArray n = check "unsafeNewUnliftedArray: negative size" (n>=0) (A.unsafeNewUnliftedArray n)++readUnliftedArray :: (PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> m a+readUnliftedArray marr i = do+  let siz = A.sizeofMutableUnliftedArray marr+  check "readUnliftedArray: index of out bounds" (i>=0 && i<siz) (A.readUnliftedArray marr i)++writeUnliftedArray :: (PrimMonad m, PrimUnlifted a) => MutableUnliftedArray (PrimState m) a -> Int -> a -> m ()+writeUnliftedArray marr i x = do+  let siz = A.sizeofMutableUnliftedArray marr+  check "writeUnliftedArray: index of out bounds" (i>=0 && i<siz) (A.writeUnliftedArray marr i x)++indexUnliftedArray :: PrimUnlifted a => UnliftedArray a -> Int -> a+indexUnliftedArray arr i = check "indexUnliftedArray: index of out bounds"+  (i>=0 && i<A.sizeofUnliftedArray arr)+  (A.indexUnliftedArray arr i)++indexUnliftedArrayM :: (Monad m, PrimUnlifted a) => UnliftedArray a -> Int -> m a+indexUnliftedArrayM arr i = check "indexUnliftedArrayM: index of out bounds"+    (i>=0 && i<A.sizeofUnliftedArray arr)+    (A.indexUnliftedArrayM arr i)++freezeUnliftedArray+  :: PrimMonad m+  => MutableUnliftedArray (PrimState m) a -- ^ source+  -> Int -- ^ offset+  -> Int -- ^ length+  -> m (UnliftedArray a)+freezeUnliftedArray marr s l = do+  let siz = A.sizeofMutableUnliftedArray marr+  check "freezeUnliftedArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=siz)+    (A.freezeUnliftedArray marr s l)++thawUnliftedArray+  :: PrimMonad m+  => UnliftedArray a -- ^ source+  -> Int -- ^ offset+  -> Int -- ^ length+  -> m (MutableUnliftedArray (PrimState m) a)+thawUnliftedArray arr s l = check "thawArr: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=A.sizeofUnliftedArray arr)+    (A.thawUnliftedArray arr s l)++copyUnliftedArray :: PrimMonad m+  => MutableUnliftedArray (PrimState m) a -- ^ destination array+  -> Int -- ^ offset into destination array+  -> UnliftedArray a -- ^ source array+  -> Int -- ^ offset into source array+  -> Int -- ^ number of elements to copy+  -> m ()+copyUnliftedArray marr s1 arr s2 l = do+  let siz = A.sizeofMutableUnliftedArray marr+  check "copyUnliftedArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=A.sizeofUnliftedArray arr && (s1+l)<=siz)+    (A.copyUnliftedArray marr s1 arr s2 l)+++copyMutableUnliftedArray :: PrimMonad m+  => MutableUnliftedArray (PrimState m) a    -- ^ destination array+  -> Int                             -- ^ offset into destination array+  -> MutableUnliftedArray (PrimState m) a    -- ^ source array+  -> Int                             -- ^ offset into source array+  -> Int                             -- ^ number of elements to copy+  -> m ()+copyMutableUnliftedArray marr1 s1 marr2 s2 l = do+  let siz1 = A.sizeofMutableUnliftedArray marr1+  let siz2 = A.sizeofMutableUnliftedArray marr2+  check "copyMutableUnliftedArray: index range of out bounds"+    (s1>=0 && s2>=0 && l>=0 && (s2+l)<=siz2 && (s1+l)<=siz1)+    (A.copyMutableUnliftedArray marr1 s1 marr2 s2 l)+++cloneUnliftedArray ::+     UnliftedArray a -- ^ source array+  -> Int -- ^ offset into destination array+  -> Int -- ^ number of elements to copy+  -> UnliftedArray a+cloneUnliftedArray arr s l = check "cloneUnliftedArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=A.sizeofUnliftedArray arr)+    (A.cloneUnliftedArray arr s l)++cloneMutableUnliftedArray :: PrimMonad m+  => MutableUnliftedArray (PrimState m) a -- ^ source array+  -> Int -- ^ offset into destination array+  -> Int -- ^ number of elements to copy+  -> m (MutableUnliftedArray (PrimState m) a)+cloneMutableUnliftedArray marr s l = do+  let siz = A.sizeofMutableUnliftedArray marr+  check "cloneMutableUnliftedArray: index range of out bounds"+    (s>=0 && l>=0 && (s+l)<=siz)+    (A.cloneMutableUnliftedArray marr s l)+