@@ 14,7 14,7 @@ import GHC.Exts (realWorld#, oneShot)
-- | Clone the given array so it can be freed without the losing access to the data.
-- Uses `memcpy` so it gets very heavily optimized by the OS.
-clonePtr :: Ptr a -> Int -> ForeignPtr a
+clonePtr :: Storable a => Ptr a -> Int -> IO (ForeignPtr a)
clonePtr ptr l = do
ret <- mallocForeignPtrArray l
withForeignPtr ret $ \ptr' -> copyArray ptr' ptr l
@@ 27,11 27,13 @@ peekLazy fp n
| otherwise = withFP $ peekEager (plusForeignPtr fp chunkSize `peekLazy` (-) n chunkSize) chunkSize
where withFP = accursedUnutterablePerformIO . withForeignPtr fp
-- | Variation of peekArray, taking a tail to append to the decoded list.
+peekEager :: Storable a => [a] -> Int -> Ptr a -> IO [a]
peekEager acc 0 ptr = return acc
peekEager acc n ptr = let n' = pred n in do
e <- peekElemOff ptr n'
peekEager (e:acc) n' ptr
-- | How many words should be decoded by `peekLazy` & `iterateLazy`.
+chunkSize :: Int
chunkSize = 1024 -- 4k, benchmarks seem to like it!
-- | Convert an array from C code into a Haskell list,
-- performant no matter how small or large it is.
@@ 81,4 83,5 @@ accursedUnutterablePerformIO (IO m) = case m realWorld# of (# _, r #) -> r
-- efficient for Haskell to recompute the glyphs than to store them.
--
-- This synonym of `oneShot` is used to instruct Haskell of this fact.
+noCache :: (a -> b) -> a -> b
noCache = oneShot