Skip to content

Commit 1819272

Browse files
authored
Implement Contiguous and ContiguousU for SmallUnliftedArray (#64)
Implement Contiguous and ContiguousU for SmallUnliftedArray Re-export Small(Mutable)UnliftedArray from Data.Primitive.Contiguous Fix bug: creating a new SmallUnliftedArray cannot use `undefined` as default element Update to the newly-released version of primitive-unlifted that fixes SmallUnliftedArray's type argument order
1 parent 2774df7 commit 1819272

File tree

4 files changed

+166
-1
lines changed

4 files changed

+166
-1
lines changed

contiguous.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ library
3939
, base >=4.14 && <5
4040
, deepseq >=1.4
4141
, primitive >=0.9 && <0.10
42-
, primitive-unlifted >=2.1
42+
, primitive-unlifted >=2.2
4343
, run-st >=0.1.3.2
4444

4545
ghc-options: -O2

src/Data/Primitive/Contiguous.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,14 @@ module Data.Primitive.Contiguous
270270
, MutablePrimArray
271271
, UnliftedArray
272272
, MutableUnliftedArray
273+
, SmallUnliftedArray
274+
, SmallMutableUnliftedArray
273275
) where
274276

275277
import Control.Monad.Primitive
276278
import Data.Primitive
277279
import Data.Primitive.Unlifted.Array
280+
import Data.Primitive.Unlifted.SmallArray
278281
import Prelude hiding (Foldable (..), all, any, filter, map, mapM, mapM_, read, replicate, reverse, scanl, sequence, sequence_, traverse, zip, zipWith, (<$))
279282

280283
import Control.Monad (when)

