@@ -10,7 +10,6 @@ module Streamly.Internal.Data.Unboxed
10 , peekWith
10 , peekWith
11 , pokeWith
11 , pokeWith
12 , MutableByteArray(..)
12 , MutableByteArray(..)
15 , getMutableByteArray#
14 , getMutableByteArray#
@@ -72,24 +71,20 @@ import Prelude hiding (read)
72--------------------------------------------------------------------------------
71--------------------------------------------------------------------------------
74-- XXX can use UnliftedNewtypes
73-- XXX can use UnliftedNewtypes
75−data MutableByteArray a = MutableByteArray (MutableByteArray# RealWorld)
74+data MutableByteArray = MutableByteArray (MutableByteArray# RealWorld)
77{-# INLINE getMutableByteArray# #-}
76{-# INLINE getMutableByteArray# #-}
78−getMutableByteArray# :: MutableByteArray a -> MutableByteArray# RealWorld
77+getMutableByteArray# :: MutableByteArray -> MutableByteArray# RealWorld
79getMutableByteArray# (MutableByteArray mbarr) = mbarr
78getMutableByteArray# (MutableByteArray mbarr) = mbarr
81−{-# INLINE castContents #-}
82−castContents :: MutableByteArray a -> MutableByteArray b
83−castContents (MutableByteArray mbarr) = MutableByteArray mbarr
85{-# INLINE touch #-}
80{-# INLINE touch #-}
86−touch :: MutableByteArray a -> IO ()
81+touch :: MutableByteArray -> IO ()
87touch (MutableByteArray contents) =
82touch (MutableByteArray contents) =
88 IO $ \s -> case touch# contents s of s' -> (# s', () #)
83 IO $ \s -> case touch# contents s of s' -> (# s', () #)
90-- | Return the size of the array in bytes.
85-- | Return the size of the array in bytes.
91{-# INLINE sizeOfMutableByteArray #-}
86{-# INLINE sizeOfMutableByteArray #-}
92−sizeOfMutableByteArray :: MutableByteArray a -> IO Int
87+sizeOfMutableByteArray :: MutableByteArray -> IO Int
93sizeOfMutableByteArray (MutableByteArray arr) =
88sizeOfMutableByteArray (MutableByteArray arr) =
94 IO $ \s ->
89 IO $ \s ->
95 case getSizeofMutableByteArray# arr s of
90 case getSizeofMutableByteArray# arr s of
@@ -100,11 +95,11 @@ sizeOfMutableByteArray (MutableByteArray arr) =
100--------------------------------------------------------------------------------
95--------------------------------------------------------------------------------
102{-# NOINLINE nil #-}
97{-# NOINLINE nil #-}
103−nil :: MutableByteArray a
98+nil :: MutableByteArray
104nil = unsafePerformIO $ newUnpinnedBytes 0
99nil = unsafePerformIO $ newUnpinnedBytes 0
106{-# INLINE newUnpinnedBytes #-}
101{-# INLINE newUnpinnedBytes #-}
107−newUnpinnedBytes :: Int -> IO (MutableByteArray a)
102+newUnpinnedBytes :: Int -> IO MutableByteArray
108newUnpinnedBytes nbytes | nbytes < 0 =
103newUnpinnedBytes nbytes | nbytes < 0 =
109 errorWithoutStackTrace "newUnpinnedBytes: size must be >= 0"
104 errorWithoutStackTrace "newUnpinnedBytes: size must be >= 0"
110newUnpinnedBytes (I# nbytes) = IO $ \s ->
105newUnpinnedBytes (I# nbytes) = IO $ \s ->
@@ -114,7 +109,7 @@ newUnpinnedBytes (I# nbytes) = IO $ \s ->
114 in (# s', c #)
109 in (# s', c #)
116{-# INLINE newPinnedBytes #-}
111{-# INLINE newPinnedBytes #-}
117−newPinnedBytes :: Int -> IO (MutableByteArray a)
112+newPinnedBytes :: Int -> IO MutableByteArray
118newPinnedBytes nbytes | nbytes < 0 =
113newPinnedBytes nbytes | nbytes < 0 =
119 errorWithoutStackTrace "newPinnedBytes: size must be >= 0"
114 errorWithoutStackTrace "newPinnedBytes: size must be >= 0"
120newPinnedBytes (I# nbytes) = IO $ \s ->
115newPinnedBytes (I# nbytes) = IO $ \s ->
@@ -124,7 +119,7 @@ newPinnedBytes (I# nbytes) = IO $ \s ->
124 in (# s', c #)
119 in (# s', c #)
126{-# INLINE newAlignedPinnedBytes #-}
121{-# INLINE newAlignedPinnedBytes #-}
127−newAlignedPinnedBytes :: Int -> Int -> IO (MutableByteArray a)
122+newAlignedPinnedBytes :: Int -> Int -> IO MutableByteArray
128newAlignedPinnedBytes nbytes _align | nbytes < 0 =
123newAlignedPinnedBytes nbytes _align | nbytes < 0 =
129 errorWithoutStackTrace "newAlignedPinnedBytes: size must be >= 0"
124 errorWithoutStackTrace "newAlignedPinnedBytes: size must be >= 0"
130newAlignedPinnedBytes (I# nbytes) (I# align) = IO $ \s ->
125newAlignedPinnedBytes (I# nbytes) (I# align) = IO $ \s ->
@@ -138,7 +133,7 @@ newAlignedPinnedBytes (I# nbytes) (I# align) = IO $ \s ->
138-------------------------------------------------------------------------------
133-------------------------------------------------------------------------------
140{-# INLINE isPinned #-}
135{-# INLINE isPinned #-}
141−isPinned :: MutableByteArray a -> Bool
136+isPinned :: MutableByteArray -> Bool
142isPinned (MutableByteArray arr#) =
137isPinned (MutableByteArray arr#) =
143 let pinnedInt = I# (isMutableByteArrayPinned# arr#)
138 let pinnedInt = I# (isMutableByteArrayPinned# arr#)
144 in pinnedInt == 1
139 in pinnedInt == 1
@@ -160,7 +155,7 @@ cloneMutableArrayWith# alloc# arr# s# =
160 s3# -> (# s3#, arr1# #)
155 s3# -> (# s3#, arr1# #)
162{-# INLINE pin #-}
157{-# INLINE pin #-}
163−pin :: MutableByteArray a -> IO (MutableByteArray a)
158+pin :: MutableByteArray -> IO MutableByteArray
164pin arr@(MutableByteArray marr#) =
159pin arr@(MutableByteArray marr#) =
165 if isPinned arr
160 if isPinned arr
166 then return arr
161 then return arr
@@ -170,7 +165,7 @@ pin arr@(MutableByteArray marr#) =
170 (# s1#, marr1# #) -> (# s1#, MutableByteArray marr1# #)
165 (# s1#, marr1# #) -> (# s1#, MutableByteArray marr1# #)
172{-# INLINE unpin #-}
167{-# INLINE unpin #-}
173−unpin :: MutableByteArray a -> IO (MutableByteArray a)
168+unpin :: MutableByteArray -> IO MutableByteArray
174unpin arr@(MutableByteArray marr#) =
169unpin arr@(MutableByteArray marr#) =
175 if not (isPinned arr)
170 if not (isPinned arr)
176 then return arr
171 then return arr
@@ -185,8 +180,6 @@ unpin arr@(MutableByteArray marr#) =
186-- XXX Use Proxy type in sizeOf method.
181-- XXX Use Proxy type in sizeOf method.
187-- XXX generate error if the size is < 1
182-- XXX generate error if the size is < 1
188−-- XXX Remove the phantom parameter from MutableByteArray?
189−-- XXX Rename/remove castContents
191-- In theory we could convert a type to and from a byte stream and use that
184-- In theory we could convert a type to and from a byte stream and use that
192-- to implement boxing, unboxing. But that would be inefficient. This type
185-- to implement boxing, unboxing. But that would be inefficient. This type
@@ -250,19 +243,16 @@ unpin arr@(MutableByteArray marr#) =
251-- If you want to write the instance manually:
244-- If you want to write the instance manually:
253−-- >>> import Streamly.Internal.Data.Unboxed (castContents)
255-- instance Unbox Object where
247-- instance Unbox Object where
256-- sizeOf _ = 16
248-- sizeOf _ = 16
257-- peekByteIndex i arr = do
249-- peekByteIndex i arr = do
258−-- let p = castContents arr
259−-- x0 <- peekByteIndex i p
250+-- x0 <- peekByteIndex i arr
260−-- x1 <- peekByteIndex (i + 8) p
251+-- x1 <- peekByteIndex (i + 8) arr
261-- return $ Object x0 x1
252-- return $ Object x0 x1
262-- pokeByteIndex i arr (Object x0 x1) = do
253-- pokeByteIndex i arr (Object x0 x1) = do
263−-- let p = castContents arr
264−-- pokeByteIndex i p x0
254+-- pokeByteIndex i arr x0
265−-- pokeByteIndex (i + 8) p x1
255+-- pokeByteIndex (i + 8) arr x1
268class Unbox a where
258class Unbox a where
@@ -277,10 +267,10 @@ class Unbox a where
278 -- IMPORTANT: The implementation of this interface may not check the bounds
268 -- IMPORTANT: The implementation of this interface may not check the bounds
279 -- of the array, the caller must not assume that.
269 -- of the array, the caller must not assume that.
280− peekByteIndex :: Int -> MutableByteArray a -> IO a
270+ peekByteIndex :: Int -> MutableByteArray -> IO a
282 default peekByteIndex :: (Generic a, PeekRep (Rep a)) =>
272 default peekByteIndex :: (Generic a, PeekRep (Rep a)) =>
283− Int -> MutableByteArray a -> IO a
273+ Int -> MutableByteArray -> IO a
284 peekByteIndex i arr = genericPeekByteIndex arr i
274 peekByteIndex i arr = genericPeekByteIndex arr i
286 -- | Write an element of type "a" to a MutableByteArray given the byte
276 -- | Write an element of type "a" to a MutableByteArray given the byte
@@ -288,10 +278,10 @@ class Unbox a where
289 -- IMPORTANT: The implementation of this interface may not check the bounds
279 -- IMPORTANT: The implementation of this interface may not check the bounds
290 -- of the array, the caller must not assume that.
280 -- of the array, the caller must not assume that.
291− pokeByteIndex :: Int -> MutableByteArray a -> a -> IO ()
281+ pokeByteIndex :: Int -> MutableByteArray -> a -> IO ()
293 default pokeByteIndex :: (Generic a, PokeRep (Rep a)) =>
283 default pokeByteIndex :: (Generic a, PokeRep (Rep a)) =>
294− Int -> MutableByteArray a -> a -> IO ()
284+ Int -> MutableByteArray -> a -> IO ()
295 pokeByteIndex i arr = genericPokeByteIndex arr i
285 pokeByteIndex i arr = genericPokeByteIndex arr i
297#define DERIVE_UNBOXED(_type, _constructor, _readArray, _writeArray, _sizeOf) \
287#define DERIVE_UNBOXED(_type, _constructor, _readArray, _writeArray, _sizeOf) \
@@ -310,9 +300,9 @@ instance Unbox _type where { \
310#define DERIVE_WRAPPED_UNBOX(_constraint, _type, _constructor, _innerType) \
300#define DERIVE_WRAPPED_UNBOX(_constraint, _type, _constructor, _innerType) \
311instance _constraint Unbox _type where \
301instance _constraint Unbox _type where \
312; {-# INLINE peekByteIndex #-} \
302; {-# INLINE peekByteIndex #-} \
313−; peekByteIndex i arr = _constructor <$> peekByteIndex i (castContents arr) \
303+; peekByteIndex i arr = _constructor <$> peekByteIndex i arr \
314; {-# INLINE pokeByteIndex #-} \
304; {-# INLINE pokeByteIndex #-} \
315−; pokeByteIndex i arr (_constructor a) = pokeByteIndex i (castContents arr) a \
305+; pokeByteIndex i arr (_constructor a) = pokeByteIndex i arr a \
316; {-# INLINE sizeOf #-} \
306; {-# INLINE sizeOf #-} \
317; sizeOf _ = SIZE_OF(_innerType)
307; sizeOf _ = SIZE_OF(_innerType)
@@ -320,15 +310,13 @@ instance _constraint Unbox _type where \
320instance _constraint Unbox _type where { \
310instance _constraint Unbox _type where { \
321; {-# INLINE peekByteIndex #-} \
311; {-# INLINE peekByteIndex #-} \
322; peekByteIndex i arr = \
312; peekByteIndex i arr = \
323− let contents = castContents arr :: MutableByteArray _innerType \
324− in peekByteIndex i contents >>= \
313+ peekByteIndex i arr >>= \
325− (\p1 -> peekByteIndex (i + SIZE_OF(_innerType)) contents \
314+ (\p1 -> peekByteIndex (i + SIZE_OF(_innerType)) arr \
326− <&> _constructor p1) \
315+ <&> _constructor p1) \
327; {-# INLINE pokeByteIndex #-} \
316; {-# INLINE pokeByteIndex #-} \
328; pokeByteIndex i arr (_constructor p1 p2) = \
317; pokeByteIndex i arr (_constructor p1 p2) = \
329− let contents = castContents arr :: MutableByteArray _innerType \
330− in pokeByteIndex i contents p1 >> \
318+ pokeByteIndex i arr p1 >> \
331− pokeByteIndex (i + SIZE_OF(_innerType)) contents p2 \
319+ pokeByteIndex (i + SIZE_OF(_innerType)) arr p2 \
332; {-# INLINE sizeOf #-} \
320; {-# INLINE sizeOf #-} \
333; sizeOf _ = 2 * SIZE_OF(_innerType) \
321; sizeOf _ = 2 * SIZE_OF(_innerType) \
@@ -455,10 +443,10 @@ instance Unbox () where
455instance Unbox IoSubSystem where
443instance Unbox IoSubSystem where
457 {-# INLINE peekByteIndex #-}
445 {-# INLINE peekByteIndex #-}
458− peekByteIndex i arr = toEnum <$> peekByteIndex i (castContents arr)
446+ peekByteIndex i arr = toEnum <$> peekByteIndex i arr
460 {-# INLINE pokeByteIndex #-}
448 {-# INLINE pokeByteIndex #-}
461− pokeByteIndex i arr a = pokeByteIndex i (castContents arr) (fromEnum a)
449+ pokeByteIndex i arr a = pokeByteIndex i arr (fromEnum a)
463 {-# INLINE sizeOf #-}
451 {-# INLINE sizeOf #-}
464 sizeOf = sizeOf . fromEnum
452 sizeOf = sizeOf . fromEnum
@@ -468,14 +456,14 @@ instance Unbox Bool where
469 {-# INLINE peekByteIndex #-}
457 {-# INLINE peekByteIndex #-}
470 peekByteIndex i arr = do
458 peekByteIndex i arr = do
471− res <- peekByteIndex i (castContents arr)
459+ res <- peekByteIndex i arr
472 return $ res /= (0 :: Int8)
460 return $ res /= (0 :: Int8)
474 {-# INLINE pokeByteIndex #-}
462 {-# INLINE pokeByteIndex #-}
475 pokeByteIndex i arr a =
463 pokeByteIndex i arr a =
477− then pokeByteIndex i (castContents arr) (1 :: Int8)
465+ then pokeByteIndex i arr (1 :: Int8)
478− else pokeByteIndex i (castContents arr) (0 :: Int8)
466+ else pokeByteIndex i arr (0 :: Int8)
480 {-# INLINE sizeOf #-}
468 {-# INLINE sizeOf #-}
481 sizeOf _ = 1
469 sizeOf _ = 1
@@ -485,11 +473,11 @@ instance Unbox Bool where
485--------------------------------------------------------------------------------
473--------------------------------------------------------------------------------
487{-# INLINE peekWith #-}
475{-# INLINE peekWith #-}
488−peekWith :: Unbox a => MutableByteArray a -> Int -> IO a
476+peekWith :: Unbox a => MutableByteArray -> Int -> IO a
489peekWith arr i = peekByteIndex i arr
477peekWith arr i = peekByteIndex i arr
491{-# INLINE pokeWith #-}
479{-# INLINE pokeWith #-}
492−pokeWith :: Unbox a => MutableByteArray a -> Int -> a -> IO ()
480+pokeWith :: Unbox a => MutableByteArray -> Int -> a -> IO ()
493pokeWith arr i = pokeByteIndex i arr
481pokeWith arr i = pokeByteIndex i arr
495--------------------------------------------------------------------------------
483--------------------------------------------------------------------------------
@@ -502,7 +490,7 @@ pokeWith arr i = pokeByteIndex i arr
502-- cheaper to just get the bound using the size of the array whenever needed?
490-- cheaper to just get the bound using the size of the array whenever needed?
503data BoundedPtr =
491data BoundedPtr =
504 BoundedPtr
492 BoundedPtr
505− (MutableByteArray Word8) -- byte array
493+ MutableByteArray -- byte array
506 Int -- current pos
494 Int -- current pos
507 Int -- position after end
495 Int -- position after end
@@ -524,7 +512,7 @@ readUnsafe = Peeker (Builder step)
524 step :: forall a. Unbox a => BoundedPtr -> IO (BoundedPtr, a)
512 step :: forall a. Unbox a => BoundedPtr -> IO (BoundedPtr, a)
525 step (BoundedPtr arr pos end) = do
513 step (BoundedPtr arr pos end) = do
526 let next = pos + sizeOf (undefined :: a)
514 let next = pos + sizeOf (undefined :: a)
527− r <- peekByteIndex pos (castContents arr)
515+ r <- peekByteIndex pos arr
528 return (BoundedPtr arr next end, r)
516 return (BoundedPtr arr next end, r)
530{-# INLINE read #-}
518{-# INLINE read #-}
@@ -538,7 +526,7 @@ read = Peeker (Builder step)
538 step (BoundedPtr arr pos end) = do
526 step (BoundedPtr arr pos end) = do
539 let next = pos + sizeOf (undefined :: a)
527 let next = pos + sizeOf (undefined :: a)
540 when (next > end) $ error "peekObject reading beyond limit"
528 when (next > end) $ error "peekObject reading beyond limit"
541− r <- peekByteIndex pos (castContents arr)
529+ r <- peekByteIndex pos arr
542 return (BoundedPtr arr next end, r)
530 return (BoundedPtr arr next end, r)
544{-# INLINE skipByte #-}
532{-# INLINE skipByte #-}
@@ -572,7 +560,7 @@ runPeeker (Peeker (Builder f)) ptr = fmap snd (f ptr)
572pokeBoundedPtrUnsafe :: Unbox a => a -> BoundedPtr -> IO BoundedPtr
560pokeBoundedPtrUnsafe :: Unbox a => a -> BoundedPtr -> IO BoundedPtr
573pokeBoundedPtrUnsafe a (BoundedPtr arr pos end) = do
561pokeBoundedPtrUnsafe a (BoundedPtr arr pos end) = do
574 let next = pos + sizeOf a
562 let next = pos + sizeOf a
575− pokeByteIndex pos (castContents arr) a
563+ pokeByteIndex pos arr a
576 return (BoundedPtr arr next end)
564 return (BoundedPtr arr next end)
578{-# INLINE pokeBoundedPtr #-}
566{-# INLINE pokeBoundedPtr #-}
@@ -580,7 +568,7 @@ pokeBoundedPtr :: Unbox a => a -> BoundedPtr -> IO BoundedPtr
580pokeBoundedPtr a (BoundedPtr arr pos end) = do
568pokeBoundedPtr a (BoundedPtr arr pos end) = do
581 let next = pos + sizeOf a
569 let next = pos + sizeOf a
582 when (next > end) $ error "pokeBoundedPtr writing beyond limit"
570 when (next > end) $ error "pokeBoundedPtr writing beyond limit"
583− pokeByteIndex pos (castContents arr) a
571+ pokeByteIndex pos arr a
584 return (BoundedPtr arr next end)
572 return (BoundedPtr arr next end)
586--------------------------------------------------------------------------------
574--------------------------------------------------------------------------------
@@ -758,11 +746,11 @@ genericPokeObj a ptr = void $ genericPokeObject a ptr
759{-# INLINE genericPokeByteIndex #-}
747{-# INLINE genericPokeByteIndex #-}
760genericPokeByteIndex :: (Generic a, PokeRep (Rep a)) =>
748genericPokeByteIndex :: (Generic a, PokeRep (Rep a)) =>
761− MutableByteArray a -> Int -> a -> IO ()
749+ MutableByteArray -> Int -> a -> IO ()
762genericPokeByteIndex arr index x = do
750genericPokeByteIndex arr index x = do
763 -- XXX Should we use unsafe poke?
751 -- XXX Should we use unsafe poke?
764 end <- sizeOfMutableByteArray arr
752 end <- sizeOfMutableByteArray arr
765− genericPokeObj x (BoundedPtr (castContents arr) index end)
753+ genericPokeObj x (BoundedPtr arr index end)
767--------------------------------------------------------------------------------
755--------------------------------------------------------------------------------
768-- Generic peek
756-- Generic peek
@@ -843,8 +831,8 @@ genericPeekBoundedPtr = runPeeker genericPeeker
844{-# INLINE genericPeekByteIndex #-}
832{-# INLINE genericPeekByteIndex #-}
845genericPeekByteIndex :: (Generic a, PeekRep (Rep a)) =>
833genericPeekByteIndex :: (Generic a, PeekRep (Rep a)) =>
846− MutableByteArray a -> Int -> IO a
834+ MutableByteArray -> Int -> IO a
847genericPeekByteIndex arr index = do
835genericPeekByteIndex arr index = do
848 -- XXX Should we use unsafe peek?
836 -- XXX Should we use unsafe peek?
849 end <- sizeOfMutableByteArray arr
837 end <- sizeOfMutableByteArray arr
850− genericPeekBoundedPtr (BoundedPtr (castContents arr) index end)
838+ genericPeekBoundedPtr (BoundedPtr arr index end)