@@ -121,6 +121,8 @@ module Streamly.Internal.Data.Array.Foreign
121121 -- , foldtWith
122122 -- , foldbWith
123123
124+ , unsafeSlice
125+
124126 -- * Immutable Transformations
125127 , streamTransform
126128
@@ -149,6 +151,7 @@ import Data.Word (Word8)
149151-- import Data.Functor.Identity (Identity)
150152import Foreign.C.String (CString)
151153import Foreign.ForeignPtr (withForeignPtr, castForeignPtr)
154+import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
152155import Foreign.Ptr (plusPtr, castPtr)
153156import Foreign.Storable (Storable(..))
154157import Prelude hiding (length, null, last, map, (!!), read, concat)
@@ -175,6 +178,15 @@ import qualified Streamly.Internal.Data.Unfold as Unfold
175178import qualified Streamly.Internal.Data.Producer.Type as Producer
176179import qualified Streamly.Internal.Ring.Foreign as RB
177180
181+#if MIN_VERSION_base(4,10,0)
182+import Foreign.ForeignPtr (plusForeignPtr)
183+#else
184+import GHC.Base (Int(..), plusAddr#)
185+import GHC.ForeignPtr (ForeignPtr(..))
186+plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
187+plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c
188+#endif
189+
178190-------------------------------------------------------------------------------
179191-- Construction
180192-------------------------------------------------------------------------------
@@ -334,9 +346,27 @@ findIndices = undefined
334346-- Slice and splice
335347-------------------------------------------------------------------------------
336348
349+-- | /O(1)/ Slice an array in constant time.
350+--
351+-- Caution: The bounds of the slice are not checked.
352+--
353+-- /Unsafe/
354+--
355+-- /Pre-release/
356+{-# INLINE unsafeSlice #-}
357+unsafeSlice ::
358+ forall a. Storable a
359+ => Int -- ^ starting index
360+ -> Int -- ^ length of the slice
361+ -> Array a
362+ -> Array a
363+unsafeSlice start len (Array fp _) =
364+ let size = sizeOf (undefined :: a)
365+ fp1 = fp `plusForeignPtr` (start * size)
366+ end = unsafeForeignPtrToPtr fp1 `plusPtr` (len * size)
367+ in Array fp1 end
368+
337369{-
338−slice :: Int -> Int -> Array a
339−slice begin end arr = undefined
340370
341371splitAt :: Int -> Array a -> (Array a, Array a)
342372splitAt i arr = undefined