src/Data/Primitive/Contiguous/Class.hs

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module Data.Primitive.Contiguous.Class
3030
import Data.Primitive
3131
import Data.Primitive.Contiguous.Shim
3232
import Data.Primitive.Unlifted.Array
33+
import Data.Primitive.Unlifted.SmallArray
3334
import Prelude hiding
3435
( all
3536
, any
@@ -64,8 +65,10 @@ import Control.Monad.ST.Run (runArrayST, runPrimArrayST, runSmallArrayST, runUnl
6465
import Data.Kind (Type)
6566
import Data.Primitive.Unlifted.Array ()
6667
import Data.Primitive.Unlifted.Array.Primops (MutableUnliftedArray# (MutableUnliftedArray#), UnliftedArray# (UnliftedArray#))
68+
import Data.Primitive.Unlifted.SmallArray.Primops (SmallUnliftedArray# (SmallUnliftedArray#), SmallMutableUnliftedArray# (SmallMutableUnliftedArray#))
6769
import Data.Primitive.Unlifted.Class (PrimUnlifted)
6870
import GHC.Exts (Array#, Constraint, MutableArray#, SmallArray#, SmallMutableArray#, TYPE, sizeofArray#, sizeofByteArray#)
71+
import GHC.ST (ST (ST))
6972

7073
import qualified Control.DeepSeq as DS
7174
import qualified Data.Primitive.Unlifted.Class as Class
@@ -885,6 +888,150 @@ instance ContiguousU SmallArray where
885888
{-# INLINE liftMut #-}
886889
liftMut x = SmallMutableArray x
887890

891+
instance Contiguous (SmallUnliftedArray_ unlifted_a) where
892+
type Mutable (SmallUnliftedArray_ unlifted_a) = SmallMutableUnliftedArray_ unlifted_a
893+
type Element (SmallUnliftedArray_ unlifted_a) = PrimUnliftsInto unlifted_a
894+
type Sliced (SmallUnliftedArray_ unlifted_a) = Slice (SmallUnliftedArray_ unlifted_a)
895+
type MutableSliced (SmallUnliftedArray_ unlifted_a) = MutableSlice (SmallUnliftedArray_ unlifted_a)
896+
{-# INLINE new #-}
897+
new n = unsafeNewSmallUnliftedArray n
898+
{-# INLINE empty #-}
899+
empty = emptySmallUnliftedArray
900+
{-# INLINE index #-}
901+
index = indexSmallUnliftedArray
902+
{-# INLINE indexM #-}
903+
indexM arr ix = pure (indexSmallUnliftedArray arr ix)
904+
{-# INLINE index# #-}
905+
index# arr ix = (# indexSmallUnliftedArray arr ix #)
906+
{-# INLINE read #-}
907+
read = readSmallUnliftedArray
908+
{-# INLINE write #-}
909+
write = writeSmallUnliftedArray
910+
{-# INLINE null #-}
911+
null a = case sizeofSmallUnliftedArray a of
912+
0 -> True
913+
_ -> False
914+
{-# INLINE slice #-}
915+
slice base offset length = Slice {offset, length, base = unlift base}
916+
{-# INLINE sliceMut #-}
917+
sliceMut baseMut offsetMut lengthMut = MutableSlice {offsetMut, lengthMut, baseMut = unliftMut baseMut}
918+
{-# INLINE toSlice #-}
919+
toSlice base = Slice {offset = 0, length = size base, base = unlift base}
920+
{-# INLINE toSliceMut #-}
921+
toSliceMut baseMut = do
922+
lengthMut <- sizeMut baseMut
923+
pure MutableSlice {offsetMut = 0, lengthMut, baseMut = unliftMut baseMut}
924+
{-# INLINE freeze_ #-}
925+
freeze_ = freezeSmallUnliftedArray
926+
{-# INLINE unsafeFreeze #-}
927+
unsafeFreeze = unsafeFreezeSmallUnliftedArray
928+
{-# INLINE size #-}
929+
size = sizeofSmallUnliftedArray
930+
{-# INLINE sizeMut #-}
931+
sizeMut = getSizeofSmallMutableUnliftedArray
932+
{-# INLINE thaw_ #-}
933+
thaw_ = thawSmallUnliftedArray
934+
{-# INLINE equals #-}
935+
equals = (==)
936+
{-# INLINE equalsMut #-}
937+
equalsMut = sameSmallMutableUnliftedArray
938+
{-# INLINE singleton #-}
939+
singleton a = runST $ do
940+
marr <- newSmallUnliftedArray 1 a
941+
unsafeFreezeSmallUnliftedArray marr
942+
{-# INLINE doubleton #-}
943+
doubleton a b = runST $ do
944+
m <- newSmallUnliftedArray 2 a
945+
writeSmallUnliftedArray m 1 b
946+
unsafeFreezeSmallUnliftedArray m
947+
{-# INLINE tripleton #-}
948+
tripleton a b c = runST $ do
949+
m <- newSmallUnliftedArray 3 a
950+
writeSmallUnliftedArray m 1 b
951+
writeSmallUnliftedArray m 2 c
952+
unsafeFreezeSmallUnliftedArray m
953+
{-# INLINE quadrupleton #-}
954+
quadrupleton a b c d = runST $ do
955+
m <- newSmallUnliftedArray 4 a
956+
writeSmallUnliftedArray m 1 b
957+
writeSmallUnliftedArray m 2 c
958+
writeSmallUnliftedArray m 3 d
959+
unsafeFreezeSmallUnliftedArray m
960+
{-# INLINE quintupleton #-}
961+
quintupleton a b c d e = runST $ do
962+
m <- newSmallUnliftedArray 5 a
963+
writeSmallUnliftedArray m 1 b
964+
writeSmallUnliftedArray m 2 c
965+
writeSmallUnliftedArray m 3 d
966+
writeSmallUnliftedArray m 4 e
967+
unsafeFreezeSmallUnliftedArray m
968+
{-# INLINE sextupleton #-}
969+
sextupleton a b c d e f = runST $ do
970+
m <- newSmallUnliftedArray 6 a
971+
writeSmallUnliftedArray m 1 b
972+
writeSmallUnliftedArray m 2 c
973+
writeSmallUnliftedArray m 3 d
974+
writeSmallUnliftedArray m 4 e
975+
writeSmallUnliftedArray m 5 f
976+
unsafeFreezeSmallUnliftedArray m
977+
{-# INLINE rnf #-}
978+
rnf !ary =
979+
let !sz = sizeofSmallUnliftedArray ary
980+
go !ix =
981+
if ix < sz
982+
then
983+
let !x = indexSmallUnliftedArray ary ix
984+
in DS.rnf x `seq` go (ix + 1)
985+
else ()
986+
in go 0
987+
{-# INLINE clone_ #-}
988+
clone_ = cloneSmallUnliftedArray
989+
{-# INLINE cloneMut_ #-}
990+
cloneMut_ = cloneSmallMutableUnliftedArray
991+
{-# INLINE copy_ #-}
992+
copy_ = copySmallUnliftedArray
993+
{-# INLINE copyMut_ #-}
994+
copyMut_ = copySmallMutableUnliftedArray
995+
{-# INLINE replicateMut #-}
996+
replicateMut = newSmallUnliftedArray
997+
{-# INLINE run #-}
998+
run = runSmallUnliftedArrayST
999+
{-# INLINE shrink #-}
1000+
shrink !arr !n = do
1001+
shrinkSmallMutableUnliftedArray arr n
1002+
pure arr
1003+
{-# INLINE unsafeShrinkAndFreeze #-}
1004+
unsafeShrinkAndFreeze !arr !n = do
1005+
shrinkSmallMutableUnliftedArray arr n
1006+
unsafeFreezeSmallUnliftedArray arr
1007+
1008+
1009+
newtype SmallUnliftedArray## (u :: TYPE UnliftedRep) (a :: Type)
1010+
= SmallUnliftedArray## (Exts.SmallArray# u)
1011+
newtype SmallMutableUnliftedArray## (u :: TYPE UnliftedRep) s (a :: Type)
1012+
= SmallMutableUnliftedArray## (Exts.SmallMutableArray# s u)
1013+
1014+
instance ContiguousU (SmallUnliftedArray_ unlifted_a) where
1015+
type Unlifted (SmallUnliftedArray_ unlifted_a) = SmallUnliftedArray## unlifted_a
1016+
type UnliftedMut (SmallUnliftedArray_ unlifted_a) = SmallMutableUnliftedArray## unlifted_a
1017+
{-# INLINE resize #-}
1018+
resize = resizeSmallUnliftedArray
1019+
{-# INLINE unlift #-}
1020+
unlift (SmallUnliftedArray (SmallUnliftedArray# x)) = SmallUnliftedArray## x
1021+
{-# INLINE unliftMut #-}
1022+
unliftMut (SmallMutableUnliftedArray (SmallMutableUnliftedArray# x)) = SmallMutableUnliftedArray## x
1023+
{-# INLINE lift #-}
1024+
lift (SmallUnliftedArray## x) = SmallUnliftedArray (SmallUnliftedArray# x)
1025+
{-# INLINE liftMut #-}
1026+
liftMut (SmallMutableUnliftedArray## x) = SmallMutableUnliftedArray (SmallMutableUnliftedArray# x)
1027+
1028+
1029+
-- NOTE: Currently missing from the `run-st` library
1030+
-- c.f. https://github.com/byteverse/run-st/issues/5
1031+
runSmallUnliftedArrayST :: (forall s. ST s (SmallUnliftedArray_ unlifted_a a)) -> SmallUnliftedArray_ unlifted_a a
1032+
{-# INLINE runSmallUnliftedArrayST #-}
1033+
runSmallUnliftedArrayST f = SmallUnliftedArray (Exts.runRW# (\s0 -> case f of ST g -> case g s0 of (# _, SmallUnliftedArray r #) -> r))
1034+
8881035
instance Contiguous PrimArray where
8891036
type Mutable PrimArray = MutablePrimArray
8901037
type Element PrimArray = Prim

src/Data/Primitive/Contiguous/Shim.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ module Data.Primitive.Contiguous.Shim
55
( errorThunk
66
, resizeArray
77
, resizeUnliftedArray
8+
, resizeSmallUnliftedArray
89
, replicateMutablePrimArray
910
) where
1011

1112
import Data.Primitive
1213
import Data.Primitive.Unlifted.Array
14+
import Data.Primitive.Unlifted.SmallArray
1315
import Prelude hiding (all, any, elem, filter, foldMap, foldl, foldr, map, mapM, mapM_, maximum, minimum, null, read, replicate, reverse, scanl, sequence, sequence_, traverse, zip, zipWith, (<$))
1416

1517
import Control.Monad.Primitive (PrimMonad (..), PrimState)
@@ -43,6 +45,19 @@ resizeUnliftedArray !src !sz = do
4345
pure dst
4446
{-# INLINE resizeUnliftedArray #-}
4547

48+
resizeSmallUnliftedArray :: (PrimMonad m, PrimUnlifted a) => SmallMutableUnliftedArray (PrimState m) a -> Int -> m (SmallMutableUnliftedArray (PrimState m) a)
49+
resizeSmallUnliftedArray !src !sz = do
50+
srcSz <- getSizeofSmallMutableUnliftedArray src
51+
case compare sz srcSz of
52+
EQ -> pure src
53+
LT -> cloneSmallMutableUnliftedArray src 0 sz
54+
GT -> do
55+
dst <- unsafeNewSmallUnliftedArray sz
56+
copySmallMutableUnliftedArray dst 0 src 0 srcSz
57+
pure dst
58+
{-# INLINE resizeSmallUnliftedArray #-}
59+
60+
4661
replicateMutablePrimArray ::
4762
(PrimMonad m, Prim a) =>
4863
-- | length

0 commit comments

Comments
 (0)