@@ -74,6 +74,7 @@ module Streamly.Internal.Data.Array.Foreign.Mut.Type
7474 , modifyIndices
7575 , modify
7676 , swapIndices
77+ , unsafeSwapIndices
7778
7879 -- * Growing and Shrinking
7980 -- Arrays grow only at the end, though it is possible to grow on both sides
@@ -652,12 +653,41 @@ modify Array{..} f = liftIO $
652653 poke ptr (f r)
653654 go (ptr `plusPtr` elemSize)
654655
656+{-# INLINE swapPtrs #-}
657+swapPtrs :: Storable a => Ptr a -> Ptr a -> IO ()
658+swapPtrs ptr1 ptr2 = do
659+ r1 <- peek ptr1
660+ r2 <- peek ptr2
661+ poke ptr1 r2
662+ poke ptr2 r1
663+
664+-- | Swap the elements at two indices without validating the indices.
665+--
666+-- /Unsafe/: This could result in memory corruption if indices are not valid.
667+--
668+-- /Pre-release/
669+{-# INLINE unsafeSwapIndices #-}
670+unsafeSwapIndices :: forall m a. (MonadIO m, Storable a)
671+ => Array a -> Int -> Int -> m ()
672+unsafeSwapIndices Array{..} i1 i2 = liftIO $ do
673+ unsafeWithArrayContents arrContents arrStart $ \ptr -> do
674+ let elemSize = sizeOf (undefined :: a)
675+ ptr1 = ptr `plusPtr` (elemSize * i1)
676+ ptr2 = ptr `plusPtr` (elemSize * i2)
677+ swapPtrs ptr1 (ptr2 :: Ptr a)
678+
655679-- | Swap the elements at two indices.
656680--
657681-- /Pre-release/
658−swapIndices :: -- (MonadIO m, Storable a) =>
659− Array a -> Int -> Int -> m ()
660−swapIndices = undefined
682+swapIndices :: forall m a. (MonadIO m, Storable a)
683+ => Array a -> Int -> Int -> m ()
684+swapIndices Array{..} i1 i2 = liftIO $ do
685+ let elemSize = sizeOf (undefined :: a)
686+ ptr1 = arrStart `plusPtr` (elemSize * i1)
687+ ptr2 = arrStart `plusPtr` (elemSize * i2)
688+ when (i1 < 0 || ptr1 >= aEnd ) $ invalidIndex "swapIndices" i1
689+ when (i2 < 0 || ptr2 >= aEnd ) $ invalidIndex "swapIndices" i2
690+ swapPtrs ptr1 (ptr2 :: Ptr a)
661691
662692-------------------------------------------------------------------------------
663693-- Rounding