impure-containers 0.5.0 → 0.5.1
raw patch · 6 files changed
+169/−21 lines, 6 filesdep ~hashabledep ~primitivePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: hashable, primitive
API changes (from Hackage documentation)
- Data.ArrayList.Generic: ArrayList :: !(MutVar s Int) -> !(MutVar s (v s a)) -> ArrayList v s a
- Data.ArrayList.Generic: [arrayListSize] :: ArrayList v s a -> !(MutVar s Int)
- Data.ArrayList.Generic: [arrayListVector] :: ArrayList v s a -> !(MutVar s (v s a))
- Data.Graph.Immutable: instance GHC.Classes.Ord a => Data.Semigroup.Semigroup (Data.Graph.Immutable.MinDistance a)
- Data.Graph.Types.Internal: instance (GHC.Classes.Eq e, GHC.Classes.Eq v) => GHC.Classes.Eq (Data.Graph.Types.Internal.SomeGraph e v)
- Data.Graph.Types.Internal: instance (GHC.Classes.Ord e, GHC.Classes.Ord v) => GHC.Classes.Ord (Data.Graph.Types.Internal.SomeGraph e v)
- Data.HashMap.Mutable.Basic: instance Data.Semigroup.Semigroup Data.HashMap.Mutable.Basic.Slot
+ Data.ArrayList.Generic: fromVector :: (PrimMonad m, Vector v a) => v a -> m (ArrayList (Mutable v) (PrimState m) a)
+ Data.ArrayList.Generic: grow :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> Int -> m ()
+ Data.ArrayList.Generic: size :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> m Int
+ Data.ArrayList.Generic: unsafeVector :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> m (v (PrimState m) a)
+ Data.ArrayList.Generic: vector :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> m (v (PrimState m) a)
+ Data.Graph.Immutable: instance GHC.Classes.Ord a => GHC.Base.Semigroup (Data.Graph.Immutable.MinDistance a)
+ Data.Graph.Types.Internal: instance (GHC.Classes.Eq v, GHC.Classes.Eq e) => GHC.Classes.Eq (Data.Graph.Types.Internal.SomeGraph e v)
+ Data.Graph.Types.Internal: instance (GHC.Classes.Ord v, GHC.Classes.Ord e) => GHC.Classes.Ord (Data.Graph.Types.Internal.SomeGraph e v)
+ Data.HashMap.Mutable.Basic: instance GHC.Base.Semigroup Data.HashMap.Mutable.Basic.Slot
- Data.Graph.Types.Internal: MGraph :: !(MHashMap s v Int) -> !(MutVar s Int) -> !(MHashMap s IntPair e) -> MGraph s g e v
+ Data.Graph.Types.Internal: MGraph :: !MHashMap s v Int -> !MutVar s Int -> !MHashMap s IntPair e -> MGraph s g e v
- Data.Graph.Types.Internal: SomeGraph :: !(Vector v) -> !(Vector (Vector Int)) -> !(Vector (Vector e)) -> SomeGraph e v
+ Data.Graph.Types.Internal: SomeGraph :: !Vector v -> !Vector (Vector Int) -> !Vector (Vector e) -> SomeGraph e v
- Data.Graph.Types.Internal: [graphOutboundNeighborEdges] :: SomeGraph e v -> !(Vector (Vector e))
+ Data.Graph.Types.Internal: [graphOutboundNeighborEdges] :: SomeGraph e v -> !Vector (Vector e)
- Data.Graph.Types.Internal: [graphOutboundNeighborVertices] :: SomeGraph e v -> !(Vector (Vector Int))
+ Data.Graph.Types.Internal: [graphOutboundNeighborVertices] :: SomeGraph e v -> !Vector (Vector Int)
- Data.Graph.Types.Internal: [graphVertices] :: SomeGraph e v -> !(Vector v)
+ Data.Graph.Types.Internal: [graphVertices] :: SomeGraph e v -> !Vector v
- Data.Graph.Types.Internal: [mgraphCurrentId] :: MGraph s g e v -> !(MutVar s Int)
+ Data.Graph.Types.Internal: [mgraphCurrentId] :: MGraph s g e v -> !MutVar s Int
- Data.Graph.Types.Internal: [mgraphEdges] :: MGraph s g e v -> !(MHashMap s IntPair e)
+ Data.Graph.Types.Internal: [mgraphEdges] :: MGraph s g e v -> !MHashMap s IntPair e
- Data.Graph.Types.Internal: [mgraphVertexIndex] :: MGraph s g e v -> !(MHashMap s v Int)
+ Data.Graph.Types.Internal: [mgraphVertexIndex] :: MGraph s g e v -> !MHashMap s v Int
- Data.HashMap.Mutable.Basic: delete :: (PrimMonad m, Hashable k, Eq k) => (MHashMap (PrimState m) k v) -> k -> m ()
+ Data.HashMap.Mutable.Basic: delete :: (PrimMonad m, Hashable k, Eq k) => MHashMap (PrimState m) k v -> k -> m ()
- Data.HashMap.Mutable.Basic: insert :: (PrimMonad m, Eq k, Hashable k) => (MHashMap (PrimState m) k v) -> k -> v -> m ()
+ Data.HashMap.Mutable.Basic: insert :: (PrimMonad m, Eq k, Hashable k) => MHashMap (PrimState m) k v -> k -> v -> m ()
- Data.HashMap.Mutable.Basic: lookup :: (PrimMonad m, Eq k, Hashable k) => (MHashMap (PrimState m) k v) -> k -> m (Maybe v)
+ Data.HashMap.Mutable.Basic: lookup :: (PrimMonad m, Eq k, Hashable k) => MHashMap (PrimState m) k v -> k -> m (Maybe v)
- Data.Heap.Mutable.ModelC: RawHeap :: !Int -> !(MutableArray s p) -> !(MutableByteArray s) -> !(MutableByteArray s) -> RawHeap s p
+ Data.Heap.Mutable.ModelC: RawHeap :: !Int -> !MutableArray s p -> !MutableByteArray s -> !MutableByteArray s -> RawHeap s p
- Data.Heap.Mutable.ModelC: [rawHeapElements] :: RawHeap s p -> !(MutableByteArray s)
+ Data.Heap.Mutable.ModelC: [rawHeapElements] :: RawHeap s p -> !MutableByteArray s
- Data.Heap.Mutable.ModelC: [rawHeapInvertedIndex] :: RawHeap s p -> !(MutableByteArray s)
+ Data.Heap.Mutable.ModelC: [rawHeapInvertedIndex] :: RawHeap s p -> !MutableByteArray s
- Data.Heap.Mutable.ModelC: [rawHeapPriorities] :: RawHeap s p -> !(MutableArray s p)
+ Data.Heap.Mutable.ModelC: [rawHeapPriorities] :: RawHeap s p -> !MutableArray s p
- Data.Heap.Mutable.ModelD: Heap :: !(RawHeap s p) -> !(MutVar s Int) -> Heap s p
+ Data.Heap.Mutable.ModelD: Heap :: !RawHeap s p -> !MutVar s Int -> Heap s p
- Data.Heap.Mutable.ModelD: [heapCurrentSize] :: Heap s p -> !(MutVar s Int)
+ Data.Heap.Mutable.ModelD: [heapCurrentSize] :: Heap s p -> !MutVar s Int
- Data.Heap.Mutable.ModelD: [heapRaw] :: Heap s p -> !(RawHeap s p)
+ Data.Heap.Mutable.ModelD: [heapRaw] :: Heap s p -> !RawHeap s p
- Data.Primitive.PrimArray: MutablePrimArray :: (MutableByteArray s) -> MutablePrimArray s a
+ Data.Primitive.PrimArray: MutablePrimArray :: MutableByteArray s -> MutablePrimArray s a
- Data.Trie.Immutable.Bits: Trie :: !(UnsafeMaybe v) -> !(UnsafeMaybe (Trie k v)) -> !(UnsafeMaybe (Trie k v)) -> Trie k v
+ Data.Trie.Immutable.Bits: Trie :: !UnsafeMaybe v -> !UnsafeMaybe (Trie k v) -> !UnsafeMaybe (Trie k v) -> Trie k v
- Data.Trie.Immutable.Bits: [trieLeft] :: Trie k v -> !(UnsafeMaybe (Trie k v))
+ Data.Trie.Immutable.Bits: [trieLeft] :: Trie k v -> !UnsafeMaybe (Trie k v)
- Data.Trie.Immutable.Bits: [trieRight] :: Trie k v -> !(UnsafeMaybe (Trie k v))
+ Data.Trie.Immutable.Bits: [trieRight] :: Trie k v -> !UnsafeMaybe (Trie k v)
- Data.Trie.Immutable.Bits: [trieValue] :: Trie k v -> !(UnsafeMaybe v)
+ Data.Trie.Immutable.Bits: [trieValue] :: Trie k v -> !UnsafeMaybe v
- Data.Trie.Mutable.Bits: MTrie :: !(MutMaybeVar s v) -> !(MutMaybeVar s (MTrie s k v)) -> !(MutMaybeVar s (MTrie s k v)) -> MTrie s k v
+ Data.Trie.Mutable.Bits: MTrie :: !MutMaybeVar s v -> !MutMaybeVar s (MTrie s k v) -> !MutMaybeVar s (MTrie s k v) -> MTrie s k v
- Data.Trie.Mutable.Bits: [mtrieLeft] :: MTrie s k v -> !(MutMaybeVar s (MTrie s k v))
+ Data.Trie.Mutable.Bits: [mtrieLeft] :: MTrie s k v -> !MutMaybeVar s (MTrie s k v)
- Data.Trie.Mutable.Bits: [mtrieRight] :: MTrie s k v -> !(MutMaybeVar s (MTrie s k v))
+ Data.Trie.Mutable.Bits: [mtrieRight] :: MTrie s k v -> !MutMaybeVar s (MTrie s k v)
- Data.Trie.Mutable.Bits: [mtrieValue] :: MTrie s k v -> !(MutMaybeVar s v)
+ Data.Trie.Mutable.Bits: [mtrieValue] :: MTrie s k v -> !MutMaybeVar s v
- ImpureContainers.MByteArray: contents :: MByteArray s -> Addr
+ ImpureContainers.MByteArray: contents :: MByteArray s -> Ptr Word8
- ImpureContainers.MByteArray: copyFromIByteArray :: (PrimMonad m) => MByteArray (PrimState m) -> Int -> IByteArray -> Int -> Int -> m ()
+ ImpureContainers.MByteArray: copyFromIByteArray :: PrimMonad m => MByteArray (PrimState m) -> Int -> IByteArray -> Int -> Int -> m ()
- ImpureContainers.MByteArray: copyFromMByteArray :: (PrimMonad m) => MByteArray (PrimState m) -> Int -> MByteArray (PrimState m) -> Int -> Int -> m ()
+ ImpureContainers.MByteArray: copyFromMByteArray :: PrimMonad m => MByteArray (PrimState m) -> Int -> MByteArray (PrimState m) -> Int -> Int -> m ()
- ImpureContainers.MByteArray: fill :: (PrimMonad m) => MByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
+ ImpureContainers.MByteArray: fill :: PrimMonad m => MByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
- ImpureContainers.MByteArray: move :: (PrimMonad m) => MByteArray (PrimState m) -> Int -> MByteArray (PrimState m) -> Int -> Int -> m ()
+ ImpureContainers.MByteArray: move :: PrimMonad m => MByteArray (PrimState m) -> Int -> MByteArray (PrimState m) -> Int -> Int -> m ()
- ImpureContainers.MByteArray: new :: (PrimMonad m) => Int -> m (MByteArray (PrimState m))
+ ImpureContainers.MByteArray: new :: PrimMonad m => Int -> m (MByteArray (PrimState m))
- ImpureContainers.MByteArray: newAlignedPinned :: (PrimMonad m) => Int -> Int -> m (MByteArray (PrimState m))
+ ImpureContainers.MByteArray: newAlignedPinned :: PrimMonad m => Int -> Int -> m (MByteArray (PrimState m))
- ImpureContainers.MByteArray: newPinned :: (PrimMonad m) => Int -> m (MByteArray (PrimState m))
+ ImpureContainers.MByteArray: newPinned :: PrimMonad m => Int -> m (MByteArray (PrimState m))
- ImpureContainers.MByteArray: unsafeFreeze :: (PrimMonad m) => MByteArray (PrimState m) -> m IByteArray
+ ImpureContainers.MByteArray: unsafeFreeze :: PrimMonad m => MByteArray (PrimState m) -> m IByteArray
- ImpureContainers.MByteArray: unsafeThaw :: (PrimMonad m) => IByteArray -> m (MByteArray (PrimState m))
+ ImpureContainers.MByteArray: unsafeThaw :: PrimMonad m => IByteArray -> m (MByteArray (PrimState m))
- ImpureContainers.PrimRef: atomicReadInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> m Int
+ ImpureContainers.PrimRef: atomicReadInt :: PrimMonad m => PrimRef (PrimState m) Int -> m Int
- ImpureContainers.PrimRef: atomicWriteInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> m ()
+ ImpureContainers.PrimRef: atomicWriteInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> m ()
- ImpureContainers.PrimRef: casInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> Int -> m Int
+ ImpureContainers.PrimRef: casInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> Int -> m Int
- ImpureContainers.PrimRef: contents :: PrimRef s a -> Addr
+ ImpureContainers.PrimRef: contents :: PrimRef s a -> Ptr Word8
- ImpureContainers.PrimRef: fetchAddInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> m Int
+ ImpureContainers.PrimRef: fetchAddInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> m Int
- ImpureContainers.PrimRef: fetchAndInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> m Int
+ ImpureContainers.PrimRef: fetchAndInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> m Int
- ImpureContainers.PrimRef: fetchNandInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> m Int
+ ImpureContainers.PrimRef: fetchNandInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> m Int
- ImpureContainers.PrimRef: fetchOrInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> m Int
+ ImpureContainers.PrimRef: fetchOrInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> m Int
- ImpureContainers.PrimRef: fetchSubInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> m Int
+ ImpureContainers.PrimRef: fetchSubInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> m Int
- ImpureContainers.PrimRef: fetchXorInt :: (PrimMonad m) => PrimRef (PrimState m) Int -> Int -> m Int
+ ImpureContainers.PrimRef: fetchXorInt :: PrimMonad m => PrimRef (PrimState m) Int -> Int -> m Int
Files
- impure-containers.cabal +4/−4
- src/Data/ArrayList/Generic.hs +136/−15
- src/Data/HashMap/Mutable/Internal/IntArray.hs +7/−1
- src/ImpureContainers/MByteArray.hs +9/−0
- src/ImpureContainers/PrimRef.hs +10/−0
- test/Spec.hs +3/−1
impure-containers.cabal view
@@ -1,7 +1,7 @@ -------------------------------------------------------------------------------- name: impure-containers-version: 0.5.0+version: 0.5.1 stability: Experimental build-type: Simple cabal-version: >= 1.10@@ -88,10 +88,10 @@ , Data.HashMap.Mutable.Internal.UnsafeTricks , Data.HashMap.Mutable.Internal.Utils build-depends: base >= 4.8 && < 5- , hashable >= 1.2 && < 1.3- , primitive >= 0.6 && < 0.7+ , hashable >= 1.2 && < 1.4+ , primitive >= 0.6 && < 0.8 , vector >= 0.11 && < 0.13- , containers > 0.5 && < 0.6+ , containers > 0.5 && < 0.7 , ghc-prim default-language: Haskell2010
src/Data/ArrayList/Generic.hs view
@@ -1,41 +1,162 @@-{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE FlexibleContexts #-} -module Data.ArrayList.Generic where+{- | +Auto-growing 'ArrayList' type that over-allocates memory to optimize frequent resizes.++This is similar to @std::vector@ from C++ or @list@ from Python.++When an @ArrayList@ is requested to grow and current allocated capacity can't hold the+required number of items, capacity is multiplied by a constant factor of @1.5@, instead+of allocating just the required number of items. This ensures that frequent grow requests+will result in a much lower number of actual allocations and memory moves.++All functions in this module are marked @INLINEABLE@, so that they may be specialized to concrete+monad and vector types at the use-site.+-}+module Data.ArrayList.Generic+ (+ -- * Creation of @ArrayList@s+ ArrayList+ , new, fromVector++ -- * Accessing the underlying vector+ , vector, size+ , unsafeVector++ -- * Extending the @ArrayList@+ , push, grow++ -- * Deconstruction of @ArrayList@s+ , freeze+ ) where++import Control.Monad (when) import Control.Monad.Primitive+import Control.Monad.ST (ST) import Data.Primitive.MutVar import Data.Vector.Generic (Mutable, Vector) import qualified Data.Vector.Generic as GV import Data.Vector.Generic.Mutable (MVector) import qualified Data.Vector.Generic.Mutable as GM+import qualified Data.Vector.Mutable as VM+import qualified Data.Vector.Unboxed.Mutable as VUM+import GHC.Prim (RealWorld) data ArrayList v s a = ArrayList { arrayListSize :: !(MutVar s Int) , arrayListVector :: !(MutVar s (v s a)) } +-- | Create a new 'ArrayList' with requested capacity. The length of 'ArrayList' as reported by+-- 'size' will be @0@. new :: (PrimMonad m, MVector v a) => Int -> m (ArrayList v (PrimState m) a) new len = ArrayList <$> newMutVar 0 <*> (newMutVar =<< GM.new len)+{-# INLINEABLE new #-} +-- | Create a new 'ArrayList' from immutable vector. Capacity will be equal to the length of vector.+-- Memory will be copied, so that input vector is safe to use afterwards.+fromVector :: (PrimMonad m, Vector v a) => v a -> m (ArrayList (Mutable v) (PrimState m) a)+fromVector vec = ArrayList <$> newMutVar (GV.length vec) <*> (newMutVar =<< GV.thaw vec)+{-# INLINEABLE fromVector #-}++-- | Get underlying mutable vector that stores @ArrayList@'s data. Length of this vector will be set+-- to the actually used length of @ArrayList@, not its capacity.+vector :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> m (v (PrimState m) a)+vector (ArrayList sizeRef mvecRef) = do+ !size_ <- readMutVar sizeRef+ GM.unsafeTake size_ <$> readMutVar mvecRef+{-# INLINEABLE vector #-}++-- | Like 'vector', but do not set the length of resulting vector. Its length will be equal to the+-- capacity of 'ArrayList'. This means that some elements of the vector will be uninitialized.+unsafeVector :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> m (v (PrimState m) a)+unsafeVector (ArrayList _ mvecRef) = readMutVar mvecRef+{-# INLINEABLE unsafeVector #-}++-- | Get currently used size of the 'ArrayList'.+size :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> m Int+size (ArrayList sizeRef _) = readMutVar sizeRef+{-# INLINEABLE size #-}+ -- | Append an element to the end of the 'ArrayList'. push :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> a -> m ()-push (ArrayList sizeRef mvecRef) a = do- !size <- readMutVar sizeRef+push al@(ArrayList sizeRef mvecRef) a = do+ grow al 1++ !size_ <- readMutVar sizeRef !mvec <- readMutVar mvecRef- let !newSize = size + 1- vlen = GM.length mvec++ GM.unsafeWrite mvec (size_ - 1) a+{-# INLINEABLE push #-}+{-# SPECIALIZE push :: ArrayList VM.MVector RealWorld a -> a -> IO () #-}+{-# SPECIALIZE push :: ArrayList VM.MVector s a -> a -> ST s () #-}+{-# SPECIALIZE push :: (GM.MVector VUM.MVector a) => ArrayList VUM.MVector RealWorld a -> a -> IO () #-}+{-# SPECIALIZE push :: (GM.MVector VUM.MVector a) => ArrayList VUM.MVector s a -> a -> ST s () #-}+{-# SPECIALIZE push :: (MVector v a) => ArrayList v RealWorld a -> a -> IO () #-}+{-# SPECIALIZE push :: (MVector v a) => ArrayList v s a -> a -> ST s () #-}++-- | Request to add more items to the vector. Used size will be set to current size + extra requested size.+--+-- __NOTE__: Do not use the result of 'vector' after calling this function, as it may refer to discarded+-- memory.+--+-- This function defines two Cost Centres: "@ArrayList.grow.toNewSize@" when vector will grow to fit+-- precisely the number of required elements, and "@ArrayList.grow.toNewCapacity@" when vector will+-- over-allocate memory.+--+-- These may be useful when profiling your program to check how much allocations and moves 'ArrayList'+-- does actually save.+--+-- This function is specialized to 'IO' and 'ST' monads, as well to simple 'VM.MVector' and unboxed+-- 'VUM.MVector' types.+grow :: (PrimMonad m, MVector v a) => ArrayList v (PrimState m) a -> Int -> m ()+grow (ArrayList sizeRef mvecRef) extraSize = do+ !size_ <- readMutVar sizeRef+ !mvec <- readMutVar mvecRef++ let+ capacity = GM.length mvec+ newSize = size_ + extraSize+ -- Next step in exponential grow+ newCapacity = floor $ fromIntegral capacity * factor++ -- Need to grow the vector only if the current capacity can't hold the requested size+ when (capacity < newSize) $ do+ -- Grow vector to be max (capacity * factor) (curSize + extraSize)+ -- unsafeGrow will reallocate the vector and return newly created one.+ --+ -- NOTE: unsafeGrow accepts extra size requested, not total new size.+ !mvec' <- if newSize > newCapacity+ then+ {-# SCC "ArrayList.grow.toNewSize" #-} GM.unsafeGrow mvec (newSize - capacity)+ else+ {-# SCC "ArrayList.grow.toNewCapacity" #-} GM.unsafeGrow mvec (newCapacity - capacity)++ -- Ensure that the memory requested by user is initialized.+ --GM.basicInitialize $ GM.unsafeSlice size_ extraSize mvec'++ writeMutVar mvecRef mvec'++ -- In any case, remeber current used size. writeMutVar sizeRef newSize- if size < vlen- then GM.unsafeWrite mvec size a- else do- newMVec <- GM.unsafeGrow mvec size- GM.unsafeWrite newMVec size a- writeMutVar mvecRef newMVec+{-# INLINEABLE grow #-}+{-# SPECIALIZE grow :: ArrayList VM.MVector RealWorld a -> Int -> IO () #-}+{-# SPECIALIZE grow :: ArrayList VM.MVector s a -> Int -> ST s () #-}+{-# SPECIALIZE grow :: (GM.MVector VUM.MVector a) => ArrayList VUM.MVector RealWorld a -> Int -> IO () #-}+{-# SPECIALIZE grow :: (GM.MVector VUM.MVector a) => ArrayList VUM.MVector s a -> Int -> ST s () #-}+{-# SPECIALIZE grow :: (MVector v a) => ArrayList v RealWorld a -> Int -> IO () #-}+{-# SPECIALIZE grow :: (MVector v a) => ArrayList v s a -> Int -> ST s () #-} +factor :: Double+factor = 1.5++-- | Make a copy of currently used part of 'ArrayList' and return it as an immutable vector. freeze :: (PrimMonad m, Vector v a) => ArrayList (Mutable v) (PrimState m) a -> m (v a) freeze (ArrayList sizeRef mvecRef) = do- !size <- readMutVar sizeRef+ !size_ <- readMutVar sizeRef !mvec <- readMutVar mvecRef- let sizedMVec = GM.unsafeTake size mvec+ let sizedMVec = GM.unsafeTake size_ mvec GV.freeze sizedMVec-+{-# INLINEABLE freeze #-}
src/Data/HashMap/Mutable/Internal/IntArray.hs view
@@ -20,8 +20,10 @@ import Control.Monad.Primitive (PrimMonad, PrimState) import Control.Monad.ST import Data.Bits-import qualified Data.Primitive.ByteArray as A+#if !MIN_VERSION_primitive(0, 7, 0) import Data.Primitive.Types (Addr (..))+#endif+import qualified Data.Primitive.ByteArray as A import GHC.Exts import GHC.Word import Prelude hiding (length)@@ -113,4 +115,8 @@ toPtr :: IntArray s -> Ptr a toPtr (IA a) = Ptr a# where+#if MIN_VERSION_primitive(0,7,0)+ !(Ptr !a#) = A.mutableByteArrayContents a+#else !(Addr !a#) = A.mutableByteArrayContents a+#endif
src/ImpureContainers/MByteArray.hs view
@@ -1,5 +1,6 @@ -------------------------------------------------------------------------------- +{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} --------------------------------------------------------------------------------@@ -42,7 +43,11 @@ import Control.Monad.Primitive import Data.Coerce (coerce)+#if MIN_VERSION_primitive(0, 7, 0)+import Data.Primitive (Prim, Ptr)+#else import Data.Primitive (Addr, Prim)+#endif import qualified Data.Primitive import qualified GHC.Prim@@ -108,7 +113,11 @@ contents :: MByteArray s -- ^ FIXME: doc+#if MIN_VERSION_primitive(0, 7, 0)+ -> Ptr Word8+#else -> Addr+#endif -- ^ FIXME: doc contents = Data.Primitive.mutableByteArrayContents {-# INLINE contents #-}
src/ImpureContainers/PrimRef.hs view
@@ -31,6 +31,7 @@ -------------------------------------------------------------------------------- +{-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE RoleAnnotations #-} {-# LANGUAGE UnboxedTuples #-}@@ -84,7 +85,12 @@ import Control.Monad.Primitive (PrimMonad, PrimState, primitive, primitive_) +#if MIN_VERSION_primitive(0, 7, 0)+import Data.Primitive (Prim, Ptr, alignment, sizeOf)+import Data.Word (Word8)+#else import Data.Primitive (Addr, Prim, alignment, sizeOf)+#endif import qualified GHC.Prim as GHC.Prim import GHC.Types (Int (I#))@@ -180,7 +186,11 @@ contents :: PrimRef s a -- ^ FIXME: doc+#if MIN_VERSION_primitive(0, 7, 0)+ -> Ptr Word8+#else -> Addr+#endif -- ^ FIXME: doc contents (MkPrimRef m) = MByteArray.contents m {-# INLINE contents #-}
test/Spec.hs view
@@ -24,6 +24,7 @@ import Data.List (groupBy) import qualified Data.List as List import qualified Data.Map.Strict as Map+import Data.Semigroup (Semigroup) import qualified Data.Set as Set import Data.Word import Debug.Trace@@ -79,9 +80,10 @@ arbitrary = fmap Min (choose (0,20)) shrink (Min a) = fmap Min $ filter (>= 0) $ shrinkIntegral a +instance Semigroup Min where+ (Min a) <> (Min b) = Min (min a b) instance Monoid Min where mempty = Min maxBound- mappend (Min a) (Min b) = Min (min a b) newtype MyElement = MyElement { getMyElement :: Int } deriving (Show,Read,Eq,Ord)