-----------------------------------------------------------------------------
-- |
-- Module      : CComplex
-- Copyright   : (c) Aaron Denney 2004
-- License     : BSD, 2-clause
-- 
-- Maintainer  : wnoise-haskell@ofb.net
-- Stability   : experimental
-- Portability : FFI
--
-- Aims to provide "CComplex a" parameterized type representing C99's
-- complex types and provide Storable instances for both it and
-- Haskell's Complex a types.  Note that C99 can parameterize over
-- integral types -- I think it's a mistake for Complex to not be
-- defined over all Real types.
--
-- For efficiency of common use, we use C's representation for easy
-- conversion.  So, we can be sloppy and use Complex CDouble instead of
-- CComplex CDouble.  In fact, for now CComplex is merely a type synonym
-- for Complex.
--
-- Will hopefully become obsolete when the FFI is revised to include the
-- complex types of C99.
------------------------------------------------------------------------

module CComplex (CComplex) where
import Complex (Complex(..))
import Foreign.Ptr (castPtr)
import Foreign.Storable

-- C 99 specifies that a variable v of type complex t is stored as
-- t v [2], with v[0] the real part and v[1] the imaginary part.
-- elem off and byte off are defaulted, but perhaps shouldn't be,
-- for efficiency.

instance (RealFloat a, Storable a) => Storable (Complex a) where
    sizeOf x    = 2 * sizeOf (f x)
    alignment x = alignment  (f x)
    poke      x (a :+ b) = do let y = castPtr x
                              poke y a
                              pokeElemOff y 1 b
    peek      x          = do let y = castPtr x
                              a <- peek y
                              b <- peekElemOff y 1
                              return (a :+ b)

type CComplex a = Complex a

f :: Complex a -> a
f _ = undefined                                                         
