@@ -170,17 +170,66 @@ unpin arr@(MutableByteArray marr#) =
170-- size and alignment. We can possibly write tests for checking compatibility
170-- size and alignment. We can possibly write tests for checking compatibility
171-- with Storable.
171-- with Storable.
173−-- | An 'Unbox' type supplies operations for reading and writing the type
173+-- | A type implementing the 'Unbox' interface supplies operations for reading
174+-- and writing the type from and to a mutable byte array (an unboxed
174−-- from and to a byte array in memory. The read operation constructs the boxed
175+-- representation) in memory. The read operation 'peekByteIndex' constructs the
175−-- type from an unboxed byte representation in memory. The write operation
176+-- boxed type from the mutable byte array. The write operation 'pokeByteIndex'
176−-- writes the boxed type to an unboxed byte representation in memory.
177+-- writes the boxed type to the mutable byte array.
178−-- This type class dependes on Storable for size and alignment of the type. It
179+-- This type class depends on the 'Storable' for 'sizeOf' and 'alignment'
179−-- is similar to Storable in the sense that it has corresponding operations for
180+-- operations. While 'Storable' supplies the ability to serialize a type to a
180−-- peekByteOff and pokeByteOff. While Storable allows writing to a Ptr, this
181+-- 'Ptr' type, 'Unbox' augments it by supplying the ability to serialize to a
181−-- type class allows writing to a MutableByteArray#.
182+-- mutable byte array. The advantage of 'Unbox' over 'Storable' is that we can
183+-- use unpinned memory with 'Unbox'.
185+-- Note: Use the @QuantifiedConstraints@ language extension so that you can
186+-- just use a single 'Unbox' constraint in your code rather than using both
187+-- 'Storable' and 'Unbox'.
189+-- Here is an example, to write an instance for this type class.
192+-- data Object = Object
198+-- Note you can leave peek and poke undefined in 'Storable' if you are not
199+-- using the Storable instance, Unbox does not need these operations.
201+-- >>> import Foreign.Ptr (plusPtr, castPtr)
202+-- >>> import Foreign.Storable (Storable(..))
204+-- instance Storable Object where
208+-- let p = castPtr ptr
210+-- x1 <- peek (p `plusPtr` 8)
211+-- return $ Object x0 x1
212+-- poke ptr (Object x0 x1) = do
213+-- let p = castPtr ptr
215+-- poke (p `plusPtr` 8) x1
218+-- >>> import Streamly.Data.Array (Unbox(..))
219+-- >>> import Streamly.Internal.Data.Unboxed (castContents)
221+-- instance Unbox Object where
222+-- peekByteIndex arr i = do
223+-- let p = castContents arr
224+-- x0 <- peekByteIndex p i
225+-- x1 <- peekByteIndex p (i + 8)
226+-- return $ Object x0 x1
227+-- pokeByteIndex arr i (Object x0 x1) = do
228+-- let p = castContents arr
229+-- pokeByteIndex p i x0
230+-- pokeByteIndex p (i + 8) x1
183−-- Note: Enable @QuantifiedConstraints@ to simplify constraint specification.
184class Storable a => Unbox a where
233class Storable a => Unbox a where
185 -- | Read an element of type "a" from a MutableByteArray given the byte
234 -- | Read an element of type "a" from a MutableByteArray given the byte
186 -- index.
235 -- index.