@@ -314,7 +314,7 @@ unsafeWithNewArray count f = do
314 unsafeWithForeignPtrM (aStart arr) $ \p -> f p >> return arr
314 unsafeWithForeignPtrM (aStart arr) $ \p -> f p >> return arr
316-------------------------------------------------------------------------------
316-------------------------------------------------------------------------------
317−-- Mutation
317+-- Random writes
318-------------------------------------------------------------------------------
318-------------------------------------------------------------------------------
320-- | Write the given element to the given index of the array. Does not check if
320-- | Write the given element to the given index of the array. Does not check if
@@ -331,16 +331,31 @@ putIndexUnsafe Array{..} i x =
331 assert (i >= 0 && elemPtr `plusPtr` elemSize <= aEnd) (return ())
331 assert (i >= 0 && elemPtr `plusPtr` elemSize <= aEnd) (return ())
332 liftIO $ poke elemPtr x
332 liftIO $ poke elemPtr x
334−-- Internal routine for when the array is being created. Appends one item at
334+-------------------------------------------------------------------------------
335−-- the end of the array. Useful when sequentially writing a stream to the
335+-- Snoc
336−-- array.
336+-------------------------------------------------------------------------------
337−{-# INLINE snocUnsafe #-}
337+
338+-- | Snoc using a 'Ptr'. Low level reusable function.
341+{-# INLINE snocNewEnd #-}
338−snocUnsafe :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
342+snocNewEnd :: (MonadIO m, Storable a) => Ptr a -> Array a -> a -> m (Array a)
339−snocUnsafe arr@Array {..} x = liftIO $ do
343+snocNewEnd newEnd arr@Array{..} x = liftIO $ do
340− when (aEnd == aBound) $ error "BUG: snocUnsafe: writing beyond array bounds"
344+ assert (newEnd <= aBound) (return ())
341 poke aEnd x
345 poke aEnd x
342 touchForeignPtr aStart
346 touchForeignPtr aStart
347+ return $ arr {aEnd = newEnd}
349+-- | Really really unsafe, appends the element into the first array, may
350+-- cause silent data corruption or if you are lucky a segfault if the first
351+-- array does not have enough space to append the element.
354+{-# INLINE snocUnsafe #-}
355+snocUnsafe :: forall m a. (MonadIO m, Storable a) =>
356+ Array a -> a -> m (Array a)
357+snocUnsafe arr@Array{..} =
343− return $ arr {aEnd = aEnd `plusPtr` sizeOf (undefined :: a)}
358+ snocNewEnd (aEnd `plusPtr` sizeOf (undefined :: a)) arr
345{-# INLINE snoc #-}
360{-# INLINE snoc #-}
346snoc :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)
361snoc :: forall m a. (MonadIO m, Storable a) => Array a -> a -> m (Array a)