1{-# LANGUAGE CPP, NoImplicitPrelude #-}
2{-# LANGUAGE ForeignFunctionInterface #-}
3module Foreign.Marshal.Alloc.Compat (
4  module Base
5, calloc
6, callocBytes
7) where
8import Foreign.Marshal.Alloc as Base
9
10#if !(MIN_VERSION_base(4,8,0))
11import Foreign.C.Types
12import Foreign.Ptr (Ptr, nullPtr)
13import Foreign.Storable (Storable(..))
14import GHC.IO.Exception
15import Prelude.Compat
16
17-- |Like 'malloc' but memory is filled with bytes of value zero.
18--
19{-# INLINE calloc #-}
20calloc :: Storable a => IO (Ptr a)
21calloc = doCalloc undefined
22  where
23    doCalloc       :: Storable b => b -> IO (Ptr b)
24    doCalloc dummy = callocBytes (sizeOf dummy)
25
26-- |Llike 'mallocBytes' but memory is filled with bytes of value zero.
27--
28callocBytes :: Int -> IO (Ptr a)
29callocBytes size = failWhenNULL "calloc" $ _calloc 1 (fromIntegral size)
30
31-- asserts that the pointer returned from the action in the second argument is
32-- non-null
33--
34failWhenNULL :: String -> IO (Ptr a) -> IO (Ptr a)
35failWhenNULL name f = do
36   addr <- f
37   if addr == nullPtr
38      then ioError (IOError Nothing ResourceExhausted name
39                                        "out of memory" Nothing Nothing)
40      else return addr
41
42foreign import ccall unsafe "stdlib.h calloc"  _calloc  :: CSize -> CSize -> IO (Ptr a)
43#endif
44