on master help sign in
Use CPP macros for manipulating array pointers
commitce93caa9db2f9a5e316f7f9cafa08e9ebc5a516b authorHarendra Kumar <harendra@composewell.com> dateThu 6 Jan 2022, 18:30 (5 years ago) parent6238f5d
11 files changed+172−176
.hlint.yaml+7−1 src/Streamly/Internal/Data/Array/ArrayMacros.h+27 src/Streamly/Internal/Data/Array/Foreign.hs+11−14 src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+74−107 src/Streamly/Internal/Data/Array/Foreign/Type.hs+14−18 src/Streamly/Internal/Data/Array/Stream/Fold/Foreign.hs+8−7 src/Streamly/Internal/Data/Array/Stream/Foreign.hs+7−11 src/Streamly/Internal/Data/Array/Stream/Mut/Foreign.hs+4−3 src/Streamly/Internal/Data/Ring/Foreign.hs+9−9 src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+5−5 streamly.cabal+6−1
.hlint.yaml+7−1
@@ -36,7 +36,13 @@
3636
3737# Specify additional command line arguments
3838#
39−- arguments: [--cpp-include=src, --cpp-include=test, --cpp-define=CABAL_OS_LINUX]
39+- arguments:
40+ [ --cpp-include=src
41+ , --cpp-include=src/Streamly/Internal/Data/Stream
42+ , --cpp-include=src/Streamly/Internal/Data/Array
43+ , --cpp-include=test
44+ , --cpp-define=CABAL_OS_LINUX
45+ ]
4046
4147
4248# Control which extensions/flags/modules/functions can be used
src/Streamly/Internal/Data/Array/ArrayMacros.hnew file+27
@@ -0,0 +1,27 @@
1+-------------------------------------------------------------------------------
2+-- Macros to access array pointers
3+-------------------------------------------------------------------------------
4+
5+-- The Storable instance of () has size 0. We ensure that the size is non-zero
6+-- to avoid a zero sized element and issues due to that.
7+-- See https://mail.haskell.org/pipermail/libraries/2022-January/thread.html
8+--
9+-- XXX Check the core to see if max can be statically eliminated. llvm can
10+-- eliminate the comparison, but not sure if GHC NCG can.
11+#define SIZE_OF(a) max 1 (sizeOf (undefined :: a))
12+
13+-- Move the pointer to ith element of specified type. Type is specified as the
14+-- type variable in the signature of the function where this macro is used.
15+#define PTR_NEXT(ptr,a) ptr `plusPtr` SIZE_OF(a)
16+#define PTR_PREV(ptr,a) ptr `plusPtr` negate (SIZE_OF(a))
17+
18+#define PTR_INDEX(ptr,i,a) ptr `plusPtr` (SIZE_OF(a) * i)
19+#define PTR_RINDEX(ptr,i,a) ptr `plusPtr` negate (SIZE_OF(a) * (i + 1))
20+
21+-- XXX If we know that the array is guaranteed to have size multiples of the
22+-- element size then we can use a simpler check saying "ptr < end". Since we
23+-- always allocate in multiples of elem we can use the simpler check and assert
24+-- the rigorous check.
25+#define PTR_VALID(ptr,end,a) ptr `plusPtr` SIZE_OF(a) <= end
26+#define PTR_INVALID(ptr,end,a) ptr `plusPtr` SIZE_OF(a) > end
27+
src/Streamly/Internal/Data/Array/Foreign.hs+11−14
@@ -1,5 +1,3 @@
1−#include "inline.hs"
2−
31-- |
42-- Module : Streamly.Internal.Data.Array.Foreign
53-- Copyright : (c) 2019 Composewell Technologies
@@ -115,6 +113,9 @@ module Streamly.Internal.Data.Array.Foreign
115113 )
116114where
117115
116+#include "inline.hs"
117+#include "ArrayMacros.h"
118+
118119import Control.Exception (assert)
119120import Control.Monad (when)
120121import Control.Monad.IO.Class (MonadIO(..))
@@ -130,8 +131,7 @@ import Prelude hiding (length, null, last, map, (!!), read, concat)
130131
131132import GHC.Ptr (Ptr(..))
132133
133−import Streamly.Internal.Data.Array.Foreign.Mut.Type
134− (ReadUState(..), sizeOfElem, touch)
134+import Streamly.Internal.Data.Array.Foreign.Mut.Type (ReadUState(..), touch)
135135import Streamly.Internal.Data.Array.Foreign.Type (Array(..), length)
136136import Streamly.Internal.Data.Fold.Type (Fold(..))
137137import Streamly.Internal.Data.Producer.Type (Producer(..))
@@ -205,8 +205,7 @@ producer = Producer step inject extract
205205 -- This should be safe as the array contents are guaranteed to be
206206 -- evaluated/written to before we peek at them.
207207 let !x = unsafeInlineIO $ peek cur
208− cur1 = cur `plusPtr` sizeOfElem (undefined :: a)
209− return $ D.Yield x (ReadUState contents end cur1)
208+ return $ D.Yield x (ReadUState contents end (PTR_NEXT(cur,a)))
210209
211210 extract (ReadUState contents end cur) = return $ Array contents cur end
212211
@@ -250,7 +249,7 @@ unsafeRead = Unfold step inject
250249 r <- peek p
251250 touch contents
252251 return r
253− let !p1 = p `plusPtr` sizeOfElem (undefined :: a)
252+ let !p1 = PTR_NEXT(p,a)
254253 return $ D.Yield x (ReadUState contents end p1)
255254
256255-- |
@@ -272,8 +271,7 @@ getIndexRev arr i =
272271 unsafeInlineIO
273272 $ MA.unsafeWithArrayContents (arrContents arr) (arrStart arr)
274273 $ \ptr -> do
275− let elemSize = sizeOfElem (undefined :: a)
276− elemPtr = aEnd arr `plusPtr` negate (elemSize * (i + 1))
274+ let elemPtr = PTR_RINDEX(aEnd arr,i,a)
277275 if i >= 0 && elemPtr >= ptr
278276 then Just <$> peek elemPtr
279277 else return Nothing
@@ -383,7 +381,7 @@ getSliceUnsafe ::
383381 -> Array a
384382 -> Array a
385383getSliceUnsafe index len (Array contents start e) =
386− let size = sizeOfElem (undefined :: a)
384+ let size = SIZE_OF(a)
387385 fp1 = start `plusPtr` (index * size)
388386 end = fp1 `plusPtr` (len * size)
389387 in assert (end <= e) (Array contents fp1 end)
@@ -438,9 +436,8 @@ getIndex arr i =
438436 unsafeInlineIO
439437 $ MA.unsafeWithArrayContents (arrContents arr) (arrStart arr)
440438 $ \ptr -> do
441− let elemSize = sizeOfElem (undefined :: a)
442− elemPtr = ptr `plusPtr` (elemSize * i)
443− if i >= 0 && elemPtr `plusPtr` elemSize <= aEnd arr
439+ let elemPtr = PTR_INDEX(ptr,i,a)
440+ if i >= 0 && PTR_VALID(elemPtr,aEnd arr,a)
444441 then Just <$> peek elemPtr
445442 else return Nothing
446443
@@ -550,7 +547,7 @@ asBytes = unsafeCast
550547cast :: forall a b. (Storable b) => Array a -> Maybe (Array b)
551548cast arr =
552549 let len = A.byteLength arr
553− r = len `mod` sizeOfElem (undefined :: b)
550+ r = len `mod` SIZE_OF(b)
554551 in if r /= 0
555552 then Nothing
556553 else Just $ unsafeCast arr
src/Streamly/Internal/Data/Array/Foreign/Mut/Type.hs+74−107
@@ -200,11 +200,11 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
200200 , memcpy
201201 , memcmp
202202 , c_memchr
203− , sizeOfElem
204203 )
205204where
206205
207206#include "inline.hs"
207+#include "ArrayMacros.h"
208208#include "MachDeps.h"
209209
210210#ifdef USE_C_MALLOC
@@ -276,14 +276,6 @@ import Prelude hiding
276276-- >>> import qualified Streamly.Internal.Data.Fold as Fold
277277-- >>> import qualified Streamly.Internal.Data.Fold.Type as Fold
278278
279−-------------------------------------------------------------------------------
280−-- Utilities
281−-------------------------------------------------------------------------------
282−
283−{-# INLINE sizeOfElem #-}
284−sizeOfElem :: forall a . (Storable a) => a -> Int
285−sizeOfElem _ = max 1 $ sizeOf (undefined :: a)
286−
287279-------------------------------------------------------------------------------
288280-- Foreign helpers
289281-------------------------------------------------------------------------------
@@ -301,10 +293,8 @@ foreign import ccall unsafe "string.h memcmp" c_memcmp
301293-- how many elements of that type will completely fit in those bytes.
302294--
303295{-# INLINE bytesToElemCount #-}
304−bytesToElemCount :: Storable a => a -> Int -> Int
305−bytesToElemCount x n =
306− let elemSize = sizeOfElem x
307− in n `div` elemSize
296+bytesToElemCount :: forall a. Storable a => a -> Int -> Int
297+bytesToElemCount _ n = n `div` SIZE_OF(a)
308298
309299-- XXX we are converting Int to CSize
310300memcpy :: Ptr Word8 -> Ptr Word8 -> Int -> IO ()
@@ -456,7 +446,7 @@ fromForeignPtrUnsafe fp@(ForeignPtr start contents) end bound =
456446newArrayWith :: forall m a. (MonadIO m, Storable a)
457447 => (Int -> Int -> m (ArrayContents, Ptr a)) -> Int -> Int -> m (Array a)
458448newArrayWith alloc alignSize count = do
459− let size = max (count * sizeOfElem (undefined :: a)) 0
449+ let size = max (count * SIZE_OF(a)) 0
460450 (contents, p) <- alloc size alignSize
461451 return $ Array
462452 { arrContents = contents
@@ -511,7 +501,7 @@ newArrayAlignedUnmanaged = do
511501 return (ArrayContents contents, Ptr addr)
512502#else
513503newArrayAlignedUnmanaged _align count = do
514− let size = max (count * sizeOfElem (undefined :: a)) 0
504+ let size = max (count * SIZE_OF(a)) 0
515505 p <- liftIO $ mallocBytes size
516506 return $ Array
517507 { arrContents = nilArrayContents
@@ -565,9 +555,8 @@ putIndexUnsafe :: forall m a. (MonadIO m, Storable a)
565555 => Array a -> Int -> a -> m ()
566556putIndexUnsafe Array{..} i x =
567557 unsafeWithArrayContents arrContents arrStart $ \ptr -> do
568− let elemSize = sizeOfElem (undefined :: a)
569− elemPtr = ptr `plusPtr` (elemSize * i)
570− assert (i >= 0 && elemPtr `plusPtr` elemSize <= aEnd) (return ())
558+ let elemPtr = PTR_INDEX(ptr,i,a)
559+ assert (i >= 0 && PTR_VALID(elemPtr,aEnd,a)) (return ())
571560 liftIO $ poke elemPtr x
572561
573562invalidIndex :: String -> Int -> a
@@ -578,9 +567,8 @@ invalidIndex label i =
578567putIndexPtr :: forall m a. (MonadIO m, Storable a) =>
579568 Ptr a -> Ptr a -> Int -> a -> m ()
580569putIndexPtr start end i x = do
581− let elemSize = sizeOfElem (undefined :: a)
582− elemPtr = start `plusPtr` (elemSize * i)
583− if i >= 0 && elemPtr `plusPtr` elemSize <= end
570+ let elemPtr = PTR_INDEX(start,i,a)
571+ if i >= 0 && PTR_VALID(elemPtr,end,a)
584572 then liftIO $ poke elemPtr x
585573 else invalidIndex "putIndexPtr" i
586574
@@ -622,9 +610,8 @@ modifyIndexUnsafe :: forall m a b. (MonadIO m, Storable a) =>
622610 Array a -> Int -> (a -> (a, b)) -> m b
623611modifyIndexUnsafe Array{..} i f = do
624612 liftIO $ unsafeWithArrayContents arrContents arrStart $ \ptr -> do
625− let elemSize = sizeOfElem (undefined :: a)
626− elemPtr = ptr `plusPtr` (elemSize * i)
627− assert (i >= 0 && elemPtr `plusPtr` elemSize <= aEnd) (return ())
613+ let elemPtr = PTR_INDEX(ptr,i,a)
614+ assert (i >= 0 && PTR_NEXT(elemPtr,a) <= aEnd) (return ())
628615 r <- peek elemPtr
629616 let (x, res) = f r
630617 poke elemPtr x
@@ -634,9 +621,8 @@ modifyIndexUnsafe Array{..} i f = do
634621modifyIndexPtr :: forall m a b. (MonadIO m, Storable a) =>
635622 Int -> (a -> (a, b)) -> Ptr a -> Ptr a -> m b
636623modifyIndexPtr i f start end = liftIO $ do
637− let elemSize = sizeOfElem (undefined :: a)
638− elemPtr = start `plusPtr` (elemSize * i)
639− if i >= 0 && elemPtr `plusPtr` elemSize <= end
624+ let elemPtr = PTR_INDEX(start,i,a)
625+ if i >= 0 && PTR_VALID(elemPtr,end,a)
640626 then do
641627 r <- peek elemPtr
642628 let (x, res) = f r
@@ -681,12 +667,11 @@ modify Array{..} f = liftIO $
681667
682668 where
683669
684− go ptr = do
685− let elemSize = sizeOfElem (undefined :: a)
686− when (ptr `plusPtr` elemSize <= aEnd) $ do
670+ go ptr =
671+ when (PTR_VALID(ptr,aEnd,a)) $ do
687672 r <- peek ptr
688673 poke ptr (f r)
689− go (ptr `plusPtr` elemSize)
674+ go (PTR_NEXT(ptr,a))
690675
691676{-# INLINE swapPtrs #-}
692677swapPtrs :: Storable a => Ptr a -> Ptr a -> IO ()
@@ -706,9 +691,8 @@ unsafeSwapIndices :: forall m a. (MonadIO m, Storable a)
706691 => Array a -> Int -> Int -> m ()
707692unsafeSwapIndices Array{..} i1 i2 = liftIO $ do
708693 unsafeWithArrayContents arrContents arrStart $ \ptr -> do
709− let elemSize = sizeOfElem (undefined :: a)
710− ptr1 = ptr `plusPtr` (elemSize * i1)
711− ptr2 = ptr `plusPtr` (elemSize * i2)
694+ let ptr1 = PTR_INDEX(ptr,i1,a)
695+ ptr2 = PTR_INDEX(ptr,i2,a)
712696 swapPtrs ptr1 (ptr2 :: Ptr a)
713697
714698-- | Swap the elements at two indices.
@@ -717,11 +701,12 @@ unsafeSwapIndices Array{..} i1 i2 = liftIO $ do
717701swapIndices :: forall m a. (MonadIO m, Storable a)
718702 => Array a -> Int -> Int -> m ()
719703swapIndices Array{..} i1 i2 = liftIO $ do
720− let elemSize = sizeOfElem (undefined :: a)
721− ptr1 = arrStart `plusPtr` (elemSize * i1)
722− ptr2 = arrStart `plusPtr` (elemSize * i2)
723− when (i1 < 0 || ptr1 >= aEnd ) $ invalidIndex "swapIndices" i1
724− when (i2 < 0 || ptr2 >= aEnd ) $ invalidIndex "swapIndices" i2
704+ let ptr1 = PTR_INDEX(arrStart,i1,a)
705+ ptr2 = PTR_INDEX(arrStart,i2,a)
706+ when (i1 < 0 || PTR_INVALID(ptr1,aEnd,a))
707+ $ invalidIndex "swapIndices" i1
708+ when (i2 < 0 || PTR_INVALID(ptr2,aEnd,a))
709+ $ invalidIndex "swapIndices" i2
725710 swapPtrs ptr1 (ptr2 :: Ptr a)
726711
727712-------------------------------------------------------------------------------
@@ -777,8 +762,7 @@ roundUpToPower2 x =
777762--
778763{-# INLINE allocBytesToBytes #-}
779764allocBytesToBytes :: forall a. Storable a => a -> Int -> Int
780−allocBytesToBytes _ n =
781− max (arrayPayloadSize n) (sizeOfElem (undefined :: a))
765+allocBytesToBytes _ n = max (arrayPayloadSize n) (SIZE_OF(a))
782766
783767-- | Given a 'Storable' type (unused first arg) and real allocation size
784768-- (including overhead), return how many elements of that type will completely
@@ -827,8 +811,7 @@ snocNewEnd newEnd arr@Array{..} x = liftIO $ do
827811{-# INLINE snocUnsafe #-}
828812snocUnsafe :: forall m a. (MonadIO m, Storable a) =>
829813 Array a -> a -> m (Array a)
830−snocUnsafe arr@Array{..} =
831− snocNewEnd (aEnd `plusPtr` sizeOfElem (undefined :: a)) arr
814+snocUnsafe arr@Array{..} = snocNewEnd (PTR_NEXT(aEnd,a)) arr
832815
833816-- | Like 'snoc' but does not reallocate when pre-allocated array capacity
834817-- becomes full.
@@ -838,7 +821,7 @@ snocUnsafe arr@Array{..} =
838821snocMay :: forall m a. (MonadIO m, Storable a) =>
839822 Array a -> a -> m (Maybe (Array a))
840823snocMay arr@Array{..} x = liftIO $ do
841− let newEnd = aEnd `plusPtr` sizeOfElem (undefined :: a)
824+ let newEnd = PTR_NEXT(aEnd,a)
842825 if newEnd <= aBound
843826 then Just <$> snocNewEnd newEnd arr x
844827 else return Nothing
@@ -875,8 +858,7 @@ snocWithRealloc :: forall m a. (MonadIO m, Storable a) =>
875858 -> a
876859 -> m (Array a)
877860snocWithRealloc sizer arr x = do
878− let elemSize = sizeOfElem (undefined :: a)
879− arr1 <- liftIO $ reallocWith "snocWith" sizer elemSize arr
861+ arr1 <- liftIO $ reallocWith "snocWith" sizer (SIZE_OF(a)) arr
880862 snocUnsafe arr1 x
881863
882864-- | @snocWith sizer arr elem@ mutates @arr@ to append @elem@. The length of
@@ -899,7 +881,7 @@ snocWith :: forall m a. (MonadIO m, Storable a) =>
899881 -> a
900882 -> m (Array a)
901883snocWith allocSize arr x = liftIO $ do
902− let newEnd = aEnd arr `plusPtr` sizeOfElem (undefined :: a)
884+ let newEnd = PTR_NEXT(aEnd arr,a)
903885 if newEnd <= aBound arr
904886 then snocNewEnd newEnd arr x
905887 else snocWithRealloc allocSize arr x
@@ -970,9 +952,7 @@ reallocAligned elemSize alignSize newSize Array{..} = do
970952{-# INLINABLE realloc #-}
971953realloc :: forall m a. (MonadIO m, Storable a) => Int -> Array a -> m (Array a)
972954realloc i arr =
973− liftIO
974− $ reallocAligned
975− (sizeOfElem (undefined :: a)) (alignment (undefined :: a)) i arr
955+ liftIO $ reallocAligned (SIZE_OF(a)) (alignment (undefined :: a)) i arr
976956
977957-- | Change the reserved memory of the array so that it is enough to hold the
978958-- specified number of elements. Nothing is done if the specified capacity is
@@ -1014,7 +994,7 @@ rightSize arr@Array{..} = do
1014994 target = roundUpLargeArray len
1015995 waste = aBound `minusPtr` aEnd
1016996 assert (target >= len) (return ())
1017− assert (len `mod` sizeOfElem (undefined :: a) == 0) (return ())
997+ assert (len `mod` SIZE_OF(a) == 0) (return ())
1018998 -- We trade off some wastage (25%) to avoid reallocations and copying.
1019999 if target < capacity && len < 3 * waste
10201000 then realloc target arr
@@ -1065,18 +1045,16 @@ truncateExp = undefined
10651045getIndexUnsafe :: forall m a. (MonadIO m, Storable a) => Array a -> Int -> m a
10661046getIndexUnsafe Array {..} i =
10671047 unsafeWithArrayContents arrContents arrStart $ \ptr -> do
1068− let elemSize = sizeOfElem (undefined :: a)
1069− elemPtr = ptr `plusPtr` (elemSize * i)
1070− assert (i >= 0 && elemPtr `plusPtr` elemSize <= aEnd) (return ())
1048+ let elemPtr = PTR_INDEX(ptr,i,a)
1049+ assert (i >= 0 && PTR_VALID(elemPtr,aEnd,a)) (return ())
10711050 liftIO $ peek elemPtr
10721051
10731052{-# INLINE getIndexPtr #-}
10741053getIndexPtr :: forall m a. (MonadIO m, Storable a) =>
10751054 Ptr a -> Ptr a -> Int -> m a
1076−getIndexPtr ptr end i = do
1077− let elemSize = sizeOfElem (undefined :: a)
1078− elemPtr = ptr `plusPtr` (elemSize * i)
1079− if i >= 0 && elemPtr `plusPtr` elemSize <= end
1055+getIndexPtr start end i = do
1056+ let elemPtr = PTR_INDEX(start,i,a)
1057+ if i >= 0 && PTR_VALID(elemPtr,end,a)
10801058 then liftIO $ peek elemPtr
10811059 else invalidIndex "getIndexPtr" i
10821060
@@ -1091,10 +1069,9 @@ getIndex arr i =
10911069{-# INLINE getIndexPtrRev #-}
10921070getIndexPtrRev :: forall m a. (MonadIO m, Storable a) =>
10931071 Ptr a -> Ptr a -> Int -> m a
1094−getIndexPtrRev ptr end i = do
1095− let elemSize = sizeOfElem (undefined :: a)
1096− elemPtr = end `plusPtr` negate (elemSize * (i + 1))
1097− if i >= 0 && elemPtr >= ptr
1072+getIndexPtrRev start end i = do
1073+ let elemPtr = PTR_RINDEX(end,i,a)
1074+ if i >= 0 && elemPtr >= start
10981075 then liftIO $ peek elemPtr
10991076 else invalidIndex "getIndexPtrRev" i
11001077
@@ -1160,9 +1137,8 @@ getSliceUnsafe :: forall a. Storable a
11601137 -> Array a
11611138 -> Array a
11621139getSliceUnsafe index len (Array contents start e _) =
1163− let size = sizeOfElem (undefined :: a)
1164− fp1 = start `plusPtr` (index * size)
1165− end = fp1 `plusPtr` (len * size)
1140+ let fp1 = PTR_INDEX(start,index,a)
1141+ end = fp1 `plusPtr` (len * SIZE_OF(a))
11661142 in assert
11671143 (index >= 0 && len >= 0 && end <= e)
11681144 (Array contents fp1 end end)
@@ -1178,9 +1154,8 @@ getSlice :: forall a. Storable a =>
11781154 -> Array a
11791155 -> Array a
11801156getSlice index len (Array contents start e _) =
1181− let size = sizeOfElem (undefined :: a)
1182− fp1 = start `plusPtr` (index * size)
1183− end = fp1 `plusPtr` (len * size)
1157+ let fp1 = PTR_INDEX(start,index,a)
1158+ end = fp1 `plusPtr` (len * SIZE_OF(a))
11841159 in if index >= 0 && len >= 0 && end <= e
11851160 then Array contents fp1 end end
11861161 else error
@@ -1203,17 +1178,15 @@ getSlice index len (Array contents start e _) =
12031178reverse :: forall m a. (MonadIO m, Storable a) => Array a -> m ()
12041179reverse Array{..} = liftIO $ do
12051180 let l = arrStart
1206− h = aEnd `plusPtr` (- elemSize)
1181+ h = PTR_PREV(aEnd,a)
12071182 in swap l h
12081183
12091184 where
12101185
1211− elemSize = sizeOfElem (undefined :: a)
1212−
12131186 swap l h = do
12141187 when (l < h) $ do
12151188 swapPtrs l h
1216− swap (l `plusPtr` elemSize) (h `plusPtr` (- elemSize))
1189+ swap (PTR_NEXT(l,a)) (PTR_PREV(h,a))
12171190
12181191-- | Generate the next permutation of the sequence, returns False if this is
12191192-- the last permutation.
@@ -1297,7 +1270,7 @@ byteLength Array{..} =
12971270{-# INLINE length #-}
12981271length :: forall a. Storable a => Array a -> Int
12991272length arr =
1300− let elemSize = sizeOfElem (undefined :: a)
1273+ let elemSize = SIZE_OF(a)
13011274 blen = byteLength arr
13021275 in assert (blen `mod` elemSize == 0) (blen `div` elemSize)
13031276
@@ -1365,13 +1338,13 @@ arraysOf n (D.Stream step state) =
13651338 case r of
13661339 D.Yield x s -> do
13671340 liftIO $ poke end x >> touch contents
1368− let end' = end `plusPtr` sizeOfElem (undefined :: a)
1341+ let end1 = PTR_NEXT(end,a)
13691342 return $
1370− if end' >= bound
1343+ if end1 >= bound
13711344 then D.Skip
13721345 (GroupYield
1373− contents start end' bound (GroupStart s))
1374− else D.Skip (GroupBuffer s contents start end' bound)
1346+ contents start end1 bound (GroupStart s))
1347+ else D.Skip (GroupBuffer s contents start end1 bound)
13751348 D.Skip s ->
13761349 return $ D.Skip (GroupBuffer s contents start end bound)
13771350 D.Stop ->
@@ -1430,8 +1403,7 @@ flattenArrays (D.Stream step state) = D.Stream step' (OuterLoop state)
14301403 r <- peek p
14311404 touch contents
14321405 return r
1433− return $ D.Yield x (InnerLoop st contents
1434− (p `plusPtr` sizeOfElem (undefined :: a)) end)
1406+ return $ D.Yield x (InnerLoop st contents (PTR_NEXT(p,a)) end)
14351407
14361408-- | Use the "readRev" unfold instead.
14371409--
@@ -1451,7 +1423,7 @@ flattenArraysRev (D.Stream step state) = D.Stream step' (OuterLoop state)
14511423 r <- step (adaptState gst) st
14521424 return $ case r of
14531425 D.Yield Array{..} s ->
1454− let p = aEnd `plusPtr` negate (sizeOfElem (undefined :: a))
1426+ let p = PTR_PREV(aEnd,a)
14551427 in D.Skip (InnerLoop s arrContents p arrStart)
14561428 D.Skip s -> D.Skip (OuterLoop s)
14571429 D.Stop -> D.Stop
@@ -1464,7 +1436,7 @@ flattenArraysRev (D.Stream step state) = D.Stream step' (OuterLoop state)
14641436 r <- peek p
14651437 touch contents
14661438 return r
1467− let cur = p `plusPtr` negate (sizeOfElem (undefined :: a))
1439+ let cur = PTR_PREV(p,a)
14681440 return $ D.Yield x (InnerLoop st contents cur start)
14691441
14701442-------------------------------------------------------------------------------
@@ -1493,8 +1465,7 @@ producer = Producer step (return . toReadUState) extract
14931465 return D.Stop
14941466 step (ReadUState contents end cur) = do
14951467 !x <- liftIO $ peek cur
1496− let cur1 = cur `plusPtr` sizeOfElem (undefined :: a)
1497− return $ D.Yield x (ReadUState contents end cur1)
1468+ return $ D.Yield x (ReadUState contents end (PTR_NEXT(cur,a)))
14981469
14991470 extract (ReadUState contents end cur) = return $ Array contents cur end end
15001471
@@ -1514,7 +1485,7 @@ readRev = Unfold step inject
15141485 where
15151486
15161487 inject (Array contents start end _) =
1517− let p = end `plusPtr` negate (sizeOfElem (undefined :: a))
1488+ let p = PTR_PREV(end,a)
15181489 in return $ ReadUState contents start p
15191490
15201491 {-# INLINE_LATE step #-}
@@ -1522,9 +1493,8 @@ readRev = Unfold step inject
15221493 liftIO $ touch contents
15231494 return D.Stop
15241495 step (ReadUState contents start p) = do
1525− x <- liftIO $ peek p
1526− let cur = p `plusPtr` negate (sizeOfElem (undefined :: a))
1527− return $ D.Yield x (ReadUState contents start cur)
1496+ x <- liftIO $ peek p
1497+ return $ D.Yield x (ReadUState contents start (PTR_PREV(p,a)))
15281498
15291499-------------------------------------------------------------------------------
15301500-- to Lists and streams
@@ -1551,7 +1521,7 @@ toListFB c n Array{..} = go arrStart
15511521 r <- peek p
15521522 touch arrContents
15531523 return r
1554− in c x (go (p `plusPtr` sizeOfElem (undefined :: a)))
1524+ in c x (go (PTR_NEXT(p,a)))
15551525-}
15561526
15571527-- XXX Monadic foldr/build fusion?
@@ -1568,7 +1538,7 @@ toList Array{..} = liftIO $ go arrStart
15681538 go p = do
15691539 x <- peek p
15701540 touch arrContents
1571− (:) x <$> go (p `plusPtr` sizeOfElem (undefined :: a))
1541+ (:) x <$> go (PTR_NEXT(p,a))
15721542
15731543-- | Use the 'read' unfold instead.
15741544--
@@ -1586,7 +1556,7 @@ toStreamD Array{..} = D.Stream step arrStart
15861556 step _ p = liftIO $ do
15871557 r <- peek p
15881558 touch arrContents
1589− return $ D.Yield r (p `plusPtr` sizeOfElem (undefined :: a))
1559+ return $ D.Yield r (PTR_NEXT(p,a))
15901560
15911561{-# INLINE toStreamK #-}
15921562toStreamK :: forall m a. (MonadIO m, Storable a) => Array a -> K.Stream m a
@@ -1600,7 +1570,7 @@ toStreamK Array{..} = go arrStart
16001570 r <- peek p
16011571 touch arrContents
16021572 return r
1603− in liftIO elemM `K.consM` go (p `plusPtr` sizeOfElem (undefined :: a))
1573+ in liftIO elemM `K.consM` go (PTR_NEXT(p,a))
16041574
16051575-- | Use the 'readRev' unfold instead.
16061576--
@@ -1610,7 +1580,7 @@ toStreamK Array{..} = go arrStart
16101580{-# INLINE_NORMAL toStreamDRev #-}
16111581toStreamDRev :: forall m a. (MonadIO m, Storable a) => Array a -> D.Stream m a
16121582toStreamDRev Array{..} =
1613− let p = aEnd `plusPtr` negate (sizeOfElem (undefined :: a))
1583+ let p = PTR_PREV(aEnd,a)
16141584 in D.Stream step p
16151585
16161586 where
@@ -1620,12 +1590,12 @@ toStreamDRev Array{..} =
16201590 step _ p = liftIO $ do
16211591 r <- peek p
16221592 touch arrContents
1623− return $ D.Yield r (p `plusPtr` negate (sizeOfElem (undefined :: a)))
1593+ return $ D.Yield r (PTR_PREV(p,a))
16241594
16251595{-# INLINE toStreamKRev #-}
16261596toStreamKRev :: forall m a. (MonadIO m, Storable a) => Array a -> K.Stream m a
16271597toStreamKRev Array {..} =
1628− let p = aEnd `plusPtr` negate (sizeOfElem (undefined :: a))
1598+ let p = PTR_PREV(aEnd,a)
16291599 in go p
16301600
16311601 where
@@ -1636,7 +1606,7 @@ toStreamKRev Array {..} =
16361606 r <- peek p
16371607 touch arrContents
16381608 return r
1639− in liftIO elemM `K.consM` go (p `plusPtr` negate (sizeOfElem (undefined :: a)))
1609+ in liftIO elemM `K.consM` go (PTR_PREV(p,a))
16401610
16411611-------------------------------------------------------------------------------
16421612-- Folding
@@ -1705,8 +1675,7 @@ appendNUnsafe action n =
17051675 assert (n >= 0) (return ())
17061676 arr@(Array _ _ end bound) <- action
17071677 let free = bound `minusPtr` end
1708− elemSize = sizeOfElem (undefined :: a)
1709− needed = n * elemSize
1678+ needed = n * SIZE_OF(a)
17101679 -- XXX We can also reallocate if the array has too much free space,
17111680 -- otherwise we lose that space.
17121681 arr1 <-
@@ -1717,8 +1686,7 @@ appendNUnsafe action n =
17171686
17181687 step (ArrayUnsafe contents start end) x = do
17191688 liftIO $ poke end x >> touch contents
1720− let end1 = end `plusPtr` sizeOfElem (undefined :: a)
1721− return $ ArrayUnsafe contents start end1
1689+ return $ ArrayUnsafe contents start (PTR_NEXT(end,a))
17221690
17231691-- | Append @n@ elements to an existing array. Any free space left in the array
17241692-- after appending @n@ elements is lost.
@@ -1835,7 +1803,7 @@ writeNWithUnsafe alloc n = Fold step initial (return . fromArrayUnsafe)
18351803 liftIO $ poke end x >> touch contents
18361804 return
18371805 $ FL.Partial
1838− $ ArrayUnsafe contents start (end `plusPtr` sizeOfElem (undefined :: a))
1806+ $ ArrayUnsafe contents start (PTR_NEXT(end,a))
18391807
18401808-- | Like 'writeN' but does not check the array bounds when writing. The fold
18411809-- driver must not call the step function more than 'n' times otherwise it will
@@ -1908,20 +1876,19 @@ writeWith elemCount =
19081876
19091877 insertElem (Array contents start end bound) x = do
19101878 liftIO $ poke end x
1911− let end1 = end `plusPtr` sizeOfElem (undefined :: a)
1912− return $ Array contents start end1 bound
1879+ return $ Array contents start (PTR_NEXT(end,a)) bound
19131880
19141881 initial = do
19151882 when (elemCount < 0) $ error "writeWith: elemCount is negative"
19161883 liftIO $ newArrayAligned (alignment (undefined :: a)) elemCount
19171884 step arr@(Array _ start end bound) x
1918− | end `plusPtr` sizeOfElem (undefined :: a) > bound = do
1885+ | PTR_NEXT(end,a) > bound = do
19191886 let oldSize = end `minusPtr` start
19201887 newSize = max (oldSize * 2) 1
19211888 arr1 <-
19221889 liftIO
19231890 $ reallocAligned
1924− (sizeOfElem (undefined :: a))
1891+ (SIZE_OF(a))
19251892 (alignment (undefined :: a))
19261893 newSize
19271894 arr
@@ -1962,7 +1929,7 @@ fromStreamDN limit str = do
19621929
19631930 fwrite ptr x = do
19641931 liftIO $ poke ptr x
1965− return $ ptr `plusPtr` sizeOfElem (undefined :: a)
1932+ return $ PTR_NEXT(ptr,a)
19661933
19671934-- | Create an 'Array' from the first N elements of a list. The array is
19681935-- allocated to size N, if the list terminates before N elements then the
@@ -2156,7 +2123,7 @@ splitAt i arr@Array{..} =
21562123 else if i > maxIndex
21572124 then error $ "sliceAt: specified array index " ++ show i
21582125 ++ " is beyond the maximum index " ++ show maxIndex
2159− else let off = i * sizeOfElem (undefined :: a)
2126+ else let off = i * SIZE_OF(a)
21602127 p = arrStart `plusPtr` off
21612128 in ( Array
21622129 { arrContents = arrContents
@@ -2207,7 +2174,7 @@ asBytes = castUnsafe
22072174cast :: forall a b. Storable b => Array a -> Maybe (Array b)
22082175cast arr =
22092176 let len = byteLength arr
2210− r = len `mod` sizeOfElem (undefined :: b)
2177+ r = len `mod` SIZE_OF(b)
22112178 in if r /= 0
22122179 then Nothing
22132180 else Just $ castUnsafe arr
src/Streamly/Internal/Data/Array/Foreign/Type.hs+14−18
@@ -1,5 +1,3 @@
1−#include "inline.hs"
2−
31-- |
42-- Module : Streamly.Internal.Data.Array.Foreign.Type
53-- Copyright : (c) 2020 Composewell Technologies
@@ -74,6 +72,9 @@ module Streamly.Internal.Data.Array.Foreign.Type
7472 )
7573where
7674
75+#include "ArrayMacros.h"
76+#include "inline.hs"
77+
7778import Control.Exception (assert)
7879import Control.DeepSeq (NFData(..))
7980import Control.Monad.IO.Class (MonadIO(..))
@@ -90,7 +91,7 @@ import GHC.ForeignPtr (ForeignPtr)
9091import GHC.IO (unsafePerformIO)
9192import GHC.Ptr (Ptr(..))
9293import Streamly.Internal.Data.Array.Foreign.Mut.Type
93− (ArrayContents, ReadUState(..), sizeOfElem, touch)
94+ (ArrayContents, ReadUState(..), touch)
9495import Streamly.Internal.Data.Fold.Type (Fold(..))
9596import Streamly.Internal.Data.Stream.Serial (SerialT(..))
9697import Streamly.Internal.Data.Unfold.Type (Unfold(..))
@@ -466,7 +467,7 @@ readRev = Unfold step inject
466467 where
467468
468469 inject (Array contents start end) =
469− let p = end `plusPtr` negate (sizeOfElem (undefined :: a))
470+ let p = PTR_PREV(end,a)
470471 in return $ ReadUState contents start p
471472
472473 {-# INLINE_LATE step #-}
@@ -481,8 +482,7 @@ readRev = Unfold step inject
481482 -- This should be safe as the array contents are guaranteed to be
482483 -- evaluated/written to before we peek at them.
483484 let !x = unsafeInlineIO $ peek p
484− let cur = p `plusPtr` negate (sizeOfElem (undefined :: a))
485− return $ D.Yield x (ReadUState contents start cur)
485+ return $ D.Yield x (ReadUState contents start (PTR_PREV(p,a)))
486486
487487
488488{-# INLINE_NORMAL toStreamD #-}
@@ -505,7 +505,7 @@ toStreamD Array{..} = D.Stream step arrStart
505505 r <- peek p
506506 touch arrContents
507507 return r
508− return $ D.Yield x (p `plusPtr` sizeOfElem (undefined :: a))
508+ return $ D.Yield x (PTR_NEXT(p,a))
509509
510510{-# INLINE toStreamK #-}
511511toStreamK :: forall m a. Storable a => Array a -> K.Stream m a
@@ -520,13 +520,11 @@ toStreamK Array{..} = go arrStart
520520 r <- peek p
521521 touch arrContents
522522 return r
523− in x `K.cons` go (p `plusPtr` sizeOfElem (undefined :: a))
523+ in x `K.cons` go (PTR_NEXT(p,a))
524524
525525{-# INLINE_NORMAL toStreamDRev #-}
526526toStreamDRev :: forall m a. (Monad m, Storable a) => Array a -> D.Stream m a
527−toStreamDRev Array{..} =
528− let p = aEnd `plusPtr` negate (sizeOfElem (undefined :: a))
529− in D.Stream step p
527+toStreamDRev Array{..} = D.Stream step (PTR_PREV(aEnd,a))
530528
531529 where
532530
@@ -538,13 +536,11 @@ toStreamDRev Array{..} =
538536 r <- peek p
539537 touch arrContents
540538 return r
541− return $ D.Yield x (p `plusPtr` negate (sizeOfElem (undefined :: a)))
539+ return $ D.Yield x (PTR_PREV(p,a))
542540
543541{-# INLINE toStreamKRev #-}
544542toStreamKRev :: forall m a. Storable a => Array a -> K.Stream m a
545−toStreamKRev Array {..} =
546− let p = aEnd `plusPtr` negate (sizeOfElem (undefined :: a))
547− in go p
543+toStreamKRev Array {..} = go (PTR_PREV(aEnd,a))
548544
549545 where
550546
@@ -554,7 +550,7 @@ toStreamKRev Array {..} =
554550 r <- peek p
555551 touch arrContents
556552 return r
557− in x `K.cons` go (p `plusPtr` negate (sizeOfElem (undefined :: a)))
553+ in x `K.cons` go (PTR_PREV(p,a))
558554
559555-- | Convert an 'Array' into a stream.
560556--
@@ -613,7 +609,7 @@ toListFB c n Array{..} = go arrStart
613609 r <- peek p
614610 touch arrContents
615611 return r
616− in c x (go (p `plusPtr` sizeOfElem (undefined :: a)))
612+ in c x (go (PTR_NEXT(p,a)))
617613
618614-- | Convert an 'Array' into a list.
619615--
@@ -781,7 +777,7 @@ contraint.
781777{-# INLINE_NORMAL _foldr #-}
782778_foldr :: forall a b. (a -> b -> b) -> b -> Array a -> b
783779_foldr f z arr =
784− let !n = sizeOfElem (undefined :: a)
780+ let !n = SIZE_OF(a)
785781 in unsafePerformIO $ D.foldr f z $ toStreamD_ n arr
786782
787783-- | Note that the 'Foldable' instance is 7x slower than the direct
src/Streamly/Internal/Data/Array/Stream/Fold/Foreign.hs+8−7
@@ -51,6 +51,8 @@ module Streamly.Internal.Data.Array.Stream.Fold.Foreign
5151 )
5252where
5353
54+#include "ArrayMacros.h"
55+
5456import Control.Applicative (liftA2)
5557import Control.Exception (assert)
5658import Control.Monad.Catch (MonadThrow)
@@ -58,7 +60,7 @@ import Control.Monad.IO.Class (MonadIO(..))
5860import Foreign.Ptr (minusPtr, plusPtr)
5961import Foreign.Storable (Storable(..))
6062import GHC.Types (SPEC(..))
61−import Streamly.Internal.Data.Array.Foreign.Mut.Type (sizeOfElem, touch)
63+import Streamly.Internal.Data.Array.Foreign.Mut.Type (touch)
6264import Streamly.Internal.Data.Array.Foreign.Type (Array(..))
6365import Streamly.Internal.Data.Parser.ParserD (Initial(..), Step(..))
6466import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
@@ -118,8 +120,8 @@ fromFold (Fold.Fold fstep finitial fextract) =
118120 goArray !_ !cur !fs = do
119121 x <- liftIO $ peek cur
120122 res <- fstep fs x
121− let elemSize = sizeOfElem (undefined :: a)
122− next = cur `plusPtr` elemSize
123+ let elemSize = SIZE_OF(a)
124+ next = PTR_NEXT(cur,a)
123125 case res of
124126 Fold.Done b ->
125127 return $ Done ((end `minusPtr` next) `div` elemSize) b
@@ -156,8 +158,8 @@ fromParser (ParserD.Parser step1 initial1 extract1) =
156158 x <- liftIO $ peek cur
157159 liftIO $ touch contents
158160 res <- step1 fs x
159− let elemSize = sizeOfElem (undefined :: a)
160− next = cur `plusPtr` elemSize
161+ let elemSize = SIZE_OF(a)
162+ next = PTR_NEXT(cur,a)
161163 arrRem = (end `minusPtr` next) `div` elemSize
162164 case res of
163165 ParserD.Done n b -> do
@@ -320,8 +322,7 @@ take n (Fold (ParserD.Parser step1 initial1 extract1)) =
320322 Error err -> return $ Error err
321323 else do
322324 let !(Array contents start _) = arr
323− sz = sizeOfElem (undefined :: a)
324− end = start `plusPtr` (i * sz)
325+ end = PTR_INDEX(start,i,a)
325326 arr1 = Array contents start end
326327 remaining = negate i1
327328 res <- step1 r arr1
src/Streamly/Internal/Data/Array/Stream/Foreign.hs+7−11
@@ -46,6 +46,7 @@ module Streamly.Internal.Data.Array.Stream.Foreign
4646 )
4747where
4848
49+#include "ArrayMacros.h"
4950#include "inline.hs"
5051
5152import Data.Bifunctor (second)
@@ -76,7 +77,7 @@ import Streamly.Internal.Data.Stream.IsStream.Type
7677 (IsStream, fromStreamD, toStreamD)
7778import Streamly.Internal.Data.SVar (adaptState, defState)
7879import Streamly.Internal.Data.Array.Foreign.Mut.Type
79− (memcpy, allocBytesToElemCount, sizeOfElem)
80+ (memcpy, allocBytesToElemCount)
8081
8182import qualified Streamly.Internal.Data.Array.Foreign as A
8283import qualified Streamly.Internal.Data.Array.Foreign as Array
@@ -194,8 +195,7 @@ unlines sep (D.Stream step state) = D.Stream step' (OuterLoop state)
194195 r <- peek p
195196 touch contents
196197 return r
197− return $ D.Yield x (InnerLoop st contents
198− (p `plusPtr` sizeOfElem (undefined :: a)) end)
198+ return $ D.Yield x (InnerLoop st contents (PTR_NEXT(p,a)) end)
199199
200200-------------------------------------------------------------------------------
201201-- Compact
@@ -349,8 +349,7 @@ foldD (Fold fstep initial extract) stream@(D.Stream step state) = do
349349 goArray !_ st fp@(ForeignPtr end contents) !cur !fs = do
350350 x <- liftIO $ peek cur
351351 res <- fstep fs x
352− let elemSize = sizeOfElem (undefined :: a)
353− next = cur `plusPtr` elemSize
352+ let next = PTR_NEXT(cur,a)
354353 case res of
355354 FL.Done b -> do
356355 let arr = Array (fptrToArrayContents contents) next (Ptr end)
@@ -390,8 +389,7 @@ takeArrayListRev = go
390389 else if n == len
391390 then [x]
392391 else let !(Array contents _ end) = x
393− sz = sizeOfElem (undefined :: a)
394− !start = end `plusPtr` negate (n * sz)
392+ !start = end `plusPtr` negate (n * SIZE_OF(a))
395393 in [Array contents start end]
396394
397395-- When we have to take an array partially, take the last part of the array in
@@ -413,8 +411,7 @@ splitAtArrayListRev n ls
413411 else if m == len
414412 then ([x],xs)
415413 else let !(Array contents start end) = x
416− sz = sizeOfElem (undefined :: a)
417− end1 = end `plusPtr` negate (m * sz)
414+ end1 = end `plusPtr` negate (m * SIZE_OF(a))
418415 arr2 = Array contents start end1
419416 arr1 = Array contents end1 end
420417 in ([arr1], arr2:xs)
@@ -568,8 +565,7 @@ parseD (PRD.Parser pstep initial extract) stream@(D.Stream step state) = do
568565 gobuf !_ s backBuf fp@(ForeignPtr end contents) !cur !pst = do
569566 x <- liftIO $ peek cur
570567 pRes <- pstep pst x
571− let elemSize = sizeOfElem (undefined :: a)
572− next = cur `plusPtr` elemSize
568+ let next = PTR_NEXT(cur,a)
573569 case pRes of
574570 PR.Partial 0 pst1 ->
575571 gobuf SPEC s (List []) fp next pst1
src/Streamly/Internal/Data/Array/Stream/Mut/Foreign.hs+4−3
@@ -25,13 +25,14 @@ module Streamly.Internal.Data.Array.Stream.Mut.Foreign
2525where
2626
2727#include "inline.hs"
28+#include "ArrayMacros.h"
2829
2930import Control.Monad.IO.Class (MonadIO(..))
3031import Control.Monad (when)
3132import Control.Monad.Catch (MonadThrow)
3233import Data.Bifunctor (first)
3334import Foreign.Storable (Storable(..))
34−import Streamly.Internal.Data.Array.Foreign.Mut.Type (Array(..), sizeOfElem)
35+import Streamly.Internal.Data.Array.Foreign.Mut.Type (Array(..))
3536import Streamly.Internal.Data.Fold.Type (Fold(..))
3637import Streamly.Internal.Data.Stream.Serial (SerialT(..))
3738import Streamly.Internal.Data.Stream.IsStream.Type
@@ -211,7 +212,7 @@ compactLEParserD n = ParserD.Parser step initial extract
211212
212213 where
213214
214− nBytes = n * sizeOfElem (undefined :: a)
215+ nBytes = n * SIZE_OF(a)
215216
216217 initial =
217218 return
@@ -261,7 +262,7 @@ compactGEFold n = Fold step initial extract
261262
262263 where
263264
264− nBytes = n * sizeOfElem (undefined :: a)
265+ nBytes = n * SIZE_OF(a)
265266
266267 initial =
267268 return
src/Streamly/Internal/Data/Ring/Foreign.hs+9−9
@@ -68,6 +68,7 @@ module Streamly.Internal.Data.Ring.Foreign
6868 , slidingWindow
6969 ) where
7070
71+#include "ArrayMacros.h"
7172#include "inline.hs"
7273
7374import Control.Exception (assert)
@@ -79,8 +80,7 @@ import Foreign.Ptr (plusPtr, minusPtr, castPtr)
7980import Foreign.Storable (Storable(..))
8081import GHC.ForeignPtr (mallocPlainForeignPtrAlignedBytes)
8182import GHC.Ptr (Ptr(..))
82−import Streamly.Internal.Data.Array.Foreign.Mut.Type
83− (Array, memcmp, sizeOfElem)
83+import Streamly.Internal.Data.Array.Foreign.Mut.Type (Array, memcmp)
8484import Streamly.Internal.Data.Fold.Type (Fold(..), Step(..))
8585import Streamly.Internal.Data.Stream.Serial (SerialT(..))
8686import Streamly.Internal.Data.Unfold.Type (Unfold(..))
@@ -124,7 +124,7 @@ startOf = unsafeForeignPtrToPtr . ringStart
124124{-# INLINE new #-}
125125new :: forall a. Storable a => Int -> IO (Ring a, Ptr a)
126126new count = do
127− let size = count * sizeOfElem (undefined :: a)
127+ let size = count * SIZE_OF(a)
128128 fptr <- mallocPlainForeignPtrAlignedBytes size (alignment (undefined :: a))
129129 let p = unsafeForeignPtrToPtr fptr
130130 return (Ring
@@ -148,7 +148,7 @@ newRing = undefined
148148{-# INLINE advance #-}
149149advance :: forall a. Storable a => Ring a -> Ptr a -> Ptr a
150150advance Ring{..} ringHead =
151− let ptr = ringHead `plusPtr` sizeOfElem (undefined :: a)
151+ let ptr = PTR_NEXT(ringHead,a)
152152 in if ptr < ringBound
153153 then ptr
154154 else unsafeForeignPtrToPtr ringStart
@@ -162,7 +162,7 @@ moveBy by Ring {..} ringHead = ringStartPtr `plusPtr` advanceFromHead
162162
163163 where
164164
165− elemSize = sizeOfElem (undefined :: a)
165+ elemSize = SIZE_OF(a)
166166 ringStartPtr = unsafeForeignPtrToPtr ringStart
167167 lenInBytes = ringBound `minusPtr` ringStartPtr
168168 offInBytes = ringHead `minusPtr` ringStartPtr
@@ -362,7 +362,7 @@ asBytes = castUnsafe
362362cast :: forall a b. Storable b => Ring a -> Maybe (Ring b)
363363cast arr =
364364 let len = byteLength arr
365− r = len `mod` sizeOfElem (undefined :: b)
365+ r = len `mod` SIZE_OF(b)
366366 in if r /= 0
367367 then Nothing
368368 else Just $ castUnsafe arr
@@ -444,7 +444,7 @@ unsafeFoldRing ptr f z Ring{..} =
444444 | p == q = return acc
445445 | otherwise = do
446446 x <- peek p
447− go (f acc x) (p `plusPtr` sizeOfElem (undefined :: a)) q
447+ go (f acc x) (PTR_NEXT(p,a)) q
448448
449449-- XXX Can we remove MonadIO here?
450450withForeignPtrM :: MonadIO m => ForeignPtr a -> (Ptr a -> m b) -> m b
@@ -464,8 +464,8 @@ unsafeFoldRingM ptr f z Ring {..} =
464464 | start == end = return acc
465465 | otherwise = do
466466 let !x = unsafeInlineIO $ peek start
467− acc' <- f acc x
468− go acc' (start `plusPtr` sizeOfElem (undefined :: a)) end
467+ acc1 <- f acc x
468+ go acc1 (PTR_NEXT(start,a)) end
469469
470470-- | Fold the entire length of a ring buffer starting at the supplied ringHead
471471-- pointer. Assuming the supplied ringHead pointer points to the oldest item,
src/Streamly/Internal/Data/Stream/StreamD/Nesting.hs+5−5
@@ -146,6 +146,7 @@ module Streamly.Internal.Data.Stream.StreamD.Nesting
146146where
147147
148148#include "inline.hs"
149+#include "ArrayMacros.h"
149150
150151import Control.Exception (assert)
151152import Control.Monad.Catch (MonadThrow, throwM)
@@ -167,7 +168,6 @@ import Streamly.Internal.Data.Refold.Type (Refold(..))
167168import Streamly.Internal.Data.SVar.Type (adaptState)
168169import Streamly.Internal.Data.Tuple.Strict (Tuple'(..))
169170import Streamly.Internal.Data.Unfold.Type (Unfold(..))
170−import Streamly.Internal.Data.Array.Foreign.Mut.Type (sizeOfElem)
171171
172172import qualified Streamly.Internal.Data.Array.Foreign.Type as A
173173import qualified Streamly.Internal.Data.Fold as FL
@@ -1672,7 +1672,7 @@ splitOnSeq patArr (Fold fstep initial done) (Stream step state) =
16721672
16731673 patLen = A.length patArr
16741674 maxIndex = patLen - 1
1675− elemBits = sizeOfElem (undefined :: a) * 8
1675+ elemBits = SIZE_OF(a) * 8
16761676
16771677 -- For word pattern case
16781678 wordMask :: Word
@@ -1720,7 +1720,7 @@ splitOnSeq patArr (Fold fstep initial done) (Stream step state) =
17201720 then do
17211721 pat <- liftIO $ A.unsafeIndexIO patArr 0
17221722 return $ Skip $ SplitOnSeqSingle acc state pat
1723− else if sizeOfElem (undefined :: a) * patLen
1723+ else if SIZE_OF(a) * patLen
17241724 <= sizeOf (undefined :: Word)
17251725 then return $ Skip $ SplitOnSeqWordInit acc state
17261726 else do
@@ -1986,7 +1986,7 @@ splitOnSuffixSeq withSep patArr (Fold fstep initial done) (Stream step state) =
19861986
19871987 patLen = A.length patArr
19881988 maxIndex = patLen - 1
1989− elemBits = sizeOfElem (undefined :: a) * 8
1989+ elemBits = SIZE_OF(a) * 8
19901990
19911991 -- For word pattern case
19921992 wordMask :: Word
@@ -2053,7 +2053,7 @@ splitOnSuffixSeq withSep patArr (Fold fstep initial done) (Stream step state) =
20532053 then do
20542054 pat <- liftIO $ A.unsafeIndexIO patArr 0
20552055 skip $ SplitOnSuffixSeqSingleInit fs state pat
2056− else if sizeOfElem (undefined :: a) * patLen
2056+ else if SIZE_OF(a) * patLen
20572057 <= sizeOf (undefined :: Word)
20582058 then skip $ SplitOnSuffixSeqWordInit fs state
20592059 else do
streamly.cabal+6−1
@@ -86,6 +86,7 @@ extra-source-files:
8686 src/Streamly/Internal/Data/Stream/Instances.hs
8787 src/Streamly/Internal/Data/Stream/PreludeCommon.hs
8888 src/Streamly/Internal/Data/Time/Clock/config-clock.h
89+ src/Streamly/Internal/Data/Array/ArrayMacros.h
8990 src/Streamly/Internal/Data/Array/PrimInclude.hs
9091 src/Streamly/Internal/Data/Array/Prim/TypesInclude.hs
9192 src/Streamly/Internal/Data/Array/Prim/MutTypesInclude.hs
@@ -321,7 +322,11 @@ library
321322 default-extensions: QuantifiedConstraints
322323
323324 js-sources: jsbits/clock.js
324− include-dirs: src, src/Streamly/Internal/Data/Stream
325+ include-dirs:
326+ src
327+ , src/Streamly/Internal/Data/Stream
328+ , src/Streamly/Internal/Data/Array
329+
325330 if os(windows)
326331 c-sources: src/Streamly/Internal/Data/Time/Clock/Windows.c
327332 exposed-modules: Streamly.Internal.FileSystem.Event.Windows